java学习笔记——基础18(Map接口、HashMap集合、LinkedHashMap集合、集合嵌套))

1、Map接口
2、HashMap集合、LinkedHashMap集合
3、集合的嵌套
4、集合应用举例

01Map集合概述

1
2
3
4
5
6
7
8
9
10
11
12
13
A:Map集合概述:
我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同
a:Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。

b:Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。

"Collection中的集合称为【单列集合】,Map中的集合称为【双列集合】"
需要注意的是,
"Map中的集合【不能】包含【重复的键】",【"值】可以重复""每个【键】只能对应一个【值】"
"如果添加【重复的键】,会把之前的【键值】【覆盖】掉"
Map
|--HashMap
|--LinkedHashMap

02Map接口中的常用方法

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
A:Map接口中的常用方法 
/*
* Map接口中的常用方法
* 使用Map接口的实现类 HashMap
*/
public class MapDemo {
public static void main(String[] args) {
function_2();
}
"/*
* 移除集合中的键值对,【返回】被【移除】之前的【值】
* V remove(K)
* 如果集合中【没有】这个【键】,【返回null】,不移除任何元素
*/"
public static void function_2(){
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
System.out.println(map);

String value = map.remove(33);//null
System.out.println(value);
System.out.println(map);
}

"/*
* 通过键对象,获取值对象
* V get(K)
* 如果集合中【没有】这个【键】,【返回null】
*/"
public static void function_1(){
//创建集合对象,作为键的对象整数,值的对象存储字符串
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
System.out.println(map);

String value = map.get(4);//null
System.out.println(value);
}

"/*
* 将键值对存储到集合中
* V put(K,V) K 作为键的对象, V作为值的对象
* 返回值:以前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null。
* 存储的是重复的键,将原有的值,覆盖
* 返回值一般情况下返回null,
* 存储重复键的时候,返回被覆盖之前的值
*/"
public static void function(){
//创建集合对象,HashMap,存储对象,键是字符串,值是整数
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);

map.put("b", 2);

map.put("c", 3);

System.out.println(map);
}
}

————————————————————————————————————————————————————————————————————————————————————————
Java 8 为 Map 新增的方法

> void forEach(BiConsumer action):
该方法是 Java 8 为 Map 新增的 一个遍历 key-value 对的方法 ,
通过该方法可以更简洁地遍历 Map 的 key-value 对 。

> Object replace(Object key, Object value) :
将 Map 中指定 key 对应的 value 替换成新value。
与传统put()方法不同的是,该方法【不可能添加新的 key-value 对】 。
如果尝试替换的 key 在原 Map 中不存在,该方法不会添加 key-value 对 , 而是返回 null

> Object computelfAbsent(Object key, Function mappingFunction):
如 果传给该方法的 key 参数在Map 中对应的 value 为 null
则使用 mappingFunction 根据 key 计算一个新的结果,如果计算结
果不为 null ,则用计算结果覆盖原有的 value。如果原 Map 原来不包括该 key,那么该方法可能
会添加一组 key-value 对。

> Object computelfPresent(Object key, BiFunction remappingFunction):
如果传给该方法的 key 参数在 Map 中对应的 value 不为 null
该方法将使用 remappingFunction 根据原 key、 value 计算一个
新的结果 ,如果计算结果不为 null ,则使用该结果覆盖原来的 value; 如果计算结果为 null ,则
删除原 key-value 对 。

03Map集合遍历方式keySet方法

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
A:Map集合遍历方式"keySet方法"
1.获取Map集合中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键
2.遍历键的Set集合,得到每一个键
3.根据键利用get(key)去Map找所对应的值
"/*
* Map集合的遍历
* 利用键获取值
* Map接口中定义方法keySet
* 所有的键,存储到Set集合
*/"
public class MapDemo1 {
public static void main(String[] args) {
"/*
* 1. 调用map集合的方法keySet,所有的键存储到Set集合中
* 2. 遍历Set集合,获取出Set集合中的所有元素 (Map中的键)
* 3. 调用map集合方法get,通过键获取到值
*/"
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("a", 11);
map.put("b", 12);
map.put("c", 13);
map.put("d", 14);

"//1. 调用map集合的方法keySet,所有的键存储到Set集合中"
Set<String> set = map.keySet();
"//2. 遍历Set集合,获取出Set集合中的所有元素 (Map中的键)"
Iterator<String> it = set.iterator();
while(it.hasNext()){
"//it.next返回是Set集合元素,也就是Map中的键
//3. 调用map集合方法get,通过键获取到值"
String key = it.next();
Integer value = map.get(key);
System.out.println(key+"...."+value);
}

System.out.println("=======================");

// for Each方法更简便
for(String key : map.keySet()){
Integer value = map.get(key);
System.out.println(key+"...."+value);
}
}
}

04Map集合Entry对象

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
在Map类设计时,提供了一个"嵌套接口""Entry"
Entry将"【键值对】的【对应关系】""封装成了对象",即"键值对对象"
这样我们在遍历Map集合时,就可以从每一个"键值对(Entry)对象"中获取对应的"键"与对应的"值"
"entrySet()方法":用于"返回"Map集合中所有的"键值对(Entry)对象",以"Set集合"形式返回。
A:Map集合Entry对象
interface Map{
interface Entry{"//Entry是Map的一个【内部接口】,是static的"
//由Map的子类的内部类实现

}
}
class HashMap{
static class Entry<K,V> implements Map.Entry<K,V> {//Entry对象指的就是该类的对象
final K key;
V value;
}
}
在Map类设计时,提供了一个"嵌套接口:Entry"
Entry将键值对的对应关系封装成了对象。
"键值对对象",这样我们在遍历Map集合时,就可以"从每一个键值对(Entry)对象中获取对应的键与对应的值"
a:Entry是Map接口中提供的一个"静态内部嵌套接口"
b:相关方法
"getKey()方法":获取Entry对象中的"键"
"getValue()方法":获取Entry对象中的"值"
"entrySet()方法":用于"返回"Map集合中所有的"键值对(Entry)对象",以"Set集合形式返回"

05Map集合遍历方式entrySet方法

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
A:Map集合遍历方式"entrySet方法"
*
* Map集合获取方式
* entrySet方法,"键值对映射关系"获取
* 实现步骤:
* 1. 调用map集合方法entrySet()将集合中的"映射关系对象","存储""Set集合"
*" Set<Map.Entry<K, V>> entrySet();
*" 2." 迭代Set集合"
* 3. 获取出的"Set集合的元素",是"映射关系对象Map.Entry<K, V>"
* 4. 通过映射关系对象的方法" getKet(), getValue()"获取"键值对"
*
* 创建内部类对象 外部类.内部类 = new
*/
public class MapDemo2 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "abc");
map.put(2, "bcd");
map.put(3, "cde");
"//1. 调用map集合方法entrySet()将集合中的映射关系对象,存储到Set集合"
Set<Map.Entry <Integer,String> > set = map.entrySet();
"//2. 迭代Set集合"
Iterator<Map.Entry <Integer,String> > it = set.iterator();
while(it.hasNext()){
"// 3. 获取出的Set集合的元素,是映射关系对象
// it.next 获取的是Map.Entry对象"
Map.Entry<Integer, String> entry = it.next();
"//4. 通过映射关系对象方法 getKet, getValue获取键值对"
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"...."+value);
}


}
}

06Map集合遍历方式增强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
A:Map集合遍历方式"增强for循环"
A:Map集合遍历方式"entrySet方法"
*
* Map集合获取方式
* entrySet方法,"键值对映射关系"获取
* 实现步骤:
* 1. 调用map集合方法entrySet()将集合中的"映射关系对象","存储""Set集合"
*" Set<Map.Entry<K, V>> entrySet();
*" 2." 迭代Set集合"
* 3. 获取出的"Set集合的元素",是"映射关系对象Map.Entry<K, V>"
* 4. 通过映射关系对象的方法" getKet(), getValue()"获取"键值对"
*
* 创建内部类对象 外部类.内部类 = new
*/
——————————————————————————————————————————————————————————————————————————————————————
"注意":Map接口"没有"继承自"Iterable<E>接口"
"【不能】"直接使用"迭代器或者foreach"进行遍历。"转成Set之后"才可以使用。
——————————————————————————————————————————————————————————————————————————————————————

public class MapDemo2 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "abc");
map.put(2, "bcd");
map.put(3, "cde");
//1. 调用map集合方法entrySet()将集合中的映射关系对象,存储到Set集合
Set<Map.Entry <Integer,String> > set = map.entrySet();
//2. 迭代Set集合
Iterator<Map.Entry <Integer,String> > it = set.iterator();
while(it.hasNext()){
// 3. 获取出的Set集合的元素,是映射关系对象
// it.next 获取的是什么对象,也是Map.Entry对象
Map.Entry<Integer, String> entry = it.next();
//4. 通过映射关系对象方法 getKet, getValue获取键值对
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"...."+value);
}

System.out.println("=========================");
for(Map.Entry<Integer, String> entry : map.entrySet()){
System.out.println(entry.getKey()+"..."+entry.getValue());
}
}
}
——————————————————————————————————————————————————————————————————————————————————————
"注意:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。"
——————————————————————————————————————————————————————————————————————————————————————

07HashMap集合存储和遍历

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
A:HashMap集合存储和遍历
"/*
* 使用HashMap集合,存储自定义的对象
* 自定义对象,作为键,出现,作为值出现
*/"
public class HashMapDemo {
public static void main(String[] args) {
function_1();
}
"/*
* HashMap 存储自定义对象Person,作为键出现
* 键的对象,是Person类型,值是字符串
* 保证键的唯一性,存储到键的对象,【【重写hashCode equals】】,见下面的Person类
*/"
public static void function_1(){
HashMap<Person, String> map = new HashMap<Person, String>();
map.put(new Person("a",20), "里约热内卢");
map.put(new Person("b",18), "索马里");
map.put(new Person("b",18), "索马里");
map.put(new Person("c",19), "百慕大");
for(Person key : map.keySet()){
String value = map.get(key);
System.out.println(key+"..."+value);
}
System.out.println("===================");
for(Map.Entry<Person, String> entry : map.entrySet()){
System.out.println(entry.getKey()+"..."+entry.getValue());
}
}

"/*
* HashMap 存储自定义的对象Person,作为值出现
* 【【键的对象,是字符串,可以保证唯一性】】
*/"
public static void function(){
HashMap<String, Person> map = new HashMap<String, Person>();
map.put("beijing", new Person("a",20));
map.put("tianjin", new Person("b",18));
map.put("shanghai", new Person("c",19));
for(String key : map.keySet()){
Person value = map.get(key);
System.out.println(key+"..."+value);
}
System.out.println("=================");
for(Map.Entry<String, Person> entry : map.entrySet()){
String key = entry.getKey();
Person value = entry.getValue();
System.out.println(key+"..."+value);
}
}
}


public class Person {
private String name;
private int age;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

//重写方法hashCode和equals
@Override
public int hashCode(){
return this.name.hashCode()+this.age*31;
}
@Override
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(obj instanceof Person){
Person p = (Person) obj;
return Objects.equals(this.name,p.name) && this.age==p.age;
// return this.name.equals(p.name) && this.age==p.age;
}
return false;
}
}

08LinkedHashMap的特点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
*A:LinkedHashMap的特点

"/*
* LinkedHashMap继承HashMap
* 保证迭代的顺序,有序的HashMap
*/"
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> link = new LinkedHashMap<String, String>();
link.put("1", "a");
link.put("13", "a");
link.put("15", "a");
link.put("17", "a");
System.out.println(link);
}
}

09Hashtable的特点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*A:Hashtable的特点
*
* "Map接口实现类 Hashtable"
* 底层数据结果哈希表,特点和HashMap是一样的
* "Hashtable" "线程安全"集合,运行"速度慢"
* "HashMap" "线程不安全"的集合,运行"速度快"
*
* Hashtable命运和Vector是一样的,从JDK1.2开始,被更先进的HashMap取代
*
* "HashMap" "允许存储""null值,null键"
* "Hashtable" "不允许存储""null值,null键"
*
* Hashtable他的孩子,"子类 Properties 依然活跃"在开发舞台
*
public class HashtableDemo {
public static void main(String[] args) {
Map<String,String> map = new Hashtable<String,String>();
map.put(null, null);
System.out.println(map);
}
}

10静态导入

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
*A:静态导入:如果"本类"中有和"静态导入""同名方法""优先使用""本类"
如果还想使用静态导入的,依然需要类名来调用
"/*
* JDK1.5新特性,静态导入
* 减少开发的代码量
* 标准的写法,【导入包】的时候才能使用
*
* import static java.lang.System.out;【最末尾】,【必须】是一个【静态成员】
*/"
import static java.lang.System.out;
import static java.util.Arrays.sort;


public class StaticImportDemo {
public static void main(String[] args) {
out.println("hello");

int[] arr = {1,4,2};
sort(arr);
}
}

例如:Map.Entry的访问,简化后为Entry
import static java.util.Map.Entry;
public class HashMapTest {
public static void main(String[] args) {
"//1,创建hashmap集合对象。"
Map<Student,String> map = new HashMap<Student,String>();

"//取出元素。键值对方式"
//Set<Map.Entry<Student, String>> entrySet = map.entrySet();
Set<Entry<Student, String>> entrySet = map.entrySet();//静态导入后,直接用Entry

//for (Map.Entry<Student, String> entry : entrySet) {
for (Entry<Student, String> entry : entrySet) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key.toString()+"....."+value);
}
}
}

11方法的可变参数

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
*A:方法的可变参数
*
* JDK1.5新的特性,"方法的可变参数"
* 前提: 方法参数数据类型确定,"参数的个数""任意"
* 可变参数语法: "数据类型...变量名"
* "可变参数","本质"就是一个"数组"
*/
public class VarArgumentsDemo {
public static void main(String[] args) {
//调用一个带有可变参数的方法,传递参数,可以任意
// getSum();
int sum = getSum(5,34,3,56,7,8,0);
System.out.println(sum);

}

/*
* 定义方法,计算10个整数和
* 方法的可变参数实现
*/
public static int getSum(int...a){
int sum = 0 ;
for(int i : a){
sum = sum + i;
}
return sum;
}

"可变参数","本质"就是一个"数组"
private static void func(int ... arr){
for(int i=0;i<arr.length;i++){
arr[i] *= 2;
System.out.println(arr[i]);
}

}
}

12可变参数的注意事项

1
2
3
4
5
6
7
8
9
*A:可变参数的注意事项    
*
* 可变参数的注意事项
* 1. "一个方法中,【可变参数】"只能"有【一个】"
* 2. 方法的"参数列表""可变参数""普通参数""都有"时,"必须"写在参数列表的"末尾位置(最后)"
*/
private static void funb(int a,int b,int ... arr){

}

13Collections工具类

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
A:Collections工具类
*
* 集合操作的工具类
* "Collections"
* 均为"静态方法",通过"Collections.方法名"进行调用
*/

public static <T> boolean addAll(Collection<? super T> c,T...elements)
将所有指定的元素添加到指定的集合。
要添加的元素【可以单独指定】或【作为数组指定】。
这种方便方法的行为与c.addAll(Arrays.asList(elements)) 相同 ,
但是在大多数实现中,【这种方法可能会显着加快】。
【单独指定元素】时,此方法为现有集合添加一些元素提供了一种便捷的方法:

Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
参数类型
T - 要添加和收集的元素的类

参数
c - 要插入 elements的集合
elements - 要插入到 c的元素

结果
true如果集合由于调用而更改

—————————————————————————————————————————————————————————————————————————————————————————
Element[] array = {new Element(1),new Element(2),new Element(3)};

"将数组转化成List":

(1)"利用ArrayList的构造方法"
ArrayList<Element> arrayList = new ArrayList<Element>(Arrays.asList(array));

ArrayList(Collection < ? extends E > c) :
构造一个包含特定容器的元素的列表ArrayList,并且根据容器迭代器的顺序返回。 
所以"构造方法"所做的事情如下: 
1.将"容器c转换为一个数组" 
2.将"数组拷贝到ArrayList中称为”elementData”的数组"中 
ArrayList的构造方法的源码如下:

public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
—————————————————————————————————————————————————————————————————————————————————————————

(2)"Arrays.asList(array)方法"
List<Element> list1 = Arrays.asList(array);

"asList()返回的列表的大小是固定的"
事实上,返回的列表"不是java.util.ArrayList",而是定义在java.util.Arrays中一个"私有静态类"
我们知道ArrayList的实现本质上是一个数组,而asList()返回的列表是由原始数组支持的固定大小的列表。
这种情况下,如果"添加或删除列表中的元素,程序会抛出异常"UnsupportedOperationException。

—————————————————————————————————————————————————————————————————————————————————————————
(3)(java.util.Collections包),"Collections.addAll(list2, array)方法"
List<element> list2 = new ArrayList<element>();
Collections.addAll(list2, array);

"这种方便方法的行为与c.addAll(Arrays.asList(elements)) 相同 ,
但是在大多数实现中,这种方法可能会显着加快"

—————————————————————————————————————————————————————————————————————————————————————————

public class CollectionsDemo {
public static void main(String[] args) {
function_2();
}
"/*
* Collections.shuffle方法
* 对List集合中的元素,进行随机排列
*/"
public static void function_2(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(5);
list.add(9);
list.add(11);
list.add(8);
list.add(10);
list.add(15);
list.add(20);
System.out.println(list);

//调用工具类方法shuffle对集合随机排列
Collections.shuffle(list);
System.out.println(list);
}

"/*
* Collections.binarySearch静态方法
* 对List集合进行二分搜索,方法参数,传递List集合,传递被查找的元素
* !!!注意:使用该方法前,"必须"先进行"排序"
*/"
public static void function_1(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(5);
list.add(8);
list.add(10);
list.add(15);
list.add(20);
//调用工具类静态方法binarySearch
int index = Collections.binarySearch(list, 16);
System.out.println(index);
}

"/*
* Collections.sort静态方法
* 对于List集合,进行"升序排列"
*/"
public static void function(){
//创建List集合
List<String> list = new ArrayList<String>();
list.add("ewrew");
list.add("qwesd");
list.add("Qwesd");
list.add("bv");
list.add("wer");
System.out.println(list);
//调用集合工具类的方法sort
Collections.sort(list);
System.out.println(list);
}
}

14集合的嵌套

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
A:集合的嵌套
/*
* Map集合的嵌套,Map中存储的还是Map集合
* 要求:
* 传智播客
* Java基础班
* 001 张三
* 002 李四
*
* Java就业班
* 001 王五
* 002 赵六
* 对以上数据进行对象的存储
* 001 张三 键值对
* Java基础班: 存储学号和姓名的键值对
* Java就业班:
* 传智播客: 存储的是班级
*
* 基础班Map <学号,姓名>
* 传智播客Map <班级名字, 基础班Map>
*/
public class MapMapDemo {
public static void main(String[] args) {
//定义基础班集合
HashMap<String, String> javase = new HashMap<String, String>();
//定义就业班集合
HashMap<String, String> javaee = new HashMap<String, String>();
//向班级集合中,存储学生信息
javase.put("001", "张三");
javase.put("002", "李四");

javaee.put("001", "王五");
javaee.put("002", "赵六");
//定义传智播客集合容器,键是班级名字,值是两个班级容器
HashMap<String, HashMap<String,String>> czbk =
new HashMap<String, HashMap<String,String>>();
czbk.put("基础班", javase);
czbk.put("就业班", javaee);

keySet(czbk);

}

15集合的嵌套keySet遍历

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
A:集合的嵌套keySet遍历
/*
* Map集合的嵌套,Map中存储的还是Map集合
* 要求:
* 传智播客
* Java基础班
* 001 张三
* 002 李四
*
* Java就业班
* 001 王五
* 002 赵六
* 对以上数据进行对象的存储
* 001 张三 键值对
* Java基础班: 存储学号和姓名的键值对
* Java就业班:
* 传智播客: 存储的是班级
*
* 基础班Map <学号,姓名>
* 传智播客Map <班级名字, 基础班Map>
*/
public class MapMapDemo {
public static void main(String[] args) {
//定义基础班集合
HashMap<String, String> javase = new HashMap<String, String>();
//定义就业班集合
HashMap<String, String> javaee = new HashMap<String, String>();
//向班级集合中,存储学生信息
javase.put("001", "张三");
javase.put("002", "李四");

javaee.put("001", "王五");
javaee.put("002", "赵六");
//定义传智播客集合容器,键是班级名字,值是两个班级容器
HashMap<String, HashMap<String,String>> czbk =
new HashMap<String, HashMap<String,String>>();
czbk.put("基础班", javase);
czbk.put("就业班", javaee);

keySet(czbk);

}


"//keySet() Iterator 遍历"
public static void keySet(HashMap<String,HashMap<String,String>> czbk){
"//调用czbk集合方法keySet将键存储到Set集合"
Set<String> classNameSet = czbk.keySet();
"//迭代Set集合"
Iterator<String> classNameIt = classNameSet.iterator();
while(classNameIt.hasNext()){
"//classNameIt.next获取出来的是Set集合元素,czbk集合的键"
String classNameKey = classNameIt.next();
"//czbk集合的方法get获取值,值是一个HashMap集合"
HashMap<String,String> classMap = czbk.get(classNameKey);
"//调用classMap集合方法keySet,键存储到Set集合"
Set<String> studentNum = classMap.keySet();
Iterator<String> studentIt = studentNum.iterator();

while(studentIt.hasNext()){
"//studentIt.next获取出来的是classMap的键,学号"
String numKey = studentIt.next();
"//调用classMap集合中的get方法获取值"
String nameValue = classMap.get(numKey);
System.out.println(classNameKey+".."+numKey+".."+nameValue);
}
}

System.out.println("==================================");
"//keySet() forEach 遍历"
for(String className: czbk.keySet()){
HashMap<String, String> hashMap = czbk.get(className);
for(String numKey : hashMap.keySet()){
String nameValue = hashMap.get(numKey);
System.out.println(className+".."+numKey+".."+nameValue);
}
}
}

}

16集合的嵌套entrySet遍历

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
A:集合的嵌套entrySet遍历
/*
* Map集合的嵌套,Map中存储的还是Map集合
* 要求:
* 传智播客
* Java基础班
* 001 张三
* 002 李四
*
* Java就业班
* 001 王五
* 002 赵六
* 对以上数据进行对象的存储
* 001 张三 键值对
* Java基础班: 存储学号和姓名的键值对
* Java就业班:
* 传智播客: 存储的是班级
*
* 基础班Map <学号,姓名>
* 传智播客Map <班级名字, 基础班Map>
*/
public class MapMapDemo {
public static void main(String[] args) {
//定义基础班集合
HashMap<String, String> javase = new HashMap<String, String>();
//定义就业班集合
HashMap<String, String> javaee = new HashMap<String, String>();
//向班级集合中,存储学生信息
javase.put("001", "张三");
javase.put("002", "李四");

javaee.put("001", "王五");
javaee.put("002", "赵六");
//定义传智播客集合容器,键是班级名字,值是两个班级容器
HashMap<String, HashMap<String,String>> czbk =
new HashMap<String, HashMap<String,String>>();
czbk.put("基础班", javase);
czbk.put("就业班", javaee);

entrySet(czbk);
}

"//entrySet() Iterator 遍历"
public static void entrySet(HashMap<String,HashMap<String,String>> czbk){
"//调用czbk集合方法entrySet方法,将czbk集合的键值对关系对象,存储到Set集合"
Set<Map.Entry<String, HashMap<String,String>>>
classNameSet = czbk.entrySet();
"//迭代器迭代Set集合"
Iterator<Map.Entry<String, HashMap<String,String>>> classNameIt = classNameSet.iterator();
while(classNameIt.hasNext()){
"//classNameIt.next方法,取出的是czbk集合的键值对关系对象"
Map.Entry<String, HashMap<String,String>> classNameEntry = classNameIt.next();
//classNameEntry方法 getKey,getValue
String classNameKey = classNameEntry.getKey();
"//获取值,值是一个Map集合"
HashMap<String,String> classMap = classNameEntry.getValue();
"//调用班级集合classMap方法entrySet,键值对关系对象存储Set集合"
Set<Map.Entry<String, String>> studentSet = classMap.entrySet();
"//迭代Set集合"
Iterator<Map.Entry<String, String>> studentIt = studentSet.iterator();
while(studentIt.hasNext()){
"//studentIt方法next获取出的是班级集合的键值对关系对象"
Map.Entry<String, String> studentEntry = studentIt.next();
//studentEntry方法 getKey getValue
String numKey = studentEntry.getKey();
String nameValue = studentEntry.getValue();
System.out.println(classNameKey+".."+numKey+".."+nameValue);
}
}
System.out.println("==================================");
"//entrySet() Iterator 遍历"
for (Map.Entry<String, HashMap<String, String>> me : czbk.entrySet()) {
String classNameKey = me.getKey();
HashMap<String, String> numNameMapValue = me.getValue();
for (Map.Entry<String, String> nameMapEntry : numNameMapValue.entrySet()) {
String numKey = nameMapEntry.getKey();
String nameValue = nameMapEntry.getValue();
System.out.println(classNameKey + ".." + numKey + ".." + nameValue);
}
}
}


}

17集合应用举例:斗地主的功能分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
A:斗地主的功能分析
a:具体规则:
1. 组装54张扑克牌
2. 将54张牌顺序打乱
3. 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
4. 查看三人各自手中的牌(按照牌的大小排序)、底牌
b:分析:
1.准备牌:
完成数字与纸牌的映射关系:
使用双列Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系(相当于一个字典)。
2.洗牌:
通过数字完成洗牌发牌
3.发牌:
将每个人以及底牌设计为ArrayList<String>,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
存放的过程中要求数字大小与斗地主规则的大小对应。
将代表不同纸牌的数字分配给不同的玩家与底牌。
4.看牌:
通过Map集合找到对应字符展示。
通过查询纸牌与数字的对应关系,由数字转成纸牌字符串再进行展示。

18斗地主的准备牌

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
A:斗地主的准备牌
/*
* 实现模拟斗地主的功能
* 1. 组合牌
* 2. 洗牌
* 3. 发牌
* 4. 看牌
*/
public class DouDiZhu {
public static void main(String[] args) {
//1. 组合牌
//创建Map集合,键是编号,值是牌
HashMap<Integer,String> pooker = new HashMap<Integer, String>();
//创建List集合,存储编号
ArrayList<Integer> pookerNumber = new ArrayList<Integer>();
//定义出13个点数的数组
String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//定义4个花色数组
String[] colors = {"♠","♥","♣","♦"};
//定义整数变量,作为键出现
int index = 2;
//遍历数组,花色+点数的组合,存储到Map集合
for(String number : numbers){
for(String color : colors){
pooker.put(index, color+number);
pookerNumber.add(index);
index++;
}
}
//存储大王,和小王,索引是从0~54,对应大王,小王,...3(牌的顺序从大到小)
pooker.put(0, "大王");
pookerNumber.add(0);
pooker.put(1, "小王");
pookerNumber.add(1);

}

19斗地主的洗牌

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
A:斗地主的洗牌
/*
* 实现模拟斗地主的功能
* 1. 组合牌
* 2. 洗牌
* 3. 发牌
* 4. 看牌
*/
public class DouDiZhu {
public static void main(String[] args) {
//1. 组合牌
//创建Map集合,键是编号,值是牌
HashMap<Integer,String> pooker = new HashMap<Integer, String>();
//创建List集合,存储编号
ArrayList<Integer> pookerNumber = new ArrayList<Integer>();
//定义出13个点数的数组
String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//定义4个花色数组
String[] colors = {"♠","♥","♣","♦"};
//定义整数变量,作为键出现
int index = 2;
//遍历数组,花色+点数的组合,存储到Map集合
for(String number : numbers){
for(String color : colors){
pooker.put(index, color+number);
pookerNumber.add(index);
index++;
}
}
//存储大王,和小王
pooker.put(0, "大王");
pookerNumber.add(0);
pooker.put(1, "小王");
pookerNumber.add(1);

//洗牌,将牌的编号打乱
Collections.shuffle(pookerNumber);


}

}

20斗地主的发牌

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
60
61
62
63
64
65
66
A:斗地主的发牌
/*
* 实现模拟斗地主的功能
* 1. 组合牌
* 2. 洗牌
* 3. 发牌
* 4. 看牌
*/
public class DouDiZhu {
public static void main(String[] args) {
//1. 组合牌
//创建Map集合,键是编号,值是牌
HashMap<Integer,String> pooker = new HashMap<Integer, String>();
//创建List集合,存储编号
ArrayList<Integer> pookerNumber = new ArrayList<Integer>();
//定义出13个点数的数组
String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//定义4个花色数组
String[] colors = {"♠","♥","♣","♦"};
//定义整数变量,作为键出现
int index = 2;
//遍历数组,花色+点数的组合,存储到Map集合
for(String number : numbers){
for(String color : colors){
pooker.put(index, color+number);
pookerNumber.add(index);
index++;
}
}
//存储大王,和小王
pooker.put(0, "大王");
pookerNumber.add(0);
pooker.put(1, "小王");
pookerNumber.add(1);

//洗牌,将牌的编号打乱
Collections.shuffle(pookerNumber);

//发牌功能,将牌编号,发给玩家集合,底牌集合
ArrayList<Integer> player1 = new ArrayList<Integer>();
ArrayList<Integer> player2 = new ArrayList<Integer>();
ArrayList<Integer> player3 = new ArrayList<Integer>();
ArrayList<Integer> bottom = new ArrayList<Integer>();

//发牌采用的是集合索引%3
for(int i = 0 ; i < pookerNumber.size() ; i++){
//先将底牌做好
if(i < 3){
//存到底牌去
bottom.add( pookerNumber.get(i));
//对索引%3判断
}else if(i % 3 == 0){
//索引上的编号,发给玩家1
player1.add( pookerNumber.get(i) );
}else if( i % 3 == 1){
//索引上的编号,发给玩家2
player2.add( pookerNumber.get(i) );
}else if( i % 3 == 2){
//索引上的编号,发给玩家3
player3.add( pookerNumber.get(i) );
}
}

}

}

21斗地主的看牌

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
A:斗地主的看牌
/*
* 实现模拟斗地主的功能
* 1. 组合牌
* 2. 洗牌
* 3. 发牌
* 4. 看牌
*/
public class DouDiZhu {
public static void main(String[] args) {
//1. 组合牌
//创建Map集合,键是编号,值是牌
HashMap<Integer,String> pooker = new HashMap<Integer, String>();
//创建List集合,存储编号
ArrayList<Integer> pookerNumber = new ArrayList<Integer>();
//定义出13个点数的数组
String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//定义4个花色数组
String[] colors = {"♠","♥","♣","♦"};
//定义整数变量,作为键出现
int index = 2;
//遍历数组,花色+点数的组合,存储到Map集合
for(String number : numbers){
for(String color : colors){
pooker.put(index, color+number);
pookerNumber.add(index);
index++;
}
}
//存储大王,和小王
pooker.put(0, "大王");
pookerNumber.add(0);
pooker.put(1, "小王");
pookerNumber.add(1);

//洗牌,将牌的编号打乱
Collections.shuffle(pookerNumber);

//发牌功能,将牌编号,发给玩家集合,底牌集合
ArrayList<Integer> player1 = new ArrayList<Integer>();
ArrayList<Integer> player2 = new ArrayList<Integer>();
ArrayList<Integer> player3 = new ArrayList<Integer>();
ArrayList<Integer> bottom = new ArrayList<Integer>();

//发牌采用的是集合索引%3
for(int i = 0 ; i < pookerNumber.size() ; i++){
//先将底牌做好
if(i < 3){
//存到底牌去
bottom.add( pookerNumber.get(i));
//对索引%3判断
}else if(i % 3 == 0){
//索引上的编号,发给玩家1
player1.add( pookerNumber.get(i) );
}else if( i % 3 == 1){
//索引上的编号,发给玩家2
player2.add( pookerNumber.get(i) );
}else if( i % 3 == 2){
//索引上的编号,发给玩家3
player3.add( pookerNumber.get(i) );
}
}
//对玩家手中的编号排序
Collections.sort(player1);
Collections.sort(player2);
Collections.sort(player3);
//看牌,将玩家手中的编号,到Map集合中查找,根据键找值
//定义方法实现
look("刘德华",player1,pooker);
look("张曼玉",player2,pooker);
look("林青霞",player3,pooker);
look("底牌",bottom,pooker);
}
public static void look(String name,ArrayList<Integer> player,HashMap<Integer,String> pooker){
//遍历ArrayList集合,获取元素,作为键,到集合Map中找值
System.out.print(name+" ");
for(Integer key : player){
String value = pooker.get(key);
System.out.print(value+" ");
}
System.out.println();
}
}

小结

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
60
61
62
63
64
65
 Map集合: 
map集合中的元素都是成对出现,成对存储的
map集合中的元素都是以一对键和值的形式组成存在的,称为键值对
map集合中的键不能重复存储,值可以重复
map集合中的每一个键 对应着一个值
 方法:
V put(K key, V value) 把指定的键与指定的值添加到Map集合中
V remove(Object key) 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值
Set<Map.Entry<K,V>> entrySet() 获取到Map集合中所有的键值对对象的集合(Set集合)
V get(Object key) 根据指定的键,在Map集合中获取对应的值
Set<K> keySet() 获取Map集合中所有的键,存储到Set集合中

——————————————————————————————————————————————————————————————————————————————————————
 Map集合遍历的两种方式
 方式1:根据键找值的方式
//a, 获取到Map集合中所有的键,返回对应的Set集合
//b, 遍历键的集合,获取到每一个键
//c, 通过键,找到对应的值

//获取到Map集合中所有的键,返回对应的Set集合
Set<String> keys = map.keySet();
//遍历键的集合,获取到每一个键
for (String key : keys) {
//通过键,找到对应的值
Student s = map.get(key);
System.out.println( key + "..." + s.getName() + "..." + s.getAge() );
}
——————————————————————————————————————————————————————————
 方式2:根据键值对对象找键和值的方式
//a, 获取Map集合中所有的键值对元素,返回对应的Set集合
//b, 遍历键值对元素集合,获取到每一个键值对元素对象
//c, 通过键值对元素对象,获取对应的键,和对应的值

//获取Map集合中所有的键值对元素,返回对应的Set集合
Set< Map.Entry<String, Student>> entrySet = map.entrySet();
//遍历键值对元素集合,获取到每一个键值对元素对象
for (Map.Entry<String, Student> entry : entrySet) {
//通过键值对元素对象,获取对应的键,和对应的值
//找键
String key = entry.getKey();
//找值
Student s = entry.getValue();
//打印
System.out.println( key+"..."+s.getName()+"..."+s.getAge() );
}

——————————————————————————————————————————————————————————————————————————————————————
 HashMap:
 特点:
"是Map集合的子集合
底层采用【哈希表】结构
HashMap集合中的key不能重复,通过【重写】hashCode() 与 equals()方法来保证【键的唯一】。
【不能保证】元素存与取的【顺序】完全一致"

——————————————————————————————————————————————————————————————————————————————————————
 LinkedHashMap:
 特点:
"是HashMap集合的子集合
底层采用【哈希表+链表】结构
LinkedHashMap集合中的key【不能重复】,通过【重写】hashCode() 与 equals()方法来保证【键的唯一】"

——————————————————————————————————————————————————————————————————————————————————————
 Collections中的方法:
public static <T> void sort(List<T> list) 排序
public static void shuffle(List<?> list) 集合中的元素存储位置随机打乱
-------------本文结束感谢您的阅读-------------
感谢您的支持,我会继续努力的!
0%