一、概述
集合框架是Java一块很重要的内容,对常用的数据结构做了规范和实现。对象封装了数据,许多对象则构成了所谓集合。Java集合类库构成了集合类的框架。它为集合的实现者定义了大量的接口和抽象类,并且对其中的某些机制给予了描述。
集合框架的接口和实现类:
集合框架的接口和实现类

二、Iterator接口
Iterator接口与Collection系列、Map系列的集合不一样:Collection系列集合、Map系列集合主要用于盛装其他对象,而Iterator则主要用于遍历(即迭代访问)Collection集合中的元素,Iterator对象也被称为迭代器。[]
Iterator接口定义了四个方法
–boolean hasNext():如果被迭代的集合还元素没有被遍历,则返回true。
–Object next():返回集合里下一个元素。
–void remove() :删除集合里上一次next方法返回的元素
–void forEachRemaining(Consumer action):这是Java 8为Iterator新增的默认方法,该方法可使用Lambda表达式来遍历集合元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* @author shen
* @desc Iterator接口
* @date 2016年8月23日
*/
public class IteratorTest {
public static void main(String[] args) {
//Iterator是Collection父接口,可如此创建集合
Collection<Object> animals = new HashSet<>();
//添加元素
animals.add("cat");
animals.add("dog");
animals.add("pig");
//使用Lambda表达式遍历集合(java1.8新特性)
animals.forEach(obj -> System.out.println("Lambda迭代输出:" + obj));
//iterator()方法获取迭代器
Iterator<Object> data = animals.iterator();
while(data.hasNext()){
Object subData = data.next();
if("cat".equals(subData)){
data.remove();//移除元素
}
System.out.println("迭代器输出:" + subData);
}
System.out.println(animals);
}
}

输出:
这里写图片描述

三、Collection接口
Collection不提供接口的任何直接实现,一个Collection代表一组Object,但它提供更加具体的子接口如List和Set,而继承自它们的 ArrayList, Vector, HashTable, HashMap等实现类才可被实例化。
1、List接口
List是一个有序集合(ordered collection)。元素可以添加到容器中某个特定的位置。将对象放置在某个位置上可以采用两种方式:使用整数索引或使用列表迭代器。[引 java核心技术]
List接口实现类主要有:ArrayList、Vector、LinkedList。
(1)ArrayList
ArrayList是List接口的可变数组的实现,其操作基本是对数组的操作,ArrayList是线程不安全的。
ArrayList包装了许多的方法,包括元素的增加移除、插入移动、转换数组等等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* @author shen
* @desc
* @date 2016年8月23日
*/
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("1");//使用list时默认长度置为10
list.add("2");
list.add("3");
list.add("4");
list.add("5");
System.out.println("list输出:"+list);
list.remove(4);//移除元素
System.out.println("移除元素之后的list:"+list);
Object[] arr = list.toArray();//转换为数组
System.out.println("数组元素输出:"+arr[0]);
List<String> c = new ArrayList<>(4);//预计有4个元素而创建
c.add("6");
c.add("7");
c.add("8");
c.add("9");
c.add("10");//超过5个元素list会增加原来长度一半个元素,目前即长度为6
list.addAll(c);//增加一组数据,数据类型应相同
System.out.println(list);
Iterator<String> data = list.iterator();//获取迭代器
System.out.println("迭代输出:");
data.forEachRemaining(action -> System.out.print(action+" "));
}
}

输出:
这里写图片描述
ArrayList的各种操作虽然很方便,但是ArrayList的插入和删除,会导致内部数据大量移位,而扩容则需要新建一个ArrayList将原来的数据复制过去,会影响性能。如果我们已经知道需要的元素个数,我们可以初始化时指定ArrayList的容量,这样可以有效的避免数组多次扩充,从而提高效率。
(2)Vector
Vector类提供了实现可增长数组的功能,随着更多元素加入其中,数组变的更大。在删除一些元素之后,数组变小,而不像ArrayList的扩容方式,基本用法与ArrayList相同。Vector是同步类,是线程安全的。
(3)LinkedList
LinkedList是list的链表实现,列表中的每个节点都包含了对前一个和后一个元素的引用,除了大部分与ArrayList相同的方法,LinkedList还有一些其特有的方法,并且LinkedList在添加和删除元素时具有比ArrayList更好的性能,但在get数据时更慢。LinkedList适用于没有大规模的随机读取,大量的增加/删除操作。[]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LinkTest {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<>();
link.add("a");
link.add("b");
link.add("c");
link.add("d");
link.add("e");
System.out.println("第一个元素:"+link.getFirst()+" 最后一个元素:"+link.getLast());
link.remove(1);
System.out.println(link);
link.add(3, "zhiding");
System.out.println(link);
}
}

输出:
这里写图片描述

2、Set接口
由于Set接口提供的数据结构是数学意义上集合概念的抽象,因此它需要支持对象的添加、删除,而不需提供随机访问。Set具有与Collection完全一样的接口,因此没有任何额外的功能。实际上Set就是Collection,只是行为不同。Set不包含重复的元素。
Set的实现类主要有:HashSet,TreeSet,LinkedHashSet
(1)HashSet
不保证set的迭代顺序,不保证该顺序永恒不变,因此HashSet也没有get方法。此类允许使用null元素,底层是使用HashMap实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("adf");
set.add("bhf");
set.add("c32");
set.add("c32");//有重复元素,添加不了
set.add(null);//null也只允许只有一个
System.out.println(set);
for(String str : set){
System.out.print(str +" ");
}
System.out.println();
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String data = iterator.next();
System.out.print(data +" ");
}
}
输出:
[null, bhf, adf, c32]
null bhf adf c32
null bhf adf c32

(2)TreeSet
TreeSet元素自然排序,底层是使用TreeMap实现的,自定义要显示Comparable接口。TreeSet可以给集合中的元素进行指定方式的排序,保证元素唯一性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* @author shen
* @desc 测试类,实现Comparable<T>接口
* @date 2016年8月24日
*/
public class User implements Comparable<User>{
private String name;
private int age;
//构造
public User(String name,int age){
this.name = name;
this.age = age;
}
//实现类
@Override
public int compareTo(User user) {
if(user == null)
throw new NullPointerException();
if(this.age > user.age)
return 1;
if(this.age < user.age)
return -1;
return 0;
}
//重写toString
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
//测试
public static void main(String[] args) {
Set<User> set = new TreeSet<User>();
User user1 = new User("Tom", 20);
User user2 = new User("Jack", 21);
User user3 = new User("Dave", 22);
User user4 = new User("Jane", 12);
set.add(user1);
set.add(user1);//重复,添加不了
set.add(user2);
set.add(user3);
set.add(user4);
System.out.println("按年龄大小输出:");
System.out.println(set);
}
输出
按年龄大小输出:
[User [name=Jane, age=12], User [name=Tom, age=20], User [name=Jack, age=21], User [name=Dave, age=22]]

(3)LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。[]

四、Map接口
在Collection实现中保存的直接是一个个对象,二在Map实现中保存的是一对对象,以键值对key-value的方式关联着。Map的常用实现类有HashMap,HashTabel和TreeMap。
1、HashMap
HashMap是基于哈希表的Map接口的非同步实现,其中元素表现无序,特别是它不保证该顺序恒久不变。HashMap会利用对象的hashCode来快速找到key。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public static void main(String[] args) {
//使用实现类创建,键值指定对象类型
HashMap<String, String> map = new HashMap<>();
map.put("name", "shen");
map.put("age", "20");
map.put("age", "19");//相同键多次存入数据覆盖
map.put("weight", "100");
map.put(null, "空");//允许空键值
map.put(null, null);
System.out.println(map);
//对map集合的遍历,可取出具体的键和对应值
for(Entry<String, String> element:map.entrySet()){
String key = element.getKey();
String value = element.getValue();
Class<? extends Entry> classData = element.getClass();
System.out.println(key + "---- " + value + "---- " + classData.getName());
}
//使用接口创建,不关心具体实现,只有在使用才具体实现
//键值的值一般设为Object,不关心什么类型的数据,当然,获取需要具体数据类型或对象需要转化
Map<String, Object> mapData = null;//new HashMap<>();
mapData = new HashMap<>();
mapData.put("name", "Jack");
mapData.put("age", 21);
mapData.put("weight", 110.5);
System.out.println(mapData);
System.out.println("获取name值:" + mapData.get("name"));
Set<String> keys = mapData.keySet();
System.out.println("获取所有key:" + keys);
Collection<Object> values = mapData.values();
System.out.println("获取所有value:" + values);
}
输出:
{null=null, name=shen, weight=100, age=19}
null---- null---- java.util.HashMap$Node
name---- shen---- java.util.HashMap$Node
weight---- 100---- java.util.HashMap$Node
age---- 19---- java.util.HashMap$Node
{name=Jack, weight=110.5, age=21}
获取name值:Jack
获取所有key:[name, weight, age]
获取所有value:[Jack, 110.5, 21]

2、HashTabel
HashTable在很大程度事实上和HashMap的实现差不多,主要区别是HashMap采用异步处理方式,性能更高,而HashTabel采用同步处理方式,性能较低。HashTabel属于线程安全类而HashMap属于线程不安全类。[参考]

3、TreeMap
TreeMap是可排序的Map集合按照集合中的key进行排序,key不允许重复。TreeMap是红黑树基于Map接口的实现。关于TreeMap红黑树参考,初次接触不容易理解,多查资料。