1集合体系概述
1.1集合的概念
集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。
1.2集合分类
集合分为单列集合和多列集合
Collection代表单列集合,每个元素(数据)只包含一个值。
Map代表双列集合,每个元素包含两个值(键值对)。
1.3Colleection集合体系
Collection集合特点
List系列集合:添加的元素是有序、可重复、有索引。
- ArrayList、LinekdList :有序、可重复、有索引。
Set系列集合:添加的元素是无序、不重复、无索引。
- HashSet: 无序、不重复、无索引;
- LinkedHashSet: 有序(先添加的再前面,后添加的再后面)、不重复、无索引。
- TreeSet:按照大小默认升序排序、不重复、无索引。
1.4Map集合体系
Map集合体系的特点
注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的
- HashMap(由键决定特点): 无序、不重复、无索引; (用的最多)
- LinkedHashMap (由键决定特点):由键决定的特点:有序(先添加的再前面,后添加的再后面)、不重复、无索引。
- TreeMap (由键决定特点):按照大小默认升序排序、不重复、无索引。
2.Collection集合
2.1 Collection的常用方法
为啥要先学Collection的常用方法?
Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。
举例说明:
package com.test.可删;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); // 多态写法
// 1.public boolean add(E e):添加元素, 添加成功返回true。
c.add("java1");
c.add("java1");
c.add("java2");
c.add("java2");
c.add("java3");
System.out.println(c);//[java1, java1, java2, java2, java3]
// 2.public boolean isEmpty():判断集合是否为空 是空返回true,反之。
System.out.println(c.isEmpty()); // false
// 3.public int size():获取集合的大小。
System.out.println(c.size());//5
// 4.public boolean contains(Object obj):判断集合中是否包含某个元素。
System.out.println(c.contains("java1")); // true
System.out.println(c.contains("Java1")); // false
// 5.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
System.out.println(c.remove("java1"));//true
System.out.println(c);//[java1, java2, java2, java3]
// 6.public Object[] toArray():把集合转换成数组
Object[] arr = c.toArray();
System.out.println(Arrays.toString(arr));//[java1, java2, java2, java3]
// 7.public void clear():清空集合的元素。
c.clear();
System.out.println(c);//[]
}
}
扩展:把一个集合的全部数据倒入到另一个集合中去
package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 把一个集合的全部数据倒入到另一个集合中去。
Collection<String> c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String> c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2); // 就是把c2集合的全部数据倒入到c1集合中去。
System.out.println(c1);//[java1, java2, java3, java4]
System.out.println(c2);//[java3, java4]
}
}
2.2Collection的遍历方式
2.2.1迭代器
迭代器概述
迭代器是用来遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator。
Collection集合获取迭代器的方法
Iterator迭代器中的常用方法
举例
package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
System.out.println(c);
// c = [赵敏, 小昭, 素素,灭绝]
// 使用迭代器遍历集合
// 1、从集合对象中获取迭代器对象-手动一个一个取。
Iterator<String> it = c.iterator();
// System.out.println(it.next());//赵敏
// System.out.println(it.next());//小昭
// System.out.println(it.next());//素素
// System.out.println(it.next());//灭绝
// System.out.println(it.next()); // 出现异常的
// 2、我们应该使用循环结合迭代器遍历集合。
while (it.hasNext()){
String ele = it.next();
System.out.println(ele);
}
}
}
2.2.2增强for
- 增强for可以用来遍历集合或者数组。
- 增强for遍历集合,本质就是迭代器遍历集合的简化写法。
package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
System.out.println(c);
// c = [赵敏, 小昭, 素素, 灭绝]
// 使用增强for遍历集合或者数组。
for (String ele : c) {
System.out.println(ele);
}
String[] names = {"迪丽热巴", "古力娜扎", "稀奇哈哈"};
//数组的增强for循环
for (String name : names) {
System.out.println(name);
}
}
}
2.2.3Lambda表达式
Lambda表达式遍历集合
- 得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。
需要使用Collection的如下方法来完成
package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Test {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("殷素素");
c.add("周芷若");
System.out.println(c);
// [赵敏, 小昭, 殷素素, 周芷若]
// default void forEach(Consumer<? super T> action): 结合Lambda表达式遍历集合:
c.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//简化
c.forEach((String s) -> {
System.out.println(s);
});
//简化
c.forEach(s -> {
System.out.println(s);
});
//简化
c.forEach(s -> System.out.println(s) );
//最终简化表达式
c.forEach(System.out::println );
}
}
2.3List集合
List系列集合特点: 有序,可重复,有索引
- ArrayList:有序,可重复,有索引。
- LinkedList:有序,可重复,有索引。
2.3.1List集合的特有方法
List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。
package com.test.可删;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
// 1.创建一个ArrayList集合对象(有序、可重复、有索引)
List<String> list = new ArrayList<>(); // 一行经典代码
list.add("蜘蛛精");
list.add("至尊宝");
list.add("至尊宝");
list.add("牛夫人");
System.out.println(list); // [蜘蛛精, 至尊宝, 至尊宝, 牛夫人]
// 2.public void add(int index, E element): 在某个索引位置插入元素。
list.add(2, "紫霞仙子");
System.out.println(list);//[蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人]
// 3.public E remove(int index): 根据索引删除元素,返回被删除元素
System.out.println(list.remove(2));//紫霞仙子
System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]
// 4.public E get(int index): 返回集合中指定位置的元素。
System.out.println(list.get(3));//牛夫人
// 5.public E set(int index, E element): 修改索引位置处的元素,修改成功后,会返回原来的数据
System.out.println(list.set(3, "牛魔王"));//牛夫人
System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛魔王]
}
}
2.3.2List集合支持的遍历方式
- for循环(因为List集合有索引)
- 迭代器
- 增强for循环
- Lambda表达式
第2,3,4的遍历方式,如有不清楚,见2.2小节
package com.test.可删;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("糖宝宝");
list.add("蜘蛛精");
list.add("至尊宝");
//(1)for循环
for (int i = 0; i < list.size(); i++) {
// i = 0 1 2
String s = list.get(i);
System.out.println(s);
}
//(2)迭代器。
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
//(3)增强for循环(foreach遍历)
for (String s : list) {
System.out.println(s);
}
//(4)JDK 1.8开始之后的Lambda表达式
list.forEach(s -> {
System.out.println(s);
});
}
}
2.3.3ArrayList集合
2.3.3.1ArrayList集合的底层原理
2.3.3.2ArrayList集合适合和不适合的应用场景
- ArrayList适合:根据索引查询数据,比如根据随机索引取数据(高效)!或者数据量不是很大时!
- ArrayList不适合:数据量大的同时又要频繁的进行增删操作!
2.3.4LinkedList集合
2.3.4.1 LinkedList集合的底层原理
- 基于双链表实现的。
- 特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
LinkedList新增了:很多首尾操作的特有方法。
2.3.4.2LinkedList的应用场景
LinkedList的应用场景之一:可以用来设计队列(先进先出,后进后出)(只是在首尾增删元素,用LinkedList来实现很合适!)
LinkedList的应用场景之一:可以用来设计栈(先进后出,后进先出)(只是在首部增删元素,用LinkedList来实现很合适!)
package com.test.可删;
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
// 1、创建一个队列。
LinkedList<String> queue = new LinkedList<>();
// 入队
queue.addLast("第1号人");
queue.addLast("第2号人");
queue.addLast("第3号人");
queue.addLast("第4号人");
System.out.println(queue);//[第1号人, 第2号人, 第3号人, 第4号人]
// 出队
System.out.println(queue.removeFirst());//第1号人
System.out.println(queue.removeFirst());//第2号人
System.out.println(queue.removeFirst());//第3号人
System.out.println(queue);//[第4号人]
System.out.println("--------------------------------------------------");
// 2、创建一个栈对象。
LinkedList<String> stack = new LinkedList<>();
// 压栈(push)
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
stack.push("第4颗子弹");
System.out.println(stack);//[第4颗子弹, 第3颗子弹, 第2颗子弹, 第1颗子弹]
// 出栈(pop)
System.out.println(stack.pop());//第4颗子弹
System.out.println(stack.pop());//第3颗子弹
System.out.println(stack);//[第2颗子弹, 第1颗子弹]
}
}
2.4Set集合
Set系列集合特点:无序:添加数据的顺序和获取出的数据顺序不一致; 不重复; 无索引;
- HashSet : 无序、不重复、无索引。
- LinkedHashSet:有序、不重复、无索引。
- TreeSet:排序、不重复、无索引。
注意: Set要用到的常用方法,基本上就是Collection提供的!! 自己几乎没有额外新增一些常用功能!
2.4.1HashSet集合
2.4.1.1哈希值
注意:在正式了解HashSet集合的底层原理前,我们需要先搞清楚一个前置知识:哈希值!
哈希值
- 就是一个int类型的数值,Java中每个对象都有一个哈希值。
- Java中的所有对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。
public int hashCode():返回对象的哈希码值。
对象哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的。
- 不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)。
2.4.1.2HashSet集合的底层原理
- 基于哈希表实现。
- 哈希表是一种增删改查数据,性能都较好的数据结构。
哈希表
JDK8之前,哈希表 = 数组+链表
JDK8开始,哈希表 = 数组+链表+红黑树
2.4.1.3两个内容一样的对象,如何让HashSet集合去重
自定义的类型的对象,比如两个内容一样的学生对象,如果让HashSet集合能够去重复!
结论:如果希望Set集合认为2个内容一样的对象是重复的, 必须重写对象的hashCode()和equals()方法
具体的实现:
java集合篇之练习题(List,Map等的应用练习)-CSDN博客
2.4.1.4LinkedHashSet集合的底层原理
LinkedHashSet:有序(添加和获取元素的顺序是一致的)、不重复、无索引。
LinkedHashSet集合的底层原理:依然是基于哈希表(数组、链表、红黑树)实现的。
但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。
2.4.2TreeSet集合
2.4.2.1TreeSet集合的特点和注意事项
特点:不重复、无索引、可排序(默认升序排序 ,按照元素的大小,由小到大排序)
底层是基于红黑树实现的排序。
注意:
对于数值类型:Integer , Double,默认按照数值本身的大小进行升序排序。
对于字符串类型:默认按照首字符的编号升序排序。
对于自定义类型如Student对象,TreeSet默认是无法直接排序的。
2.4.2.2TreeSet自定义排序规则
TreeSet集合存储自定义类型的对象时,必须指定排序规则,支持如下两种方式来指定比较规则。
方式一
让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。
方式二
通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则。
public TreeSet(Comparator<? super E> comparator)
根据方式一解决对象排序
根据方式二解决对象排序
注意:如果既用了方式一又用了方式二进行自定义排序,那么TreeSet就近选择自己自带的比较器对象进行排序;
自定义排序总结:
两种方式中,关于返回值的规则:
- 如果认为第一个元素 > 第二个元素 返回正整数即可。
- 如果认为第一个元素 < 第二个元素返回负整数即可。
- 如果认为第一个元素 = 第二个元素返回0即可,此时Treeset集合只会保留一个元素,认为两者重复。
2.5总结
1)、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据?
用ArrayList集合(有序、可重复、有索引),底层基于数组的。(常用)
2)、如果希望记住元素的添加顺序,且增删首尾数据的情况较多?
用LinkedList集合(有序、可重复、有索引),底层基于双链表实现的。
3). 如果不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快?
用HashSet集合(无序,不重复,无索引),底层基于哈希表实现的。 (常用)
4).如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?
用LinkedHashSet集合(有序,不重复,无索引), 底层基于哈希表和双链表。
5). 如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?
用TreeSet集合,基于红黑树实现。
3.Collection其他相关知识
3.1可变参数
就是一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称;
可变参数的特点和好处
特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它。
好处:常常用来灵活的接收数据。
可变参数的注意事项:
- 可变参数在方法内部就是一个数组。
- 一个形参列表中可变参数只能有一个
- 可变参数必须放在形参列表的最后面
package com.test.可删;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
// 特点:
test(); // 不传数据
test(10); // 传输一个数据给它
test(10, 20, 30); // 传输多个数据给它
test(new int[]{10, 20, 30, 40}); // 传输一个数组给可变参数
}
// 注意事项1:一个形参列表中,只能有一个可变参数。
// 注意事项2:可变参数必须放在形参列表的最后面
public static void test(int...nums){
// 可变参数在方法内部,本质就是一个数组。
System.out.println(nums.length);
System.out.println(Arrays.toString(nums));
System.out.println("-----------------------------------------");
}
}
4.Collections工具类
Collections是一个用来操作集合的工具类
Collections提供的常用静态方法
package com.test.可删;
import com.test.集合框架.p140.Student;
import java.util.*;
public class Test {
public static void main(String[] args) {
// 1、public static <T> boolean addAll(Collection<? super T> c, T...elements):为集合批量添加数据
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三", "王五", "李四", "张麻子");
System.out.println(names);//[张三, 王五, 李四, 张麻子]
// 2、public static void shuffle(List<?> list):打乱List集合中的元素顺序。
Collections.shuffle(names);
System.out.println(names);
// 3、 public static <T> void sort(List<T> list):对List集合中的元素进行升序排序。
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(5);
list.add(2);
Collections.sort(list);
System.out.println(list);//[2, 3, 5]
// 4、public static <T> void sort(List<T> list, Comparator<? super T> c): 对List集合中元素,按照比较器对象指定的规则进行排序
List<Student> students = new ArrayList<>();
students.add(new Student("蜘蛛精",23, 169.7));
students.add(new Student("紫霞",22, 169.8));
students.add(new Student("紫霞",22, 169.8));
students.add(new Student("至尊宝",26, 165.5));
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getHeight(), o2.getHeight());
}
});
System.out.println(students);
}
}
注意:Collections只能支持对List集合进行排序
5.Map集合
认识Map集合
- Map集合称为双列集合,格式:{key1=value1 , key2=value2 , key3=value3 , ...}, 一次需要存一对数据做为一个元素.
- Map集合的每个元素“key=value”称为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做“键值对集合”
- Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值
Map集合在什么业务场景下使用
需要存储一一对应的数据时,就可以考虑使用Map集合来做
package com.test.可删;
import java.util.*;
public class Test {
public static void main(String[] args) {
// Map<String, Integer> map = new HashMap<>(); // 一行经典代码。 按照键 无序,不重复,无索引。
Map<String, Integer> map = new LinkedHashMap<>(); // 有序,不重复,无索引。
map.put("手表", 100);
map.put("手表", 220); // 后面重复的数据会覆盖前面的数据(键)
map.put("手机", 2);
map.put("Java", 2);
map.put(null, null);
System.out.println(map);//{手表=220, 手机=2, Java=2, null=null}
Map<Integer, String> map1 = new TreeMap<>(); // 可排序,不重复,无索引
map1.put(23, "Java");
map1.put(23, "MySQL");
map1.put(19, "李四");
map1.put(20, "王五");
System.out.println(map1);//{19=李四, 20=王五, 23=MySQL}
}
}
5.1Map集合的常用方法
Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的。
Map的常用方法如下:
package com.test.可删;
import java.util.*;
public class Test {
public static void main(String[] args) {
// 1.添加元素: 无序,不重复,无索引。
Map<String, Integer> map = new HashMap<>();
map.put("手表", 100);
map.put("手表", 220);
map.put("手机", 2);
map.put("Java", 2);
map.put(null, null);
System.out.println(map);
// map = {null=null, 手表=220, Java=2, 手机=2}
// 2.public int size():获取集合的大小
System.out.println(map.size());//4
// 3、public void clear():清空集合
//map.clear();
//System.out.println(map);//{}
// 4.public boolean isEmpty(): 判断集合是否为空,为空返回true ,反之!
System.out.println(map.isEmpty());//false
// 5.public V get(Object key):根据键获取对应值
int v1 = map.get("手表");
System.out.println(v1);//220
System.out.println(map.get("手机")); // 2
System.out.println(map.get("张三")); // null
// 6. public V remove(Object key):根据键删除整个元素(删除键会返回键的值)
System.out.println(map.remove("手表"));//220
System.out.println(map);//{null=null, Java=2, 手机=2}
// 7.public boolean containsKey(Object key): 判断是否包含某个键 ,包含返回true ,反之
System.out.println(map.containsKey("手表")); // false
System.out.println(map.containsKey("手机")); // true
System.out.println(map.containsKey("java")); // false
System.out.println(map.containsKey("Java")); // true
// 8.public boolean containsValue(Object value): 判断是否包含某个值。
System.out.println(map.containsValue(2)); // true
System.out.println(map.containsValue("2")); // false
// 9.public Set<K> keySet(): 获取Map集合的全部键。
Set<String> keys = map.keySet();
System.out.println(keys);//[null, Java, 手机]
// 10.public Collection<V> values(); 获取Map集合的全部值。
Collection<Integer> values = map.values();
System.out.println(values);//[null, 2, 2]
// 11.把其他Map集合的数据倒入到自己集合中来。(拓展)
Map<String, Integer> map1 = new HashMap<>();
map1.put("java1", 10);
map1.put("java2", 20);
Map<String, Integer> map2 = new HashMap<>();
map2.put("java3", 10);
map2.put("java2", 222);
map1.putAll(map2); // putAll:把map2集合中的元素全部倒入一份到map1集合中去。
System.out.println(map1);//{java3=10, java2=222, java1=10}
System.out.println(map2);//{java3=10, java2=222}
}
}
5.2Map集合的遍历方式
(1)Map集合的遍历方式一:键找值
先获取Map集合全部的键,再通过遍历键来找值
需要用到Map的如下方法:
package com.test.可删;
import java.util.*;
public class Test {
public static void main(String[] args) {
// 准备一个Map集合。
Map<String, Double> map = new HashMap<>();
map.put("蜘蛛精", 162.5);
map.put("蜘蛛精", 169.8);
map.put("紫霞", 165.8);
map.put("至尊宝", 169.5);
map.put("牛魔王", 183.6);
System.out.println(map);
// map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}
// 1、获取Map集合的全部键
Set<String> keys = map.keySet();
// System.out.println(keys);
// [蜘蛛精, 牛魔王, 至尊宝, 紫霞]
// key
// 2、遍历全部的键,根据键获取其对应的值
for (String key : keys) {
// 根据键获取对应的值
double value = map.get(key);
System.out.println(key + "=====>" + value);
}
}
}
(2)Map集合的遍历方式二:键值对
把“键值对“看成一个整体进行遍历(难度较大)
package com.test.可删;
import java.util.*;
public class Test {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("蜘蛛精", 169.8);
map.put("紫霞", 165.8);
map.put("至尊宝", 169.5);
map.put("牛魔王", 183.6);
System.out.println(map);
// map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}
// entries = [(蜘蛛精=169.8), (牛魔王=183.6), (至尊宝=169.5), (紫霞=165.8)]
// entry
// 1、调用Map集合提供entrySet方法,把Map集合转换成键值对类型的Set集合
Set<Map.Entry<String, Double>> entries = map.entrySet();
for (Map.Entry<String, Double> entry : entries) {
String key = entry.getKey();
double value = entry.getValue();
System.out.println(key + "---->" + value);
}
}
}
(3)Map集合的遍历方式三:Lambda
需要用到Map的如下方法
package com.test.可删;
import java.util.*;
public class Test {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("蜘蛛精", 169.8);
map.put("紫霞", 165.8);
map.put("至尊宝", 169.5);
map.put("牛魔王", 183.6);
System.out.println(map);
// map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}
// map.forEach(new BiConsumer<String, Double>() {
// @Override
// public void accept(String k, Double v) {
// System.out.println(k + "---->" + v);
// }
// });
map.forEach(( k, v) -> {
System.out.println(k + "---->" + v);
});
}
}
5.3HashMap集合的底层原理
HashMap(由键决定特点): 无序、不重复、无索引; (用的最多)
HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表实现的。
实际上:原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。
HashMap底层原理基于哈希表实现
- HashMap集合是一种增删改查数据,性能都较好的集合
- 但是它是无序,不能重复,没有索引支持的(由键决定特点)
- HashMap的键依赖hashCode方法和equals方法保证键的唯一
- 如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。
5.4LinkedHashMap集合的底层原理
LinkedHashMap (由键决定特点): 有序、不重复、无索引。
底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)
实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap。
5.5TreeMap集合的底层原理
TreeMap (由键决定特点):按照键的大小默认升序排序、不重复、无索引。
原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。
TreeMap集合同样也支持两种方式来指定排序规则
- 让类实现Comparable接口,重写比较规则。
- TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则。
6.集合的嵌套
集合的嵌套:集合中的元素又是一个集合
案例可参考链接:
java集合篇之练习题(List,Map等的应用练习)-CSDN博客