集合:Collection,List,Set,Map
集合体系
集合结构
单列集合
1.Collection
1.初识Collection
package cn.hdc.oop8.Collection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**
* 目标:认识collection集合体系
*/
public class Test1 {
public static void main(String[] args) {
//简单确认一下collection集合的特点
ArrayList<String> list = new ArrayList<>();
list.add("java1");
list.add("java2");
list.add("java1");
list.add("java2");
System.out.println(list);
//[java1, java2, java1, java2]//有序,可重复,有索引
HashSet<String> set = new HashSet<>();
set.add("java1");
set.add("java2");
set.add("java1");
set.add("java2");
set.add("java3");
System.out.println(set);
//[java3, java2, java1]//无序,不可重复,无索引
}
}
2.常用API
package cn.hdc.oop8.Collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class api {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();//实现类对象给到顶级的父类接口,这是一种多态现象
//1.public boolean add (E e):添加元素,添加成功返回true。
System.out.println(list.add("jsz"));
//2.public void clear(): 清空集合的元素
list.clear();
System.out.println(list);
//3.public boolean isEmpty():判断集合是否为空 是空返回true,反之。
System.out.println(list.isEmpty());
//4.public int size():获取集合的大小。
System.out.println(list.size());
//5.public boolean contains(object obj): 判断集合中是否包含某个元素。
System.out.println(list.contains("jsz"));
//6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
System.out.println(list.remove("jsz"));
//7.public 0bject[] toArray():把集合转换成数组
System.out.println(Arrays.toString(list.toArray()));
Object[] objects = list.toArray();//默认是Object类型的数组
//转成指定类型的数组
String[] strArr = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(strArr));
System.out.println("-----------------------------------------------------");
//把一个集合中的数据倒入到另一个集合中去
Collection<String> lis = new ArrayList<>();
lis.add("java1");
lis.add("java2");
Collection<String> lis1 = new ArrayList<>();
lis1.add("java3");
lis1.addAll(lis);//addAll:把lis集合的全部数据倒入到lis1集合中,lis1和lis集合的数据类型需一致
System.out.println(lis1);
}
}
3.遍历方式
1.迭代器
package cn.hdc.oop8.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class iterator {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("庆桑");
list.add("乐桑");
list.add("卓桑");
list.add("毅桑");
System.out.println(list);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {//hasNext判断当前位置有没有数据,位置的变化是由next进行的,hasNext与下一个位置有没有数据无关,不要被名称表面所迷惑
System.out.println(iterator.next());//hasNext判断一次,取一次
/**
* 错误写法:
* while (iterator.hasNext()) {
* System.out.println(iterator.next());
* System.out.println(iterator.next());
* }
* 这样的话当集合里面数据为奇数个时第二个next会报空
*/
}
}
}
2.增强for循环
package cn.hdc.oop8.Collection;
import java.util.ArrayList;
import java.util.Collection;
public class forPlus {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("庆桑");
list.add("乐桑");
list.add("卓桑");
list.add("毅桑");
System.out.println(list);
for (String str : list) {
System.out.println(str);
}
}
}
增强for除了可以用来遍历集合,还可以用来遍历数组
3.Lambda
package cn.hdc.oop8.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Lambda {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("庆桑");
list.add("乐桑");
list.add("卓桑");
list.add("毅桑");
System.out.println(list);
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("-----------------------------------------");
list.forEach((String s) -> {
System.out.println(s);
}
);
System.out.println("-----------------------------------------");
list.forEach(item -> System.out.println(item));
System.out.println("-----------------------------------------");
list.forEach(System.out::println);
}
}
为什么没有支持for循环?
因为for循环必须是支持索引的,Collection集合并不是所有集合都支持索引
4.案例
package cn.hdc.oop8.Collection.demo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
public class Test1 {
public static void main(String[] args) {
Collection<Movies> list = new ArrayList<>();
list.add(new Movies("《肖申克的救赎》", 9.7, "罗宾斯"));
list.add(new Movies("《霸王别姬》", 9.6, "张国荣、张丰毅"));
list.add(new Movies("《阿甘正传》", 9.5, "汤姆.汉克斯"));
for (Movies movies : list) {
System.out.println(movies);
}
Iterator<Movies> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
list.forEach(System.out::println);
}
}
package cn.hdc.oop8.Collection.demo;
public class Movies {
private String name;
private double score;
private String actor;
@Override
public String toString() {
return "Movies{" +
"name='" + name + '\'' +
", score=" + score +
", actor='" + actor + '\'' +
'}';
}
public Movies() {
}
public Movies(String name, double score, String actor) {
this.name = name;
this.score = score;
this.actor = actor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
}
2.List
1.特点、特有方法
package cn.hdc.oop8.List;
import java.util.ArrayList;
import java.util.List;
public class special {
public static void main(String[] args) {
//1.创建一个ArrayList集合对象(有序、可重复、有索引)
List<String> list = new ArrayList<>();//多态
list.add("666");
list.add("777");
list.add("888");
list.add("999");
System.out.println(list);
System.out.println("--------------------------------------");
//2.public void add(int index,E element):在某个索引位置插入元素。
list.add(0, "java");
list.add(4, "java");
list.add(6, "java");
System.out.println(list);
System.out.println("--------------------------------------");
//3.public E remove(int index): 根据索引删除元素,返回被删除元素
System.out.println("删除的元素是:" + list.remove(0));
System.out.println(list);
System.out.println("--------------------------------------");
//4.public E get(int index): 返回集合中指定位置的元素。
System.out.println("集合首位元素是:" + list.get(0));
System.out.println("--------------------------------------");
//5.public E set(int index,E element): 修改索引位置处的元素,修改成功后,会返回原来的数据
list.set(5, "这是末尾元素");
System.out.println(list);
System.out.println("--------------------------------------");
}
}
2.遍历方式
3.ArrayList集合的底层原理
4.LinkedList集合的底层原理
1.什么是链表
2.链表的特点
3.单链表和双链表
4.LinkedList集合的底层原理
5.应用场景
1.用于设计队列
package cn.hdc.oop8.List;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
// 创建一个队列
LinkedList<String> list = new LinkedList<>();
//入队
list.addLast("sq");
list.addLast("sq1");
list.addLast("sq2");
list.addLast("sq3");
list.addLast("sq4");
list.addLast("sq5");
list.addLast("sq6");
list.addLast("sq7");
System.out.println(list);
//出队
list.removeFirst();
list.removeFirst();
list.removeFirst();
System.out.println(list);
}
}
2.用于设计栈
// 创建一个栈
LinkedList<String> list1 = new LinkedList<>();
//压栈push
list1.addFirst("wsn");
list1.addFirst("wzn");
list1.addFirst("wyr");
System.out.println(list1);
//弹栈pop
list1.removeFirst();
list1.removeFirst();
System.out.println(list1);
System.out.println("--------------------------------");
list1.push("wsn");
list1.push("wzn");
list1.push("wyr");
System.out.println(list1);
list1.pop();
list1.pop();
list1.pop();
System.out.println(list1);
System.out.println("--------------------------------");
3.Set
1.Set集合特点
package cn.hdc.oop8.Set;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
Set<Integer> s1 = new TreeSet<>();//可排序不重复无索引
s1.add(34);
s1.add(36);
s1.add(37);
s1.add(37);
s1.add(31);
s1.add(33);
s1.add(33);
s1.add(34);
System.out.println(s1);
System.out.println("-------------------------------------------");
Set<Integer> s = new LinkedHashSet<>();//有序不重复无索引
s.add(4);
s.add(6);
s.add(7);
s.add(7);
s.add(1);
s.add(3);
s.add(3);
s.add(4);
System.out.println(s);
System.out.println("-------------------------------------------");
Set<Integer> set = new HashSet<>();//创建了一个HashSet的集合对象,一行经典代码,HashSet:无序不重复无索引
set.add(666);
set.add(555);
set.add(555);
set.add(777);
set.add(777);
set.add(888);
System.out.println(set);
}
}
Set无特殊新增常用方法
2.HashSet集合的底层原理
1.为什么添加的元素无序、不重复、无索引?
2.增删改查数据有什么特点,适合什么场景?
1.哈希值
2.底层原理
JDK8_Before
当集合数组长度有 默认数组长度 * 默认加载因子 即16*0.75=12时,也就是当HashSet存储了12个位置的元素时,集合会扩容成其的两倍。
如果数组快占满了,会出现什么问题?该怎么办?
会出现:链表会过长,导致查询性能降低 的问题
应该: 扩容
JKD8_After
二叉查找树
平衡二叉树
红黑树
3.HashSet集合去重
深入理解HashSet集合去重复的机制
package cn.hdc.oop8.Set.DuplicateRemove;
import cn.hdc.oop8.Set.Student;
import java.util.HashSet;
public class Test1 {
public static void main(String[] args) {
HashSet<Student> set = new HashSet<>();
Student s1 = new Student("蜘蛛精", 25, 169.5);
Student s2 = new Student("蜘蛛精1", 25, 169.5);
Student s3 = new Student("蜘蛛精", 25, 169.5);
Student s4 = new Student("蜘蛛精2", 25, 169.5);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
System.out.println(set);
}
}
重写HashSet的equals和hashCode方法
//只要两个对象内容一样,就返回true
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
}
//只要两个对象内容一样,返回的哈希值就是一样的。
@Override
public int hashCode() {
//姓名,年龄,身高
return Objects.hash(name, age, height);
}
重写一路回车,无需更改。
运行结果
重写前
重写后
3.LinkedHashSet
4.TreeSet
1.定义
2.自定义排序规则
方式一
实现Comparable接口
package cn.hdc.oop8.Set;
import java.util.Objects;
//public class Student {
public class Student implements Comparable<Student> {
private String name;
private int age;
private double height;
//TreeSet自定义排序规则
//只要两个对象内容一样,就返回true
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
}
//只要两个对象内容一样,返回的哈希值就是一样的。
@Override
public int hashCode() {
//姓名,年龄,身高
return Objects.hash(name, age, height);
}
......getter setter toString 有参 无参等.......
//年龄降序
// @Override
// public int compareTo(Student o) {
// return o.getAge() - this.getAge();
// }
//身高升序
@Override
public int compareTo(Student o) {
// return this.getHeight() - o.getHeight() > 0 ? 1 : -1;
return Double.compare(o.getHeight(), this.getHeight());
}
}
compareTo需要的返回值是int
double数据类型的数据可以通过两种方式进行比较:1.三元运算符
2.Double的compare方法
package cn.hdc.oop8.Set;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest2 {
public static void main(String[] args) {
//就近选择自己自带的比较器对对象进行排序
// Set<Student> set = new TreeSet<>(Comparator.comparingInt(Student::getAge));
Set<Student> set = new TreeSet<>();
set.add(new Student("蜘蛛精", 250, 169.5));
set.add(new Student("蜘蛛精1", 259, 169.6));
set.add(new Student("蜘蛛精2", 257, 169.7));
set.add(new Student("蜘蛛精3", 257, 169.8));
System.out.println(set);
}
}
方式二
package cn.hdc.oop8.Set;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest2 {
public static void main(String[] args) {
//就近选择自己自带的比较器对对象进行排序
Set<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
// Set<Student> set = new TreeSet<>();
set.add(new Student("蜘蛛精", 250, 169.5));
set.add(new Student("蜘蛛精1", 259, 169.6));
set.add(new Student("蜘蛛精2", 257, 169.7));
set.add(new Student("蜘蛛精3", 257, 169.8));
System.out.println(set);
}
}
Comparable接口和TreeSet集合自带比较器Comparator同时存在时,就近使用集合自带的比较器对对象进行比较排序。
5.小结
1.Collection单列集合小结
2.补充
1.集合的并发修改异常问题
package cn.hdc.oop8.zongjie;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CollectionHighTogetherException {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("许李国");
list.add("李慕婉");
list.add("藤化元");
list.add("唐舞桐");
list.add("圣采儿");
System.out.println(list);
//[王麻子, 李慕婉, 藤化元, 许立国, 唐舞桐, 圣采儿]
//需求:需要找出集合中全部带“李”的名字并从集合中删除
// Iterator<String> it = list.iterator();
// while (it.hasNext()) {
// if (it.next().contains("李")) {
// list.remove(it.next());//控制台报错
// }
// }
System.out.println("-----------------------------------------");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().contains("李")) {
it.remove();//迭代器自带删除方法
}
}
System.out.println("-----------------------------------------");
//使用for循环遍历集合并删除集合中带“李”的名字
// for (int i = 0; i < list.size(); i++) {
// if (list.get(i).contains("李")) {
// list.remove(i);//删除可能不完全
// }
// }
System.out.println("-----------------------------------------");
// for (int i = list.size() - 1; i >= 0; i--) {
// if (list.get(i).contains("李")) {
// list.remove(i);//可以删除
// }
// }
System.out.println("-----------------------------------------");
//增强for循环和Lambda表达式是无法解决这个问题的,他们都是迭代器的一种简化写法,但又无法调用迭代器的删除方法
// for (String s : list) {
// if (s.contains("李")) {
// list.remove(s);
// }
// }
System.out.println(list);
}
}
2.可变参数
定义
可变参数注意事项
1.一个形参列表中,只能有一个可变参数
错误案例:public static void t(int... id,int...num) {}
2.可变参数必须放在形参列表的最后面
错误案例:public static void t(int... id,int age) {}
3.可变参数在方法内部就是一个数组,并且是一个有序数组
3.Collections工具类
1.定义及常用方法
package cn.hdc.oop8.collections;
import java.util.*;
public class collections {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list);
//1、public static <T> boolean addAll(collection<? super T>c,T...elements):为集合批量添加数据
Collections.addAll(list, 6, 7, 8, 9, 0);
System.out.println(list);
//2、public static void shuffle(List<?> list):打乱List集合中的元素顺序。
Collections.shuffle(list);
System.out.println(list);
//3、 public static <T> void sort(List<T> list):对List集合中的元素进行升序排序。
Collections.sort(list);
System.out.println(list);
//4、public static <T> void sort(List<T> list,Comparator<? super T> c):对List集合中元素,按照比较器对象指定的规则进行排序。
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(list);
}
}
自定义对象排序规则
List<Student> set = new ArrayList<>();
set.add(new Student("蜘蛛精", 250, 169.5));
set.add(new Student("蜘蛛精1", 259, 169.6));
set.add(new Student("蜘蛛精2", 257, 169.7));
set.add(new Student("蜘蛛精3", 257, 169.8));
// System.out.println(set);
Collections.sort(set, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(set);
4.Collection案例:斗地主
1.分析业务需求
2.分析实现
双列集合
1.Map
1.认识Map集合
2.应用场景
3.Map集合体系
特点
package cn.hdc.oop8.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class knowMap {
public static void main(String[] args) {
Map<String, Integer> map = new LinkedHashMap<>();//多态、经典代码,按照键无序、不重复、无索引
// Map<String, Integer> map = new HashMap<>();//多态、经典代码,按照键无序、不重复、无索引
map.put("dsb", 100);
map.put("dsb", 220);//后添加的数据会覆盖之前添加的数据
map.put("sj", 2);
map.put("java", 2);
map.put(null, null);
System.out.println(map);
Map<Integer, String> map1 = new TreeMap<>();
map1.put(23, "java");
map1.put(23, "MySQL");//后覆前
map1.put(19, "Vue");
map1.put(20, "Ele");
System.out.println(map1);
}
}
4.Map集合常用方法
package cn.hdc.oop8.Map;
import java.util.HashMap;
import java.util.Map;
public class MapAPI {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(23, "Java");
map.put(24, "MySQL");//后覆前
map.put(19, "Vue");
map.put(20, "Ele");
map.put(27, "Ajax");
map.put(29, "React");
HashMap<Integer, String> mp = (HashMap<Integer, String>) ((HashMap<Integer, String>) map).clone();
//2.public int size():获取集合的大小
System.out.println(map.size());
System.out.println(mp.size());
System.out.println("3=========");
//3、public void clear():清空集合
map.clear();
System.out.println(map);
System.out.println(mp);
System.out.println("4=========");
// 4.public boolean isEmpty():判断集合是否为空,为空返回true,反之!
System.out.println(map.isEmpty());
System.out.println(mp.isEmpty());
System.out.println("5=========");
//5.public V get(object key):根据键获取对应值
System.out.println(mp.get(20));
System.out.println(mp.get(201));
System.out.println("6=========");
//6.public V remove(object key):根据键删除整个元素(删除键会返回键的值):
System.out.println(mp.remove(20));
System.out.println(mp.remove(201));
System.out.println("7=========");
//7.public boolean containsKey(0bject key):判断是否包含某个键 ,包含返回true,反之
System.out.println(mp.containsKey(29));
System.out.println(mp.containsKey(292));
System.out.println("8=========");
//8.public boolean containsValue(object value): 判断是否包含某个值。
System.out.println(mp.containsValue("Java"));
System.out.println(mp.containsValue("JavaSpring"));
System.out.println("9=========");
//9.public Set<K> keySet():获取Map集合的全部键。
System.out.println(map.keySet());
System.out.println(mp.keySet());
System.out.println("10=========");
//10.public Collection<V> values():获取Map集合的全部值。
System.out.println(map.values());
System.out.println(mp.values());
System.out.println("11=========");
//11.把其他Map集合的数据倒入自己的集合中
map.putAll(mp);
map.putAll(mp);
System.out.println(map);
System.out.println(map.values());
}
}
5.Map集合的遍历方式
Map遍历测试模版
package cn.hdc.oop8.Map.bianli;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class m1 {
public static void main(String[] args) {
// 创建一个 HashMap 并填充数据
Map<Integer, String> map = generateFixedMap();
// 打印 HashMap
System.out.println(map);
}
public static Map<Integer, String> generateFixedMap() {
Map<Integer, String> map = new HashMap<>();
// 填充固定的数据
map.put(1, "Java");
map.put(2, "Python");
map.put(3, "C++");
map.put(4, "JavaScript");
map.put(5, "Go");
map.put(6, "Ruby");
map.put(7, "Swift");
map.put(8, "Kotlin");
map.put(9, "Rust");
map.put(10, "PHP");
map.put(11, "Scala");
map.put(12, "TypeScript");
map.put(13, "Dart");
map.put(14, "Perl");
map.put(15, "Lua");
map.put(16, "Haskell");
map.put(17, "Groovy");
map.put(18, "Julia");
map.put(19, "Elixir");
map.put(20, "R");
return map;
}
}
1.方式一:键找值
Set<Integer> set = map.keySet();
for (Integer integer : set) {
System.out.println(integer + ":" + map.get(integer));
}
2.方式二:键值对
Set<Map.Entry<Integer, String>> set = map.entrySet();
for (Map.Entry<Integer, String> entry : set) {
System.out.println(entry);
System.out.println(entry.getKey() + ":" + entry.getValue());
}
3.方式三:Lambda
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer integer, String s) {
System.out.println(integer + ":" + s);
}
});
map.forEach((Integer integer, String s) -> {
System.out.println(integer + ":" + s);
});
map.forEach((integer, s) -> System.out.println(integer + ":" + s));
6.Map集合案例:统计投票人数
案例代码
package cn.hdc.oop8.Map.demo;
import java.util.*;
public class d1 {
public static void main(String[] args) {
List<String> list = createList();
long t1 = System.currentTimeMillis();
Map<String, Integer> map = statistics(list);
System.out.println(map);
long t2 = System.currentTimeMillis();
System.out.println("time1:" + (t2 - t1));
long t3 = System.currentTimeMillis();
int a = 0, b = 0, c = 0, d = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("A")) {
a++;
} else if (list.get(i).equals("B")) {
b++;
} else if (list.get(i).equals("C")) {
c++;
} else {
d++;
}
}
System.out.println("A:" + a + "\tB:" + b + "\tC:" + c + "\tD:" + d);
long t4 = System.currentTimeMillis();
System.out.println("time2:" + (t4 - t3));
}
private static Map<String, Integer> statistics(List<String> list) {
Map<String, Integer> map = new HashMap<>();
for (String s : list) {
if (map.containsKey(s)) {
map.put(s, map.get(s) + 1);
} else {
map.put(s, 1);
}
}
// for (int i = 0; i < list.size(); i++) {
// if (map.containsKey(list.get(i))) {
// Integer v = map.get(list.get(i));
// map.put(list.get(i), ++v);
// } else {
// map.put(list.get(i), 1);
// }
// }
return map;
}
private static List<String> createList() {
String[] strArr = {"A", "B", "C", "D"};
List<String> list = new ArrayList<>();
Random r = new Random();
for (int i = 0; i < 80; i++) {
list.add(strArr[r.nextInt(4)]);
}
return list;
}
}
运行结果
通过比较可得,map相较for循环来说,更快。
2.HashMap
1.底层原理
2.底层是基于哈希表实现的
3.案例代码
package cn.hdc.oop8.Map.HashMap;
import java.util.HashMap;
import java.util.Map;
public class t1 {
public static void main(String[] args) {
Map<Student, String> map = new HashMap<>();
map.put(new Student("wzn", 158.4, 20), "泗上");
map.put(new Student("wzn", 158.4, 20), "辛集");
map.put(new Student("wsn", 162.7, 21), "晋州");
map.put(new Student("wyr", 165.2, 22), "邯郸");
map.put(new Student("jsz", 178.7, 22), "北京");
System.out.println(map);
}
}
重写hashCode和equals方法
package cn.hdc.oop8.Map.HashMap;
import java.util.Objects;
public class Student {
private String name;
private double height;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Double.compare(student.height, height) == 0 && age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, height, age);
}
......有参、无参、getter、setter、toString
}
3.LinkedHashMap集合原理
1.原理
2.使用
4.TreeMap集合的原理、使用
1.原理
2.使用
package cn.hdc.oop8.Map.TreeMap;
import cn.hdc.oop8.Map.HashMap.Student;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
public class t2 {
public static void main(String[] args) {
// 使用情况一的Comparator
Comparator<Student> comparator1 = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() > o2.getAge() ? 1 : -1;
}
};
Map<Student, String> map1 = new TreeMap<>(comparator1);
map1.put(new Student("wyr", 165.2, 22), "邯郸");
map1.put(new Student("jsz", 178.7, 22), "北京");
System.out.println("Map with Comparator 1:\n " + map1);
// 使用情况二的Comparator
Comparator<Student> comparator2 = (o1, o2) -> {
int ageCompare = Integer.compare(o1.getAge(), o2.getAge());
int heightCompare = Double.compare(o1.getHeight(), o2.getHeight());
if (ageCompare != 0) {
return ageCompare;
} else if (heightCompare != 0) {
return heightCompare;
} else {
return o1.getName().compareTo(o2.getName());
}
};
Map<Student, String> map2 = new TreeMap<>(comparator2);
map2.put(new Student("wyr", 165.2, 22), "邯郸");
map2.put(new Student("jsz", 178.7, 22), "北京");
System.out.println("Map with Comparator 2: \n" + map2);
}
}
2.1运行结果
3.可能会遇到的问题参考:
自定义对象排序方法之谁前谁后问题-CSDN博客https://blog.csdn.net/XiaomeiGuiSnJs/article/details/141780415?spm=1001.2014.3001.5501
5.补充知识:集合的嵌套
1.什么是集合的嵌套
即一个集合内的元素是另一个集合
2.案例:省和市
3.案例代码
package cn.hdc.oop8.Map.qiantao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class t1 {
public static void main(String[] args) {
Map<String, ArrayList<String>> map = new HashMap<>();
ArrayList<String> l1 = new ArrayList<>();
Collections.addAll(l1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");
ArrayList<String> l2 = new ArrayList<>();
Collections.addAll(l2, "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市");
ArrayList<String> l3 = new ArrayList<>();
Collections.addAll(l3, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");
map.put("江苏省", l1);
map.put("湖北省", l2);
map.put("河北省", l3);
System.out.println(map);
System.out.println(map.get("河北省"));
for (String s : map.get("江苏省")) {
System.out.println(s);
}
map.forEach((p, c) -> System.out.println(p + ":" + c));
}
}