集合类
集合可以看作是一个容器
集合类与数组的不同之处是:数组的长度是固定的,集合的长度是可变的;数组用来存储基本类型的数据,集合用来存储对象的引用。常用的集合有List集合、Set集合和Map集合,其中List集合与Set集合继承了Collection接口,各接口还提供了不同的实现类。
Collection接口
Collection接口是层次结构中的根接口,构成Collection的单位被称为元素。Collection接口通常不能被直接使用,但该接口提供了添加元素、删除元素、管理数据的方法。由于List接口与Set接口都继承了Collection接口,因此这些方法对List集合与Set集合是通用的。
遍历集合通常都是通过迭代器(iterator)来实现的。Collection接口中的iterator()方法可返回在此Collection进行迭代的迭代器。
示例
List接口
List集合包括List接口以及List接口的所有实现类。List集合中的元素可以重复,各元素的顺序就是对象插入的顺序。用户可通过使用索引来访问集合中的元素。
get(int index):获得指定索引位置的元素。
set(int index,Object obj):将集合中指定索引位置的对象修改为指定的对象。
List接口的常用实现类有ArrayList类与LinkedList类
ArrayList类实现了可变的数组,允许保存所有元素,包括null。缺点是向指定的索引位置处插入对象或从指定的索引位置处删除对象的速度较慢。
通过ArrayList类可以实例化List接口
List<string>list = new ArrayList<>()
LinkedList类采用链表结构保存对象。这种结构的优点是便于向集合中插入对象或从集合中删除对象。需要向集合中插入对象或从集合中删除对象时,使用LinkedList类实现的List集合的效率较高;但对于随机访问集合中的对象,使用LinkedList类实现List集合的效率较低,可选择ArrayList类。
通过LinkedList类可以实例化List接口
List<string>list = newLinkedList<>()
遍历集合中的元素
Iterator遍历集合中的元素
在遍历Collection集合中的元素时,需要使用Iterator接口中用于判断集合中的元素是否被遍历完全的hasNext()方法和用于返回集合里的下一个元素的next()方法。
使用foreach循环遍历集合中的元素
使用forEach()方法遍历集合中的元素
使用Predicate操作集合
removeIf()方法需要一个Predicate对象作为参数。因为Predicate是一个函数式接口,所以可使用Lambda表达式作为removeIf()方法的参数。
可过滤集合和简化集合的运算。
Set接口
Set集合中不能包含重复的元素。
误区警示
Set集合的构造有一个约束条件,传入的Collection对象不能有重复值,必须小心操作可变对象(mutable object)。如果一个Set集合中的可变元素改变了自身状态而导致Object.equals(Object)=true,则会出现一些问题。
HashSet类
它不保证Set集合的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用null元素。
Set<E>set = new HashSet<>();
TreeSet类
TreeSet类实现的Set集合可以按照自然顺序进行递增排序,也可以按照指定比较器进行递增排序,即可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。
Set<E>set = new TreeSet<>();
headSet()、subSet()、tailSet()方法截取对象生成新集合时是否包含指定的参数,可通过如下方法来判别:
(1)如果指定参数位于新集合的起始位置处,则包含该对象,如subSet()方法的第一个参数和tailSet()方法的参数。
(2)如果指定参数是新集合的终止位置处,则不包含该参数,如headSet()方法的入口参数和subSet()方法的第二个入口参数。
Map接口
在Map集合中不能包含相同的key,每个key只能映射一个value。key还决定了存储对象在映射中的存储位置,但不是由key对象本身决定的,而是通过一种“散列技术”进行处理的,产生一个散列码(hash code)的整数值。生成的散列码用作一个“偏移量”,相当于一个指针或索引,用于决定数据在内存中的存储位置。这个偏移量是相对于某个特定的内存区域(分配给映射的内存区域的起始位置)进行的,从而确定了存储对象的具体位置。
HashMap类
HashMap类实现的Map集合添加和删除映射关系效率更高。可以通过HashMap类创建Map集合,当需要顺序输出时,再创建一个完成相同映射关系的TreeMap类实例。
Map集合有key(键)和value(值)两组值,所以遍历Map集合时既可以只遍历key(键),或只遍历value(值),还可以同时遍历key(键)和value(值)。
在for循环中使用entries能够同时遍历Map集合的key(键)和value(值)
使用foreach循环能够遍历Map集合的key(键)或者value(值)。
TreeMap类
由于TreeMap类实现的Map集合中的映射关系是根据键对象按照一定的顺序排列的,因此不允许键对象是null。
Properties类
Properties类是一个特殊的集合,表示一个持久的属性集,在属性列表中的每个key(键)及其对应的value(值)都是一个字符串。Properties类主要用于读取Java的配置文件,其配置文件常为.properties文件,属文本文件,是以键值对的形式进行参数配置的。
Collections类
Collections类的构造方法被私有化处理,直接通过类名即可调用Collections类的静态方法。
注意:Collections是一个具有属性和静态方法的工具类,Collection是一个含有List接口及其实现类和Set接口及其实现类的接口。
打乱List集合中元素的顺序:Collections.shuffle(list)
shuffle()方法的作用是随机打乱集合中元素的原来顺序,并且shuffle()方法只能作用于List集合中。