java之集合(详细-Map,Set,List)
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")); // trueSystem.out.println(c.contains("Java1")); // false// 5.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!System.out.println(c.remove("java1"));//trueSystem.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>() {@Overridepublic 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 2String 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>() {@Overridepublic 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);//220System.out.println(map.get("手机")); // 2System.out.println(map.get("张三")); // null// 6. public V remove(Object key):根据键删除整个元素(删除键会返回键的值)System.out.println(map.remove("手表"));//220System.out.println(map);//{null=null, Java=2, 手机=2}// 7.public boolean containsKey(Object key): 判断是否包含某个键 ,包含返回true ,反之System.out.println(map.containsKey("手表")); // falseSystem.out.println(map.containsKey("手机")); // trueSystem.out.println(map.containsKey("java")); // falseSystem.out.println(map.containsKey("Java")); // true// 8.public boolean containsValue(Object value): 判断是否包含某个值。System.out.println(map.containsValue(2)); // trueSystem.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博客
相关文章:
java之集合(详细-Map,Set,List)
1集合体系概述 1.1集合的概念 集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。 1.2集合分类 集合分为单列集合和多列集合 Collection代表单列集合,每个元素(数据ÿ…...
利用卷积神经网络进行手写数字的识别
数据集介绍 MNIST(Modified National Institute of Standards and Technology)数据集是一个广泛使用的手写数字识别数据集,常用于机器学习和计算机视觉领域中的分类任务。它包含了从0到9的手写数字样本,常用于训练和测试各种图像…...
Flutter 桌面端串口配置
前言 我使用flutter_libserialport包在macOS中实现串口通信的功能,可以实现数据收发,但是收到的内容是乱码。这种情况一般都是由于波特率和硬件设备不一致导致的。 配置串口配置 1.打开串口读写 import package:flutter_libserialport/flutter_libser…...
Java 的常量池与 String 优化
Java 中的常量池(Constant Pool)是一种内存优化机制,比如字符串常量池: String s1 "Hello"; String s2 "Hello"; System.out.println(s1 s2); // 输出 true,因为指向同一池中的对象但对于使用…...
防范TCP攻击:策略与实践
TCP(传输控制协议)是互联网通信的核心协议之一,它确保了数据在网络上的可靠传输。然而,TCP也容易成为各种网络攻击的目标,如SYN洪水攻击、TCP连接耗尽攻击等。本文将探讨如何通过配置防火墙规则、优化服务器设置以及采…...
单片机:实现呼吸灯(附带源码)
单片机实现呼吸灯详细解读 呼吸灯是一种常见的灯光效果,广泛应用于电子产品、汽车、家居照明等领域。其基本特性是通过逐渐增亮和减弱的方式,使得灯光呈现出“呼吸”的效果,给人一种平缓、舒适的视觉感受。在嵌入式系统中,呼吸灯…...
Android 第三方框架:RxJava:源码分析:责任链模式
文章目录 责任链模式RxJava中的责任链总结 责任链模式 RxJava中的责任链 链式调用的使用过程中形成了两个单向链表 第一个单向链表是Observable链表 它的形成过程: 1.首先调用Observable的静态方法创建第一个Observable对象,作为Observable链表的表…...
基于HTML的个人博客系统的设计与实现
一、前言 随着互联网的飞速发展,人们分享生活、表达观点和展示自我的需求日益增长。个人博客作为一种重要的网络交流平台,为用户提供了便捷的信息发布和分享渠道。它不仅可以记录个人的成长经历、专业知识、兴趣爱好等,还能促进用户之间的互动…...
DMA(Direct Memory Access):直接内存访问
DMA(Direct Memory Access):直接内存访问 一、传统CPU存取数据 CPU不直接存取外设的原因主要有两点: 速度差异:CPU的处理速度远高于外设,无法直接同步。格式多样性:外设数据格式种类繁多&…...
数据分析python小工具录入产品信息到Excel
在没有后台管理系统的时候,有时候为了方便起见,想提供一个输入框让运营人员直接输入,然后数据就会以数据库的形式存进数据库 效果图: 输入用户名 输入数据 输入信息后点击添加到表格,检查后方便批量保存到excel …...
Mac安装brew的终极方法
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"按回车后,根据提示操作: 输入镜像序号(1-5都可以)输入Y,回车等待brew安装完成即可。 M系列芯片亲测有效&#x…...
卷积神经网络比于全连接神经网络强在哪?
卷积神经网络(Convolutional Neural Networks,简称CNN)与全连接神经网络(Fully Connected Neural Networks,简称FFNN)是深度学习和神经网络领域中两种最为常见的网络结构。两者在结构、工作原理及应用场景上…...
Stable Diffusion Controlnet常用控制类型解析与实战课程 4
本节内容,是stable diffusion Controlnet常用控制类型解析与实战的第四节课程。上节课程,我们陆续讲解了几个与图像风格约束相关的控制类型,本节课程我们再学习一些实用价值较高的控制类型,看一看他们提供了哪些控制思路。 一&…...
[ShaderLab] 【Unity】【图像编程】理解 Unity Shader 的结构
在计算机图形学领域,开发者经常面临着管理着色器复杂性的挑战。正如大卫惠勒(David Wheeler)所说:“计算机科学中的任何问题都可以通过增加一层抽象来解决。” Unity 提供了这样一层抽象,即 ShaderLab,它通过组织和定义渲染过程的各个步骤,简化了编写着色器的过程。 什…...
Source Insight的使用经验汇总
01-Add All"和“Add Tree”有何区别? 在 Source Insight 中,“Add All”和“Add Tree”是两种向项目(Project)中添加文件的操作选项,它们的区别在于处理文件和目录的方式不同: 1. Add All 范围&am…...
CentOS 7.9 更换 YUM:解决宝塔安装困境的探索之旅
在进行网站搭建工作时,我满怀期待地准备安装宝塔面板,然而却遭遇了安装失败的挫折。经过一番排查与思考,我将目光聚焦到了系统的 YUM 上,怀疑它可能是导致问题的“罪魁祸首”。于是,我毅然决定对 CentOS 7.9 的 YUM 进…...
28. Three.js案例-创建圆角矩形并进行拉伸
28. Three.js案例-创建圆角矩形并进行拉伸 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染 3D 场景的主要渲染器。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数,可选。 …...
最佳实践:编写和配置 Stylelint 自定义插件,Stylelint 自定义规则
前言 在前端开发中,代码质量和一致性是至关重要的。Stylelint 作为一个强大的 CSS 代码检查工具,能够帮助开发者发现代码中的问题,并保持代码风格的一致性。然而,内置的规则和插件有时无法完全满足特定项目的需求。在这种情况下&…...
vscode借助插件调试OpenFoam的正确的.vscode配置文件
正确的备份文件位置: /home/jie/桌面/理解openfoam/正确的调试爆轰单进程案例/mydebugblastFoam 调试爆轰案例流体 并且工作区和用户区都是openfoam-7版本 问题:F5以debug模式启动后不停在断点 解决方法: 这里备份一下.vsode正确的配置&…...
Towards Frame Rate Agnostic Multi-object Tracking—迈向帧率无关的多目标跟踪
Towards Frame Rate Agnostic Multi-object Tracking—迈向帧率无关的多目标跟踪 发表在IJCV 2023年 作者:Weitao Feng, Lei Bai, Yongqiang Yao, Fengwei Yu & Wanli Ouyang 研究目标:多目标跟踪的帧率无关性研究 IJCV 在计算机视觉领域的影响力非常…...
视频网站中重磅推荐模块(附加源码)
写在开头 上期代码主要实现省市区三级联动效果,开发久了很多功能都是通过框架组件库来完成,但是如果组件满足不了开发需求,还需要开发人员手动封装组件,专门出这样一期文章,通过原生js实现一些特定功能,功能…...
Flink keyBy算子的分区规则
demo代码 String worlds "flink,spark,hadoop,zk,kafka";streamSource.flatMap(new RichFlatMapFunction<String, String>() {Overridepublic void flatMap(String value, Collector<String> collector) throws Exception {String[] worlds value.spl…...
jvm内存优化方式
1. JVM(Java Virtual Machine): • 定义:Java虚拟机,是运行Java字节码的抽象计算机。 • 内存管理:负责内存的分配和回收,是JVM内存优化的核心。 2. 堆(Heap):…...
顺序表的实现
大家好,今天给大家分享一下最基础的数据结构--顺序表的实现,其实顺序表与我们的数组相似,但是顺序表存储数据必须是连续的,不能像数组一样存储在任意下标,那么我们就来看看顺序表的代码。 SeqList.h SeqList.c 那么今…...
优化Go语言中的网络连接:设置代理超时参数
网络连接优化的重要性 在分布式系统和微服务架构中,网络请求的效率直接影响到整个系统的响应速度。合理的超时设置可以防止系统在等待网络响应时陷入无限期的阻塞,从而提高系统的吞吐量和用户体验。特别是在使用代理服务器时,由于增加了网络…...
活动|华院计算董事长宣晓华出席第十五届田长霖论坛会议
12月11日,2024年光谷田长霖中心科技文化交流大会暨第十五届田长霖论坛会议举行,300多位院士专家、大学校长、青年学者和优秀企业家齐聚光谷。 华院计算技术(上海)股份有限公司(以下简称“华院计算”)创始人…...
qt-C++语法笔记之mapToGlobal将组件(控件)中的本地坐标系(局部坐标)映射到全局坐标系
qt-C语法笔记之mapToGlobal将组件(控件)中的本地坐标系(局部坐标)映射到全局坐标系 code review! 文章目录 qt-C语法笔记之mapToGlobal将组件(控件)中的本地坐标系(局部坐标)映射到…...
设计一个高效的Java多线程应用程序及案例
《剑来》 勇敢追梦:“如果真的有那么喜欢苏姑娘,既然这辈子到最后也没能说出口喜欢她,没关系,以后数十年百余年,哪怕找遍人间,你都要去再见她一次,大声告诉她,自己喜欢她。” 正视困…...
基于最新的Apache StreamPark搭建指南
一、StreamPark 的介绍 官方文档:Apache StreamPark (incubating) | Apache StreamPark (incubating) 中文文档:Apache StreamPark (incubating) | Apache StreamPark (incubating)Github地址:https://github.com/apache/incubator-streampark Apache StreamPark™ 是一个…...
迎接全新的 Kotlin 支持 – K2 模式:基本信息
K2 模式有什么作用? K2 模式是 IntelliJ IDEA 中 Kotlin 支持的新实现,它可以提高 IDE 的稳定性,同时也会为支持未来 Kotlin 语言功能奠定基础。 K2 模式与 Kotlin K2 编译器有什么区别? K2 编译器负责编译 Kotlin 语言 2.0 或…...
阿里云元宇宙
在数字经济时代,技术的迅猛发展带来了前所未有的机遇与挑战,元宇宙正逐步成为全球科技与商业创新的热点。作为中国云计算和人工智能领域的领导者,阿里云通过其强大的技术能力,推出了全面的阿里云元宇宙解决方案,为全球…...
题目 1688: 数据结构-字符串插入
第一种方式字符串 #include<iostream> #include<cstring> #include<algorithm> using namespace std; int main(){string s1,s2;int n;cin>>s1>>s2>>n;s1.insert(n-1,s2);cout<<s1<<endl;return 0; } 第二种方式字符数组 …...
MetaGPT中的教程助手:TutorialAssistant
1. 提示词 COMMON_PROMPT """ You are now a seasoned technical professional in the field of the internet. We need you to write a technical tutorial with the topic "{topic}". """DIRECTORY_PROMPT (COMMON_PROMPT "…...
如何将Python程序打包发布,实现一键安装
哈喽,大家好,我是木头左! 编写完Python脚本后,如何将其高效地发布并安装到其他计算机上,。本文将详细介绍如何将Python程序打包发布,实现一键安装,让程序的分发与部署变得轻松便捷。 一、准备工作 1. 编写和测试程序 在开始打包之前,首先要确保你的Python程序已经编…...
Java 接口
1. 接口概述 (1) Java提供了一个关键字 interface,用这个关键字可以定义接口; (2)格式: public interface 接口名{ //成员变量(常量) //成员方法(抽象方法) } public interface A {//成员变量(接口默认为常量-public static final)String NA…...
RTMP推流平台EasyDSS在无人机推流直播安防监控中的创新应用
无人机与低空经济的关系密切,并且正在快速发展。2024年中国低空经济行业市场规模达到5800亿元,其中低空制造产业占整个低空经济产业的88%。预计未来五年复合增速将达到16.03%。 随着科技的飞速发展,公共安防关乎每一个市民的生命财产安全。在…...
【Flutter_Web】Flutter编译Web第一篇(插件篇):Flutter_web实现上传TOS上传资源,编写web插件
前言 由于Flutter在双端的开发体验几乎接近的情况下,尝试将Flutter代码转Web端进行部署和发布,在其中遇到的所有问题,我都会通过这种方式分享出来。那么第一个要解决的就是上传资源到TOS上,在双端中都是通过插件的方式在各端通过…...
SpringBoot 项目使用 EasyExcel 插件构建 Excel 表格格式(行高、列宽和字体等)工具类
本文主要讲了如何使用 EasyExcel 插件,在导出 Excel 时,设置行高,列宽,表头格式,内容字体大小等工具类。 1、代码使用的依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyex…...
数据优化带来的问题
原因大概可以猜到 等待进一步深究(必须一个是浮点型) double x 1 / 2;double x2 static_cast<double> (1 / 2);double x3 (double)1 / (double)2;double x4 (double)1 / 2;double x5 1 / (double)2;double nTotalDataCount 78182;double n…...
2024153读书笔记|《春烂漫:新平摄影作品选》——跳绳酷似人生路,起落平常,进退平常,莫惧征途万里长
2024153读书笔记|《春烂漫:新平摄影作品选》——跳绳酷似人生路,起落平常,进退平常,莫惧征途万里长 《春烂漫:新平摄影作品选》作者新平,2019.12.25年读完的小书,当时就觉得挺不错,今…...
RabbitMQ个人理解与基本使用
目录 一. 作用: 二. RabbitMQ的5中队列模式: 1. 简单模式 2. Work模式 3. 发布/订阅模式 4. 路由模式 5. 主题模式 三. 消息持久化: 消息过期时间 ACK应答 四. 同步接收和异步接收: 应用场景 五. 基本使用 ÿ…...
每天40分玩转Django:Django视图和URL
Django视图和URL 一、课程概述 学习项目具体内容预计用时视图基础函数视图、类视图、视图装饰器90分钟URL配置URL模式、路由系统、命名URL60分钟请求处理请求对象、响应对象、中间件90分钟 二、视图基础 2.1 函数视图 # blog/views.py from django.shortcuts import render…...
ModbusTcp获取数据
ModbusTcp获取数据 记录一个用 pymodbus 库来获取数据的代码。 注意: 1.读取寄存器地址是16进制的。2.大小端转换通过代码知道原理。读取数据时,切记频率别太高,否则会出现连接被关闭问题。 from pymodbus.client.sync import ModbusTcpCli…...
汽车车牌识别数据集,支持YOLO,COCO,VOC格式的标注,8493张图片,可识别多种环境下的车牌
汽车车牌识别数据集,支持YOLO,COCO,VOC格式的标注,8493张图片,可识别多种环境下的车牌 数据集分割 训练组82% 6994图片 有效集12% 999图片 测试集6% 500图片 预处理 自动…...
YOLOv5+pyqt5+摄像头在特定条件下进行目标检测并采集原始数据
项目介绍 项目地址 GitHub - biabu0/Yolov5_D435i: 通过YOLOV5与pyqt5实现一个使用D435i深度摄像头采集特定需求与场景下的深度数据的小程序 通过YOLOV5对指定的区域进行检测,当检测到目标进入特定区域时,开始保存数据,摄像头采用D435i深度…...
代码随想录-算法训练营-番外(图论02:岛屿数量,岛屿的最大面积)
day02 图论part02 今日任务:岛屿数量,岛屿的最大面积 都是一个模子套出来的 https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html#思路往日任务: day01 图论part01 今日任务:图论理论基础/所有可到达的路径 代码随想录图论视频部分还没更新 https://programmercar…...
C# 23种设计模式(3)工厂(SimpleFactory)模式
一、工厂模式介绍 工厂模式(Factory Pattern)是一种在软件开发中常用的创建型设计模式。它的主要目的是将对象的创建逻辑与使用逻辑分离,使得增加新的对象类型时不需要修改使用对象的代码。这样做提高了系统的可扩展性和可维护性。 工厂模式…...
安卓主板_MTK联发科android主板方案
在当前智能设备的发展中,安卓主板的配置灵活性和性能优化显得尤为重要。安卓主板的联发科方案,在芯片上,搭载联发科MTK6761、MT8766、MT6765、MT6762、MT8768、MT8390、MTK8370以及MT8788等型号,均基于64位的四核或八核架构设计。…...
中企出海 - 平行账 - Parallel Ledger
以中国企业出海美国,为同时满足中国和美国的会计核算要求,请给出SAP 平行账的实施方案及国家科目表(alternative account)实施海外国家的注意事项 中国企业在美国开展业务需同时满足中国和美国的会计准则,这通常包括《中国企业会计准则》&am…...
Pyside6 --Qt设计师--简单了解各个控件的作用之:Item Views
目录 一、List View二、Tree View三、Table View四、Column View 一、List View 学习方法和Buttons一样,大家自己在qt设计师上面在属性编辑区进行相应的学习! 我就先紧着qt设计师的页面进行讲解,部分内容查自AI。 后面有什么好用的控件或者…...