1.1 集合

1.1.2 集合的体系结构

集合框架被设计成要满足以下几个目标。

  • 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。

  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。

  • 对一个集合的扩展和适应必须是简单的。

  • list系列集合:添加的元素是有序,可重复,有索引。

  • set系列集合:添加元素是无序,不重复,无索引

  • collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。

常见的方法

image-20221209153927894

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
package com.ydl.Coolection;

import java.util.ArrayList;
import java.util.Collection;

/**
* public boolean add(E e) 添加
* public void clear() 清空
* public boolean remove(E e) 删除
* public boolean contains(Object obj) 判断是否包含
* public boolean isEmpty() 判断是否为空
* public int size() 集合长度
* 注意 :
* collection是一个接口 我们不能直接创建他的对象,
* 我们学习他的方法的时候只能创建他的实现类的对象,
* 实现类Arraylist
*
*/

public class test {
public static void main(String[] args) {
Collection<String> coll= new ArrayList<String>();
//添加元素
//如果我们要往list集合中添加数据,那么方法返回true 因为list集合可以重复
coll.add("aaaa");
coll.add("aaaa");
coll.add("bbb");
// //清空
// coll.clear();
//删除 不能通过索引删除
coll.remove("aaa");
System.out.println(coll);
//判断
boolean aaa = coll.contains("aaaa");
System.out.println(aaa);
//判断集合是否为空
boolean empty = coll.isEmpty();
System.out.println(empty);
//判断长度
int size = coll.size();
System.out.println(size);

}
}

1.1.3collection遍历方式

1.迭代器遍历

​ 迭代器在Java中的类是iterator ,迭代器是集合专用的遍历方式。

image-20221209172523274

image-20221210103457393

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
package com.ydl.Coolection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class test2 {
public static void main(String[] args) {
//1.创建集合并添加元素
Collection<String> coll= new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
//2.获取迭代器对象,默认指向0索引处
Iterator<String> it= coll.iterator();
//3.利用循环获取元素
while(it.hasNext()){
//获取元素,并移动指针
String str = it.next();
System.out.println(str);
}
//当迭代器结束,指针指向最后一个元素,若在次调用it.next()
//会报NoSuchElementException

}
}
  • 报错NoSuchElementException
  • ,迭代器遍历完毕,指针不会复位
  • 循环中只能用一次next方法
  • 迭代器遍历时,不能用集合的方法进行增加或者删除
2.增强for遍历
  • 增强fo的底层就是迭代器,为了简化迭代器的代码书写的。
  • 它是DK5之后出现的,其内部原理就是一个Iteratori迭代器。
  • 所有的单列集合和数组才能用增强fo进行遍历。
1
2
3
4
5
6
7
8
增强for格式:
for(数据类型变量名:集合/数组){

}
快速生成方式:
集合的名字+for 回车

使用增强for不会改变集合中原来的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.ydl.Coolection;

import java.util.ArrayList;
import java.util.Collection;

public class test3 {
public static void main(String[] args) {
//创建集合并添加元素
Collection<String> coll= new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
//增强for遍历
for (String s: coll) {
System.out.println(s);
}
}
}
3.lambda表达式遍历

​ 得益于DK8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式。

image-20221210113032495

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.ydl.Coolection;

import java.util.ArrayList;
import java.util.Collection;

public class test3 {
public static void main(String[] args) {
//创建集合并添加元素
Collection<String> coll= new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");

// coll.forEach((String s) ->{
// System.out.println(s);
// }
// );
coll.forEach(s -> System.out.println(s));
}
}

1.2 list集合

  • collection的方法都继承了
  • list集合因为都有索引,所以多了很多索引操作的方法 ·

image-20221210143014838

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.ArrayList;
import java.util.List;

public class list_test {
public static void main(String[] args) {
//创建集合
List<String> list= new ArrayList<>();
//添加元素
list.add("a");
list.add("b");
System.out.println(list);
//在1索引处添加qqqqq
list.add(1,"qqqqq");
//删除指定索引
list.remove(0);
System.out.println(list);
list.set(1,"56566");
System.out.println(list);
list.get(0);
System.out.println(list);
}
}
1.collection遍历方式
  • 迭代器遍历
  • 列表迭代器遍历
  • 增强for遍历
  • lambda表达式遍历
  • 普通for遍历
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
package com.ydl.Coolection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class list_test2 {
public static void main(String[] args) {
//1.创建集合
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
//迭代器遍历
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String next = it.next();
System.out.println(next);
}
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
//增强for
for (String s : list) {
System.out.println(s);
}
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
//lambda表达式
list.forEach(s -> System.out.println(s));
//普通for
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
//列表迭代器
//获取迭代器对象,默认指向0,在遍历的时候可以添加元素
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
ListIterator<String> ita = list.listIterator();

while (ita.hasNext()) {
String str = ita.next();
if ("1".equals(str)){
ita.add("748545");
}
}
System.out.println(list);
}
}

image-20221210155011708

1.3set 集合

set集合实现类

  • HashSet:无序、不重复、无索引
  • LinkedHashSet:有序、不重复、无索引
  • TreeSet:可排序、不重复、无索引

image-20221212102141001

利用Set系列的集合,添加字符串,并使用多种方式遍历。

① 迭代器

② 增强for

③ 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
package com.ydl.Coolection;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Set_Test {
public static void main(String[] args) {
//创建一个集合对象
Set<String> s= new HashSet<>();
boolean b = s.add("张三");
boolean b2 = s.add("张三");
boolean b3 = s.add("李四");
boolean b4 = s.add("王五");
//无序,不重复
System.out.println(s);
//迭代器遍历
Iterator<String> iterator = s.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("++++++++++++++++++++++++");
//增强for
for (String s1 : s) {
System.out.println(s1);
}
System.out.println("++++++++++++++++");
//lambda表达式
s.forEach(a -> System.out.println(a));

}
}

HashSet底层原理

  • HashSet集合底层采取哈希表存储数据
  • 哈希表是一种对于增删改查数据性能都较好的结构
  • 哈希表组成
  • JDK8之前:数组+链表
  • JDK8开始:数组+链表+红黑树

哈希值

  • 根据hashCode方法算出来的int类型的整数
  • 该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
  • 一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值

对象的哈希值特点

  • 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
  • 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.ydl.Coolection;

public class Hashset_Test {
public static void main(String[] args) {
Student s = new Student("张三", 20);
Student s3 = new Student("张三", 20);
Student s2 = new Student("李四", 24);
System.out.println(s.hashCode());
System.out.println(s3.hashCode());
System.out.println(s2.hashCode());

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.ydl.Coolection;

import java.util.HashSet;

public class Hashset_Test {
public static void main(String[] args) {
Student s = new Student("张三", 20);
Student s3 = new Student("张三", 20);
Student s2 = new Student("李四", 24);
System.out.println(s.hashCode());
System.out.println(s3.hashCode());
System.out.println(s2.hashCode());
HashSet<Student> hs= new HashSet<Student>();
//添加元素
hs.add(s);
hs.add(s3);
hs.add(s2);
System.out.println(s);
System.out.println(hs);

}
}

LinkedHashSet底层原理

  • 有序、不重复、无索引。
  • 这里的有序指的是保证存储和取出的元素顺序一致
  • 原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.ydl.Coolection;

import java.util.HashSet;
import java.util.LinkedHashSet;

public class Hashset_Test {
public static void main(String[] args) {
Student s = new Student("张三", 20);
Student s3 = new Student("张三", 20);
Student s2 = new Student("李四", 24);
System.out.println(s.hashCode());
System.out.println(s3.hashCode());
System.out.println(s2.hashCode());
LinkedHashSet<Student> hs= new LinkedHashSet<Student>();
//添加元素
System.out.println(hs.add(s));
System.out.println(hs.add(s3));
System.out.println(hs.add(s2));


}
}

TreeSet的特点

  • 不重复、无索引、可排序

  • 可排序:按照元素的默认规则(有小到大)排序。

  • TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.ydl.Coolection;

import java.util.TreeSet;

public class TreeSet_Test {
public static void main(String[] args) {
TreeSet<Integer> ts= new TreeSet<Integer>();
ts.add(8);
ts.add(2);
ts.add(7);
ts.add(4);
System.out.println(ts);
for (Integer t : ts) {
System.out.println(t);
}
}
}