7 容器
7.1 Java Collections 框架
Java Collections 框架包含了大量的集合接口以及这些接口的实现类和操作他们的算法,例如排序、查找、反转、替换、复制等。具体而言主要提供了List(列表)、Queue(队列)、Set(集合)、Stack(栈)、Map(映射表)等数据结构。其中List、Queue、Set、Stack都继承自Collention 接口。
List、Set、Map 接口:
1)Set 表示数学意义上的集合概念。其最主要的特点是集合中的元素不能重复,因此存入的Set 的每一个元素都必须定义 equals() 方法来确保对象的唯一性。该接口有两个实现类:hashSet 和 TreeSet。其中TreeSet 实现了 SortedSet接口,因此TreeSet容器中的元素是有序的。
总结:Set 是无序的,不可重复的集合,TreeSet是有序的不可重复的集合。
2)List 是有序的 Collention。它按对象进入的顺序保存对象,所以它能对列表中的每一个元素插入和删除的位置进行精确的控制。List 也可以保存重复的对象。LinkedList、ArrayList 和 Vector都实现了 List 接口
总结:有序的,可重复的集合
3)Map 提供了一个从键映射到值的数据结构。它用于保存键值对,其中值可以重复,但是键不可重复。Java类库中有很多实现该接口的类:HashMap、TreeMap、LinkedHashMap等。
Collention 框架结构图:
图来源于优快云博客
7.2 迭代器
迭代器(Iterator)是一个对象,它的工作是遍历并选择序列中的对象,它提供了一种访问一个容器对象的各个元素,而又不需要暴露该对象内部细节的方法。由于创建迭代器的代价小,所以迭代器通常被称作轻量级容器。
迭代器使用的三个注意项:
1)使用迭代器的 iterator() 方法返回一个 Iterator ,然后通过 Iterator 的 next() 方法返回第一个元素。
2)使用 Iterator 的 hashNext() 方法判断容器里是否还有元素,如果有,可以使用 next() 方法返回下一个元素。
3)可以通过 remove() 方法删除迭代器返回的元素。
Iterator 使用方法:
public class Main {
public static void main(String[] args) {
List<String> list = new LinkedList<String>();
list.add("fist");
list.add("next");
list.add("final");
for (Iterator<String> iterator = list.listIterator(); iterator.hasNext(); ) {
String string = iterator.next();
System.out.println(string);
}
}
}
结果:
fist
next
final
遍历集合的三种方式(有判断条件):
public class Singleton {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//指定位置插入元素
list.add(2,"zzz");
System.out.println(list);
//删除元素
list.remove("zzz");
System.out.println(list);
System.out.println("==================================");
//删除所有元素
//list.removeAll(list);
System.out.println(list);
//数组反转
Collections.reverse(list);
System.out.println(list);
System.out.println("==================================");
//for循环遍历
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("ccc")){
System.out.println(list.get(i));
}
}
System.out.println("==================================");
//foreac遍历
for (String o:list) {
if (o.equals("bbb")){
System.out.println(o);
}
}
System.out.println("==================================");
//迭代器遍历
Iterator it = list.iterator();
while(it.hasNext()) {
String i=(String)it.next();
if (i.equals("aaa")){
System.out.println(i);
}
}
}
}
结果:
[aaa, bbb, zzz, ccc]
[aaa, bbb, ccc]
================================
[aaa, bbb, ccc]
[ccc, bbb, aaa]
================================
ccc
================================
bbb
================================
aaa
注:在使用 Iterator 遍历容器时对容器进行增加或者删除操作或出现 ConcurrentModificationException 异常。或者在多线程下,一个线程使用迭代器遍历容器的同时,另一个线程对这个容器进行增加或删除操作也会出现 ConcurrentModificationException 异常。
解决方法:在遍历对象时将需要删除的对象保存到另一个集合,在遍历结束后调用 removeAll() 方法来删除。或者使用 iter.remove() 方法
7.3 ArrayList、Veator与LinkedList
ArrayList、Veator 与 LinkedList 均在 java.util 包中,都是可以动态改变长度的数组。
LinkedList:
采用双向列表来实现,对数据的索引需要从列表头开始遍历,用于随机访问效率比较低,但是插入元素时对数据不需要进行移动,因此插入数据效率比较高。是非线程安全的容器。
ArrayList:
基于存储元素 Object[ ] array 来实现的,会在内存中开辟一块连续的空间来存储,由于数据存储是连续的,所以支持用下标来访问元素,同时索引数据较快。有一个初始化容量大小,当存储的元素超过这个大小后会自动扩容,ArrayList 默认扩容为原来的1.5倍。ArrayList 方法没有同步的,所以线程不安全。
Vextor:
基于存储元素 Object[ ] array 来实现的,会在内存中开辟一块连续的空间来存储,由于数据存储是连续的,所以支持用下标来访问元素,同时索引数据较快。有一个初始化容量大小,当存储的元素超过这个大小后会自动扩容,Vextor 默认扩容为原来的2倍。Vextor 方法都是直接或者间接同步的,所以线程安全。
2021-03-11 更新集合的三种遍历方式
容器(HashMap)这一方面一知半解,不知从何入手去写,等深入了解后会更新
注:
此文来源于《Java程序员面试笔试宝典》一书
仅作为本人学习过程的记录
填写原创是因为找不到相关链接
如有不妥请联系本人,会立即删除
此书对于我这种小白来说非常有用,讲解详细,知识点全面,目前正在根据此书学习,陆续会记录更多知识点。