数组
数组的储存方式在内存的地址是连续的,大小固定,一旦分配不能被其他引用占用。它的特点是查询快,增删慢。
链表的存储方式是非连续的,大小不固定,特点与数组相反,插入和删除快,查询速度慢。
数组的特点
-
在内存中,数组是一块连续的区域。 拿上面的看电影来说,这几个人在电影院必须坐在一起。
-
数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费内存空间。 比如看电影时,为了保证10个人能坐在一起,必须提前订好10个连续的位置。这样的好处就是能保证10个人可以在一起。但是这样的缺点是,如果来的人不够10个,那么剩下的位置就浪费了。如果临时有多来了个人,那么10个就不够用了,这时可能需要将第11个位置上的人挪走,或者是他们11个人重新去找一个11连坐的位置,效率都很低。如果没有找到符合要求的作为,那么就没法坐了。
-
插入数据和删除数据效率低,插入数据时,这个位置后面的数据在内存中都要向后移。删除数据时,这个数据后面的数据都要往前移动。 比如原来去了5个人,然后后来又去了一个人要坐在第三个位置上,那么第三个到第五个都要往后移动一个位子,将第三个位置留给新来的人。 当这个人走了的时候,因为他们要连在一起的,所以他后面几个人要往前移动一个位置,把这个空位补上。
-
随机读取效率很高。因为数组是连续的,知道每一个数据的内存地址,可以直接找到给地址的数据。
-
并且不利于扩展,数组定义的空间不够时要重新定义数组。
链表的特点
-
在内存中可以存在任何地方,不要求连续。 在电影院几个人可以随便坐。
-
每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。 第一个人知道第二个人的座位号,第二个人知道第三个人的座位号……
-
增加数据和删除数据很容易。 再来个人可以随便坐,比如来了个人要做到第三个位置,那他只需要把自己的位置告诉第二个人,然后问第二个人拿到原来第三个人的位置就行了。其他人都不用动。
-
查找数据时效率低,因为不具有随机访问性,所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。 要找到第三个人,必须从第一个人开始问起。
-
不指定大小,扩展方便。链表大小不用定义,数据随意增删。
长度固定 与其他容器之间的区别:效率 类型和保存基本类型的能力 效率最高的存储和随机访问对象引用序列的方式。
- 赋值其实只是复制了一个引用。
- 对象数组保存的是引用,基本类型数组保存基本类型的值。
int[] arr = {1, 2, 3, 4, 5};
int[] arr2;
arr2 = arr;
for (int i = 0; i < arr2.length; i++) {
arr2[i] = arr2[i] + 1;
}
for (int i = 0; i < arr.length; i++) {
Logger.v("arr[" + i + "] = " + arr[i]);
// 2,3,4,5,6
}
持有对象
在任何时刻任何位置创建任何数量的对象。
Collection 一个独立元素的序列
- int size() 返回collection的元素数,如果大于Inter.MAX_VALUE,则返回Inter.MAX_VALUE;
- boolean isEmpty 如果collection不包含元素,返回true
- boolean contains(Object obj) 如果collection包含指定的元素,则返回true
- boolean add(E a);
- boolean remove(Object o);
- void clear();
List 必须按照插入的顺序保存元素
ArrayList 用户进行大量的随机访问。
- int indexOf(Object o) 返回列表中首次出现的指定元素的索引,如果不包含,则返回-1.
LinkList是栈实现,双链表结构, 经常实现插入删除数据
ArrayList实现动态数组的数据结构, 可以实现大量的随机访问
LinkedList 栈实现 用于经常从表中间插入或删除元素
- T getFirst();获取列表第一个元素
Set 不能有重复元素 主要使用contains()测试Set的归属性。
- TreeSet 将元素存储在红-黑数据结构中。具有排序实现
- HashSet 使用的散列函数。
- LinkedHashList使用 散列
Map 一组成对儿的“键值对”对象
HashMap 初始容量和负载因子
- HashMap 用来快速访问
- TreeMap 保持处于排序状态。
- LinkedHashMap 保持元素插入时的顺序
Random random = new Random(47);
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < 1000; i++) {
int r = random.nextInt(20);
Integer fre = map.get(r);
map.put(r, fre == null ? 1 : fre + 1);
}
Logger.v(map + "");
Queue 队列是一个典型的先进先出容器。
Queue<Integer> mu = new LinkedList<>();
for (int i = 0; i < 200; i++) {
// 将指定的元素插入此队列(如果立即可行且不会违反容量限制)
boolean add = mu.add(i);
//获取,但是不移除此队列的头。
Integer element = mu.element();
//将指定的元素插入此队列(如果立即可行且不会违反容量限制) 此方法通常要优于 add(E),插入队尾。
boolean offer = mu.offer(i);
// 获取但不移除此队列的头;
Integer peek = mu.peek();
//获取并移除此队列的头
Integer poll = mu.poll();
// 获取并移除此队列的头
Integer remove = mu.remove();
}
Arrars
- Arrars.asList() 接收一个数组,返回一个List对象
- Arrays.fill() 填充数据
- equals()用于比较两个数组是否相等
- sort用户数组排序
- binarySearch用于在已经排序的数组中查找元素
- System.arraycopy();
int[] ints = new int[5];
Arrays.fill(ints,666);
迭代器 Iterator
List lm = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
// 使用iterator()方法要求容器返回一个Iterator
Iterator<Integer> iterator = lm.iterator();
// 检测序列中是否还有元素
while (iterator.hasNext()) {
// 获得序列中下一个元素
int next = iterator.next();
Logger.v(next + "");
}
- ListIterator 用于List访问。Iterator只能单向移动,ListIterator可以双向移动。
Stack “栈”是指先进后出的容器
Stack<String> ms = new Stack<>();
for (String str: "My dog has fleas".split(" ")) {
//把项压入堆栈顶部.
ms.push(str);
// 移除堆栈顶部的对象,并作为此函数的值返回该对象。
String pop = ms.pop();
// 查看堆栈顶部的对象,但不从堆栈中移除它。
String peek = ms.peek();
// 测试堆栈是否为空。
boolean empty = ms.empty();
}
网友评论