Java集合类
程序员文章站
2022-03-19 14:26:37
ArrayList 实现原理:由数组实现的。元素有序,允许重复。 //其中增长长度的方法,可以看到是创建一个新数组,传入旧数组和新的数组长度。 private void grow(int minCapacity) { // overflow-conscious code int oldCapacit ......
一、集合类
- Java提供的一些相当于容器的类,其可以用来存储一系列的对象的引用
- 其中存储的每个内容称为元素
- 集合类框架中,Java提供了一些接口,实现方法和计算方法 集合与数组相似,但是定义和功能却略有差异
- 数组的大小是固定的,集合的大小则是可变的
- 数组用来存放基本类型的数据,集合用来存放对象的引用
- 集合类框架提供了两个接口——Collection和Map,都继承自java.langObject类
-
Collection类有List和Set两种继承接口,每个接口都有各自的实现 Map是一种键值对的存储形式,同时也有自己的实现
二、collection接口
- 最基本的集合类接口,可以认为它是描述了一系列相同功能接口的共性接口
- 提供了通用的对集合内元素操作的方法,Collection的子类会实现这些方法
- 其子类一些是具体类,可以直接使用,有些是抽象类,提供了该接口的部分实现
- 该接口同时继承了Iterable接口,因此Collection的所有子类(List类、Set类)也都实现了Iterable接口
- Iterable是Java集合的*接口之一,这个接口中提供了三个方法,分别是forEach()、iterator()、spliterator()
-
iterator()最常用,可以通过迭代器遍历自身元素,即查询整个集合的所有元素
三、list集合
ArrayList类
- 继承自Collection接口,同时在Collection的基础方法上添加了大量的方法来支持元素的插入和移除等操作
- ArrayList实现了List接口,同时继承于AbstractList类,实现了可变大小的数组(即数组的容量不可变,但是ArrayList得容量可以动态增长),允许有null元素
- ArrayList随机访问和遍历整个集合时性能较好,但是在List的指定位置插入和移除元素时性能较差
实例化格式如下:
List<T>list名 = new ArrayList<T>()
List<T>list名 = new ArrayList<T>(int)
- 使用new创建一个新的集合对象时可以省略<>,系统在编译时会将前面默认的类型填充进去
ArrayList具体使用
public class UseArrayList
{
public static void main(String[] args)
{
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.remove(1); // one three
for (String string : list)
{
System.out.println("foreach遍历:" + string);
}
System.out.println();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext())
{
System.out.println("迭代遍历:" + iterator.next());
}
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();
List<Integer> list3 = new ArrayList<Integer>(3);
list3.add(4);
list3.add(66);
list3.add(33);
list3.add(14);
list3.add(99);
//sort排序
System.out.println("排序前:");
for (Integer integer : list3)
{
System.out.print(integer + " ");
}
list3.sort(null);
System.out.println("\n排序后:");
for (Integer integer : list3)
{
System.out.print(integer + " ");
}
//根据索引获取指定范围集合内的子集合
list1 = list3.subList(0, 3);
System.out.println("\n获取list3【0-3】号元素给list1:");
for (Integer integer : list1)
{
System.out.print(integer + " ");
}
System.out.println("list3的内存:" + list3.size());
//查找指定对象,第一个
System.out.println("查找33的索引:" + list3.indexOf(33));
//最后一个
list3.add(99);
list3.add(99);
list3.add(99);
System.out.println("查找99的索引:" + list3.lastIndexOf(99));
System.out.println("list3的内存:" + list3.size());
}
}
-
ArrayList可以使用get()和set()方法来对指定索引获取、设置特定的元素
LinkedList类
- 实现了List接口,使用了链表结构进行存储,允许有null元素
- 在List的中间插入和移除元素时性能较好,但是在随机访问和查询集合中的元素时性能较差,这也是链表结构的特点
四、Set集合
- Set接口继承了Collection接口,且与List类似,也也支持元素的插入和移除等各种操作
- Set集合不能包含重复元素(不能包含满足equals()方法的两个对象:包括某个数值或字符串和对象)
- Set不一定保证元素在集合中的顺序,也没有提供get()和set()方法
Set接口的实现有AbstractSet、HashSet、EnumSet、LinkedHashSet、TreeSet等
HashSet类
- 该类实现了Set接口,由哈希表(实际上是一个HashMap对象)支持,它不保证Set内元素的顺序,因此每次在访问或迭代遍历时取出元素的顺序并不相同
-
使用时将变量类型声明为Set类型,可以通过具体的类来定义不同对象的具体实例化类型
- add()方法用来给集合添加元素
- 当添加集合内已经有的值时,集合并不会添加
- remove()方法用来移除指定元素
遍历:
- foreach遍历
- 迭代器 Iterator 遍历
Tips:
HashSet是非线程同步的,在多线程情况下,如果多个线程同时访问一个HashSet对象,当至少一个线程修改了该对象时,需要使用Collection类中的synchronizedSet()方法来包装,使这个对象对外部保持同步
TreeSet类
- TreeSet类同时实现了Set接口和NavigableSet接口
- 该类既可以使用元素的自然顺序对元素进行排序,也可以根据Set集合提供的Comparator比较器的顺序来进行排序,如果没有则抛出ClassCastException异常
- Comparator接口中提供了compareTo(Object o)方法,用于比较当前对象与传入对象来决定前后顺序
- 若当前对象小于入参对象,则返回负整数
- 若相同,则返回0
- 若大于,则返回正整数
-
TreeSet类初始化一般使用TreeSet,这样便于使用该类中提供的方法
- 第一次迭代遍历TreeSet对象时使用的是默认的Integer中默认的compareTo()方法
- 第二次迭代遍历中,Person类实现了Comparable接口,使用的是Person类中的自定义的compareTo()方法
TreeSet常用方法
- TreeSet也是非同步的,在多线程环境下使用时须谨慎
五、Map集合
- Map接口是和Collection接口并列的另一种结构,提供了键值对的存储能力,即key-value
- Map接口是由最初的Java提供的一个抽象类(Dictionary字典类)演变而来的
- Map接口中的key和value是成对一起出现的,Java中提供 Map.Entry<K,V>接口来描述它们
- Map中提供了entrySet()方法来获取所有的Entry集合
- Map是在java.util包中提供的,具体实现类有AbstractMap、HashMap、TreeMap、HashTable、LinkedHashMap、EnumMap等
HashMap
- HashMap实现了Map接口,同时继承于AbstractMap类
- 它利用哈希值来存储数据,不允许重复的键出现,但允许有null值和null键,最多只允许一个为null的键
- HashMap因为使用了哈希表,所以对其中的映射关系具有很快的访问速度
-
HashMap不保证存入键值对映射关系的顺序,而且它的顺序可能会发生改变
- 当集合内键值对较多时,使用第三种方法——Map.entrySet()遍历的效率最高,一次获取所有的键值对
- 使用get()方法过去Map集合中指定key映射的值
- 使用put()方法来设定指定key映射的值
HashMap是非线程的,在多线程情况下谨慎使用
TreeMap
-
TreeMap实现了Map接口,继承于AbstractMap类,同时实现了NavigableMap接口
-
TreeMap是基于红黑树结构的,因此键值对的存储具有一定的顺序
-
TreeMap既可以使用键值对映射的自然顺序对映射关系进行排序,也可以根据创建Map集合时提供的Comparrator比较器的顺序进行排序,如果没有就会抛出ClassCastException异常
-
TreeMap由于引入了顺序,所以查询的性能比HashMap稍差,但它不允许有null键
-
-
TreeMap也是非同步的,一般会使用Collections.synchronizedSortedMap()方法来包装该映射
本文地址:https://blog.csdn.net/weixin_43520256/article/details/109252144