Java集合

Java集合

集合概述

​ 1、为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),Java提供了集合类;

​ 2、集合类主要负责保存盛装其他数据,因此集合类也被称为容器类

​ 3、集合类和数组不一样,数组元素既阔以是基本类型的值,也阔以是对象(对象的引用变量);而集合里只能保存对象(实际上只是 保存 对象的引用变量)

Java集合类的主要有两个接口派生而出:Collection 和 Map

对于Set、List、Queue 和 Map 四种集合,最常用的实现类放入了思考的表情,分别是HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList 和 HashMap 、TreeMap 等实现类;

Collection 和 Iterator 接口

1. 使用Lambda表达式遍历集合

​ Java8 为Iterable 接口新增了一个forEach的默认方法,而iterable的接口是Collection接口的父接口,因此Collection集合也阔以直接调用该方法!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Lambda表达式遍历集合 {
public static void main(String[] args) {
//创建一个集合

Collection demo = new HashSet();
demo.add("aaa");
demo.add("bbb");
demo.add("ccc");
//调用foreach()方法遍历集合
demo.forEach(o -> System.out.println("迭代集合元素:" + o));

}
}

/*运行结果:
迭代集合元素:aaa
迭代集合元素:ccc
迭代集合元素:bbb
*/
2. 使用增强的Iterator遍历集合元素

​ Iterator接口隐藏了各种Collection实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接口。

​ Iterator 接口定义了如下四个方法:

  • boolean hasNext() —如果被迭代的集合元素还没有被遍历完,则返回true;
  • Object next() —返回集合里的下一个元素;
  • void remove() —删除集合里的上一次next方法返回的元素;
  • viod forEachRemaining(Consumer action) —Java8 中新增的默认方法,阔以使用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
34
35
36
public class 增强的Iterator遍历集合元素 {
public static void main(String[] args) {
Collection demo = new HashSet();
demo.add("aaa");
demo.add("bbb");
demo.add("ccc");

//获取demo集合对应的迭代器
Iterator it = demo.iterator();
while (it.hasNext()) {
//it.next() 方法返回的数据类型为Object 因此需要强制转换
String test = (String)it.next();
System.out.println(test);
if (test .equals("bbb") ) {
//从集合中删除上一次next返回的元素
it.remove();

/**
* 使用Iterator迭代过程中,不可修改集合元素下面的代码将会发生异常
* it.remove(test);
*/
}
//对test赋值,不会改变集合元素本身
test = "ddd";
}
System.out.println(demo);
}
}


/*运行结果如下:
aaa
ccc
bbb
[aaa, ccc]
*/
3. 使用Lambda表达式遍历Iterator

​ Java8 新增了一个forEachRemaining(Consumer action)方法。

​ 当程序调用Iterator的forEachRemaining(Consumer action)遍历集合元素时,程序会一次将集合传给Consumer 的 accept(T t)方法 (该接口中唯一的抽象方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class Lambda表达式遍历Iterator {
public static void main(String[] args) {
Collection demo = new HashSet();
demo.add("aaa");
demo.add("bbb");
demo.add("ccc");

//获取demo集合对应的迭代器
Iterator it = demo.iterator();
//使用:Lambda表达式(目标类型是Consumer)来遍历集合
it.forEachRemaining(o -> System.out.println("迭代集合元素:" + o));
}
}


/*运行结果如下:
迭代集合元素:aaa
迭代集合元素:ccc
迭代集合元素:bbb
*/
4. 使用 foreach 循环遍历集合元素

​ 除了使用 Iterator 接口迭代访问 Collection 集合里的元素之外, Java还提供了foreach 循环迭代访问集合元素更加便捷。

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
public class foreach循环遍历集合元素 {
public static void main(String[] args) {
Collection demo = new HashSet();
demo.add("aaa");
demo.add("bbb");
demo.add("ccc");

for (Object o : demo) {
//此处的demo变量也不是集合元素的本身
String test = (String) o;
System.out.println(test);
if (test.equals("aaa")) {
/*
//下面的代码回引发 ConcurrentModificationException 异常
demo.remove(test);
*/
}
}
System.out.println(demo);
}
}


/*运行结果如下:
aaa
ccc
bbb
[aaa, ccc, bbb]
*/

Set集合

​ Set 和 Collection 基本相同, 没有提供任何额外的方法。 实际上Set 就是Collection, 只是行为略有不同(Set不允许包含重复的元素

1. HashSet类

​ HashSet 按 Hash算法来储存集合中的元素,因此具有很好的存取和查找性能

​ HashSet 具有以下特点:

  • 不能保证元素的排列顺序,顺序可能与添加的顺序不同,顺序也有可能发生变化;
  • HashSet 不是同步的,多个线程同时访问一个 HashSet 时,必须通过代码来保证其同步;
  • 集合的元素值阔以是null

​ 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的hashCode()方法来得到该对象的 hashCode 值, 然后根据该hashCode 值决定该对象在HashSet中的储存位置。如果两个元素通过了equals()方法返回true,但是它们的hashCode()方法返回的值不相等,HashSet将会把它们储存在不同的位置,依然阔以添加成功。

​ 也就是说, HashSet 集合判断两个元素相等的标准是两个对象通过 equals()方法比较相等,并且两个对象的hashCode()方法返回的值也相等

下面的程序分别提供了A、B、C、

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
A.java
public class A {
//equals() 方法总是返回true,但是没有重写其hashCode()方法
public boolean equals(Object o){
return true;
}
}

B.java
public class B {
//hashCode() 总是返回1,但是没有重写其equals()方法
public int hashCode(){
return 1;
}
}

C.java
public class C {
//hashCode() 方法总是返回2,且重写其equals()方法总是返回true
public int hashCode(){
return 2;
}
public boolean equals(Object o){
return true;
}
}


HashSetTest.java
public class HashSetTest {
public static void main(String[] args) {
HashSet demo = new HashSet();
//分别向demo集合中添加两个A/B/C对象
demo.add(new A());
demo.add(new A());
demo.add(new B());
demo.add(new B());
demo.add(new C());
demo.add(new C());

System.out.println(demo);

}
}

/*运行结果如下:
[B@1, B@1, C@2, A@4554617c, A@1b6d3586]



*/



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!