集合类是Java数据结构的实现。Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java集合类是Java将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。
Java中的集合类可以分为两大类:一类是实现Collection接口;另一类是实现Map接口。
Collection是一个基本的集合接口,Collection中可以容纳一组集合元素(Element)。
Map没有继承Collection接口,与Collection是并列关系。Map提供键(key)到值(value)的映射。一个Map中不能包含相同的键,每个键只能映射一个值。
Collection有两个重要的子接口List和Set。List表达一个有序的集合,List中的每个元素都有索引,使用此接口能够准确的控制每个元素插入的位置。用户也能够使用索引来访问List中的元素,List类似于Java的数组。Set接口的特点是不能包含重复的元素。对Set中任意的两个元素element1和element2都有elementl.equals(element2)= false。另外,Set最多有一个null元素。此接口模仿了数学上的集合概念。
Map接口与Collection接口不同,Map提供键到值的映射。Map接口提供三种Collection视图,允许以键集、值集或键一值映射关系集的形式查看某个映射的内容。
List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。
List接口继承于Collection接口,它可以定义一个允许重复的有序集合。因为List中的元素是有序的,所以我们可以通过使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector。
public static void main(String[] args) {
//定义一个list集合,指定泛型为String,()中为集合初始长度
List<String> list=new ArrayList<String>(100);
//list集合的add方法是指向集合中添加一个(符合泛型要求的)元素
list.add("张三");
list.add("李四");
list.add("王五");
//list集合的add方法是指向集合中指定位置,添加一个(符合泛型要求的)元素[属于方法重载]
list.add(0,"赵六");
//list集合使用size()方法获取集合长度,集合从0开始,最后一位元素为size-1,与数组相似
for (int i = 0; i < list.size(); i++) {
//list集合通过get(index)方法获取集合中的元素,index为集合下标,集合下标从0开始
System.out.println(list.get(i));
}
}
常用方法名称 | 方法介绍 |
---|---|
void add(Object obj) | 向List集合中添加元素,元素可以重复添加,元素值可以是null |
int size() | 获取List集合中元素的个数 |
Object get(int index) | 从List集合中获取元素 |
boolean remove(Object obj) | 从List集合中删除元素 |
boolean remove(int index) | 从List集合中删除元素 |
void clear() | 从List集合中删除所有元素 |
boolean contains(Object obj) | 集合中是否存在某个元素,如果存在返回true |
isEmpty() | 判断 arraylist 是否为空,如果为空返回true |
ArrayList是线程不同步,不安全的集合
public static void main(String[] args) {
//创建list集合的LinkedList实例
List<String> list=new LinkedList<String>();
//使用add方法添加元素
list.add("张三");
list.add("李四");
list.add("王五");
//向下转型获取linkedList对象
LinkedList<String> linkedList=(LinkedList<String>)list;
//向首位添加元素
linkedList.addFirst("赵六");
//向末位添加元素
linkedList.addLast("最后一位");
//使用for循环对象形式迭代集合
for (String string : linkedList) {
System.out.println(string);
}
}
常用方法名称 | 方法介绍 |
---|---|
void addFirst(Object obj) | 向集合容器的顶端添加元素 |
void addLast(Object obj) | 向集合容器的底端添加元素 |
Object getFirst() | 获取集合容器顶端的元素 |
Object getLast() | 获取集合容器底端的元素 |
Object removeFirst() | 删除集合容器顶端的元素,并返回被删除的元素 |
Object removeLast() | 删除集合容器底端的元素,并返回呗删除的元素 |
LinkedList是线程不同步,不安全的集合
注:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候速度较快,比线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要较长时间。
Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样允许null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。
Set是一种不包含重复的元素的Collection,无序,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。需要注意的是:虽然Set中元素没有顺序,但是元素在set中的位置是由该元素的HashCode决定的,其具体位置其实是固定的。
Set接口中的不重复是有特殊要求的,如果一个类重写了hashcode和equals方法,并且重写后的hashcode和equals方法是相同的话。那么这个类实例化的两个对象是不能同时放入到Set集合中去的,也就是Set集合中的去重和hashcode与equals方法直接相关。
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
set.add("张三");
set.add("张三1");
for (String string : set) {
System.out.println(string);
}
}
public static void main(String[] args) {
LinkedHashSet<String> set=new LinkedHashSet<String>();
set.add("张三");
set.add("张三1");
for (String string : set) {
System.out.println(string);
}
System.out.println();
}
Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。
public static void main(String[] args) {
Map<Integer, String> map=new HashMap<Integer, String>();
map.put(1, "张三");
map.put(2, "李四");
map.put(3, "王五");
map.put(4, "赵六");
map.put(5, "你猜");
for (Integer i : map.keySet()) {
System.out.println(map.get(i));
}
System.out.println("*******************");
for (String str: map.values()) {
System.out.println(str);
}
}
常用方法名称 | 方法介绍 |
---|---|
oid clear() | 删除该Map对象中的所有key-value对 |
boolean containsKey(Object key) | 查询Map中是否包含指定的key,如果包含就返回true |
boolean containsValue(Object value) | 查询Map中是否包含指定的value,如果包含就返回true |
boolean isEmpty() | 查询该Map是否为空(即不包含任何key-value对),如果为空则返回true |
Object get(Object key) | 返回指定key所对应的value;如果此Map中不包含该key,则返回null |
void put(Object key, Object value) | 添加一个key-value对,如果当前Map中已有一个与该key相等的key-value对,则新的key-value对会覆盖原来的key-value对 |
boolean remove(Object key) | 这是Java8新增的方法,删除指定key所对应的key-value对,删除成功返回true |
int size() | 返回该Map里的key-value对的个数 |
Set keySet() | 返回该Map中所有的key组成的Set集合,可以用来遍历Map集合 |
Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。
常用方法 | 方法介绍 |
---|---|
boolean hasNext() | 判断集合里是否存在下一个元素。如果有,hasNext()方法返回 true |
Object next() | 返回集合里下一个元素。 |
void remove() | 删除集合里上一次next方法返回的元素 |
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("aaa");
a.add("bbb");
a.add("ccc");
Iterator<String> it = a.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
ListIterator是一个功能更加强大的迭代器, 它继承于Iterator接口,只能用于各种List类型的访问。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。
常用方法 | 方法介绍 |
---|---|
boolean hasNext() | 判断集合里是否存在下一个元素。如果有,hasNext()方法返回 true |
boolean hasPrevious() | 判断集合里是否存在上一个元素。如果有,hasNext()方法返回 true。 |
Object next() | 返回集合里下一个元素。 |
Object previous() | 返回集合里上一个元素。 |
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("aaa");
a.add("bbb");
a.add("ccc");
ListIterator<String> it = a.listIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("******************");
while (it.hasPrevious()) {
System.out.println(it.previous());
}
}