背景:数组只能存储同一类型的数据和对象,且存储长度不能改变,过于局限,Java提供了集合类,集合可以存储不同类型的对象,且长度可以改变。
集合可以存引用数据类型,但不可以存基本数据类型(得用包装类)
ArrayList
ArrayList集合是用的最多的一个集合,它是基于动态数组实现的List类。
如何创造ArrayList集合的对象?
ArrayList<string> list=new ArrayList<>();
其中<string>表示泛型,用于限定集合中存储数据的类型。
ArrayList成员方法:
boolean add(E e):添加元素,返回值表示是否添加成功
boolean remove(E e):删除指定元素,返回值表示是否删除成功
E remove(int index):根据索引删除集合中的元素,返回值表示被删除的元素
E set(int index,E e):修改指定索引位置,返回被覆盖的元素
E get(int index);根据索引,获取集合中的元素
int size( ):获取集合中的元素个数
boolean add(E e)无论添加是否成功都会返回true,所以可以不用接收他的返回值。
有关ArrayList的练习 http://t.csdn.cn/8czmo
collection
集合体系结构可分为collection(单列集合)和map(双列集合)
单列:一个元素含一个值,双列:一个元素含两个值
collection又分list接口和set接口。
list又有ArrayList和LinkList和Vector这些实现类
set又有HashSet和TreeSet和LinkedHashSet这些实现类
List系列集合:添加元素是有序的、可重复的、有索引
Set系列集合:添加元素是无序的、不重复的、无索引
Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。
方法名称及说明:
public boolean add(E e):把给定的对象添加到当前集合中
public void clear():清空集合中所有的元素
public boolean remove(E e):把给定的对象在当前集合中删除
public boolean contains(Object obj):判断当前集合中是否包含给定的对象
public boolean isEmpty():判断当前集合是否为空
public int size():返回集合中元素的个数/集合的长度
注意点:
Collection是一个接口,我们不能直接创建他的对象。
所以,现在我们学习他的方法时,只能创建他实现类的对象。 实现类:ArrayList
Collection<String> coll = new ArrayList<>();
1.添加元素
细节1:如果我们要往List系列集合中添加数据,那么方法永远返回true,因为List系列的是允许元素重复的。
细节2:如果我们要往Set系列集合中添加数据,如果当前要添加元素不存在,方法返回true,表示添加成功。
如果当前要添加的元素已经存在,方法返回false,表示添加失败。
因为Set系列的集合不允许重复。
3.删除
细节1:因为collection里面定义的是共性的方法(所有子集合能用),所以此时不能通过索引进行删除。只能通过元素的对象进行删除。
细节2:方法会有一个布尔类型的返回值,删除成功返回true,删除失败返回false
如果要删除的元素不存在,就会删除失败。
4.判断元素是否包含
细节:底层是依赖equals方法进行判断是否存在的。
所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在javabean类中,一定要重写equals方法。 (否则比较的只是地址)
collection遍历方式
迭代器遍历
迭代器在Java中的类是Iterator,迭代器是集合专用的遍历方式。
迭代器在遍历集合的时候是不依赖索引的,他是通过创建指针,移动指针获取元素
Iterator<E>iterator(): 获取迭代器对象,默认指向当前集合的0索引
boolean hasNext(): 判断当前位置是否有元素,有元素返回true,没有元素返回false
E next() :获取当前位置的元素,并将迭代器对象移向下一个位置。
迭代器遍历具体代码:
Iterator<String>it =list. iterator();// 获取迭代器对象,默认指向当前集合的0索引
while( it. hasNext()){
String str =it. next();//next方法的两件事情:获取元素,并移动指针
System. out. println(str);
}
迭代器的四个细节:
如果当前位置没有元素,还要强行获取,会报NoSuchElementException
迭代器遍历完毕,指针不会复位
如果我们要继续第二次遍历集合,只能再次获取一个新的迭代器对象
循环中只能用一次next方法
如果是奇数个元素,2次next方法就会报1中的错
迭代器遍历时,不能用集合的方法进行增加或者删除
实在要删除:那么可以用迭代器提供的remove方法进行删除。
增强for遍历
●增强for的底层就是迭代器,为了简化迭代器的代码书写的。
●它是JDK5之后出现的,其内部原理就是一个Iterator迭代器
●所有的 单列集合和数组才能用增强for进行遍历。
格式:
for(元素的数据类型 变量名:数组或者集合){
}
实例:
for(String s:coll){
System. out. println(coll);
}
快速生成增强for遍历方式:
集合的名字+for 回车
细节:
Collection<String>coll =new ArrayList<>();
coll. add("zhangsan");
coll. add("lisi");
coll. add("wangwu");
for(String s:coll){
s="qqq";
}
System. out. println(coll);
//输出的结果是:zhangsan lisi wangwu 而不是:qqq qqq qqq
修改增强for中的变量,不会改变集合中原本的数据。
s其实就是一个第三方变量,在循环的过程中依次表示集合中的每一个数据
Lambda表达式遍历
基本语法:
(parameters) -> expression (表达式为其主体)或
(parameters) ->{ statements; }(语句块作为其主体)
Lambda表达式由三部分组成:
paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。
->:可理解为“被用于”
方法体:可以是表达式也可以代码块
default void forEach(Consumer <? super T> action): 结合lambda遍历集合
Collection<String>coll =new ArrayList<>();
coll. add("zhangsan");
coll. add("lisi");
coll. add("wangwu");
coll. forEach((String s)->{
System. out. println(s);
}
) ;
三种通用的遍历方式:
迭代器:在遍历的过程中需要删除元素,请使用迭代器。
增强for、Lambda:仅仅想遍历,那么使用增强for或Lambda表达式。
平衡二叉树
平衡二叉树是二叉排序树,并且左右子树高度差小于等于 1(当左右子树高度差超过1时,通过旋转保持平衡)
右旋
步骤:
确定支点:从添加的节点开始,不断的往父节点找不平衡的节点
以不平衡的点作为支点
就是将根节点的左侧往右拉
原先的左子节点变成新的父节点,并把多余的右子节点出让,给已经降级的根节点当左子节点
平衡二叉树需要旋转的四种情况及平衡方法:
①左左 一次右旋
②左右 先局部左旋,再整体右旋
③右右 一次左旋
④右左 先局部右旋,再整体左旋
右左的意思:当根节点右子树的左子树有节点插入,导致二叉树不平衡
红黑树
●红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构。
● 1972年出现,当时被称之为平衡二叉B树。后来,1978年被修改为如今的"红黑树"。
●它是一种特殊的二叉查找树,红黑树的每一个节点上都有存储位表示节点的颜色,
●每一个节点可以是红或者黑;红黑树不是高度平衡的,它的平衡是通过"红黑规则"进行实现的
平衡二叉树与红黑树对比
平衡二叉树:
高度平衡,当左右子树高度差超过1时,通过旋转保持平衡
红黑树:
是一个二叉查找树,但是不是高度平衡的,条件:特有的红黑规则
红黑树不是高度平衡的,它的平衡是通过"红黑规则"进行实现的
规则如下:
①每一个节点或是红色的,或者是黑色的。
②根节点必须是黑色
③如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的;
④不能出现两个红色节点相连的情况
⑤对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点;
红黑树增删改查的性能都很好
红黑树添加节点规则:
红黑树在添加节点的时候,添加的节点默认是红色的
添加根节点:直接变为黑色
添加非根节点(父为黑色):则不需要任何操作
添加非根节点(父为红色)(叔叔红色):
将“父”设为黑色,将“叔叔”设为黑色
将“祖父”设为“红色”
如果祖父为根,再将根变回黑色
如果祖父非根,将祖父设置为当前节点再进行其他判断
添加非根节点(父为红色)(叔叔黑色)(当前节点时父的右孩子):
把父设置为当前节点并左旋,再进行判断
添加非根节点(父为红色)(叔叔黑色)(当前节点时父的左孩子):
1.将“父”设为“黑色”
2.将“祖父”变为“红色”
3.以祖父为支点进行右旋
Set系列集合
Set系列集合的特点:
无序、不重复、无索引
Set集合的实现类特点:
HashSet:无序、不重复、无索引
LinkedHaşhSet:有序、不重复、无索引
TreeSet:可排序、不重复、无索引
Set集合的方法上基本上与Collection的API一致
public boolean add(E e):把给定的对象添加到当前集合中
public void clear():清空集合中所有的元素
public boolean remove(E e):把给定的对象在当前集合中删除
public boolean contains(Object obj):判断当前集合中是否包含给定的对象
public boolean isEmpty():判断当前集合是否为空
public int size():返回集合中元素的个数/集合的长度
set练习
存储字符串并遍历
利用Set系列的集合,添加字符串,并使用多种方式遍历。
①迭代器②增强for③Lambda表达式
package set类练习;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
public class set_lx {
public static void main(String[] args) {
//创建set集合对象
Set<String> s= new HashSet<>();
//添加元素
boolean r1=s.add("张三");
boolean r2=s.add("李四");
boolean r3=s.add("王五");
//三种遍历
//迭代器遍历
//快速生成s.iterator();
System.out.println("运用迭代器遍历");
Iterator<String> it = s.iterator();
while(it.hasNext()){
String str=it.next();
System.out.println(str);
}
//增强for遍历
//快速生成s.for
System.out.println("运用增强for遍历:");
for (String s1 : s) {
System.out.println(s1);
}
//Lambda遍历
System.out.println("运用增强Lambda遍历:");
s.forEach((String s2) ->System.out.println(s2));
}
}
Lambda 表达式
基本语法:
(parameters) -> expression (表达式为其主体)或
(parameters) ->{ statements; }(语句块作为其主体)
Lambda 表达式可以看作是一个匿名函数,lambda就是由匿名内部类方法而来。
接下来演示如何将匿名内部类方法写成lambda形式:
这是匿名内部类的方法
s.forEach(new Consumer<String>() {
@Override
public void accept(String s2) {
System.out.println(s2);
}
});
将匿名内部类的方法改成Lambda
1.将new到方法名这些代码删除,再删个右大括号。变成如下:
s.forEach((String s2) {
System.out.println(s2);
}
);
2.加个右箭头到参数后面,变成如下:
s.forEach((String s2) ->{
System.out.println(s2);
}
);
3.简化:
1.参数数据类型可删;
2.参数只有一个则小括号可删;
3.如果方法体只有一个,大括号可删,分号也可删。
最终得到Lambda 表达式:
s.forEach((String s2) ->System.out.println(s2));
HashSet
HashSet底层原理是用哈希表来存储数据
哈希表组成
JDK8以前:数组+链表
JDK8以后:数组+链表+红黑树
HashSet底层原理:
① 创建一个默认长度16,默认加载因子为0.75的数组,数组名table
(当数组元素达到16*0.75时,数组长度就会扩大到原来的两倍)
② 根据元素的哈希值跟数组的长度计算出应存入的位置
③ 判断当前位置是否为null,如果是null直接存入
④ 如果位置不为null,表示有元素,则调用equals方法比较属性值
当链表长度大于8而且数组长度大于等于64
⑤ 一样:不存
不一样:存入数组,形成链表
JDK8以前:新元素存入数组,老元素挂在新元素下面
JDK8以后:新元素直接挂在老元素下面
JDK8以后,当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树
如果集合中存储的是自定义对象,必须要重写hashCode和equals方法
哈希值:将对象以整数的形式表现
●根据hashCode方法算出来的int类型的整数
●该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
●一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值
对象的哈希值特点:
●如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
●如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
●在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。(哈希碰撞)
添加元素的位序公式:int index = (数组长度-1)&哈希值;
HashSet的存取元素顺序是不一样的
HashSet没有索引
HashSet是利用什么机制保证数据去重的?
HashCode方法 equals方法
利用HashSet集合去除重复元素
需求:创建一个存储学生对象的集合,存储多个学生对象。
使用程序实现在控制台遍历该集合。
要求:学生对象的成员变量值相同,我们就认为是同一个对象
创建学生类:
package HashSet练习;
import java.util.Objects;
public class student {
private String name;
private int age;
public student() {
}
public student(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 "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
创建测试类:
package HashSet练习;
import java.util.HashSet;
public class HashSet_lx {
public static void main(String[] args) {
//1.创建对象
student s1=new student("a",12);
student s2=new student("b",13);
student s3=new student("c",11);
student s4=new student("a",12);
//创建集合来添加学生
HashSet<student> hs=new HashSet<>();
//添加学生元素
System.out.println(hs.add(s1));
System.out.println(hs.add(s2));
System.out.println(hs.add(s3));
System.out.println(hs.add(s4));
//打印集合
System.out.println(hs);
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/88433b0d7d7028aaddf38de953012b18.png)
可以看到都添加成功了,但对于HashSet来说却不正常,因为s1与s4完全一样,s4是不应该添加成功的,原因在于没student是自己定义的对象,而又没重写hashCode和equals方法,所以是以它们的地址值计算的哈希值,认为了s1与s4不同。
改进:在学生类中添加重写hashCode和equals方法
![](https://img-blog.csdnimg.cn/img_convert/6a137c5563e23f39f0ba17f2e254267b.png)
学生类:
package HashSet练习;
import java.util.Objects;
public class student {
private String name;
private int age;
public student() {
}
public student(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 "student{" +
"name='" + name + '\'' +
", age=" + 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 age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/25c631daf8e5997f4e52e9036aefba87.png)
LinkedHaşhSet
有序、不重复、无索引。
这里的有序指的是保证存储和取出的元素顺序一致
原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个 双链表的机制记录存储的顺序。
import java.util.HashSet;
import java.util.LinkedHashSet;
public class LinkHashSet_lx {
public static void main(String[] args) {
student ss1=new student("aa",12);
student ss2=new student("bb",13);
student ss3=new student("cc",11);
student ss4=new student("aa",12);
//创建集合来添加学生
LinkedHashSet<student> lhs=new LinkedHashSet<>();
//添加学生元素
System.out.println(lhs.add(ss1));
System.out.println(lhs.add(ss2));
System.out.println(lhs.add(ss3));
System.out.println(lhs.add(ss4));
//打印集合
System.out.println(lhs);
}
}
import java.util.Objects;
public class student {
private String name;
private int age;
public student() {
}
public student(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 "student{" +
"name='" + name + '\'' +
", age=" + 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 age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
![](https://img-blog.csdnimg.cn/img_convert/7cbffde7f279d377a14aad75fdc72a34.png)
TreeSet
TreeSet的特点
● 不重复、无索引、可排序
● 可排序:按照元素的默认规则(有小到大)排序。
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。
TreeSet集合默认的规则
● 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序。
● 对于字符、字符串类型:按照字符在ASCII码表中的数字升序进行排序。
利用TreeSet存储整数并进行排序
import java.util.TreeSet;
public class TreeSet_lx1 {
public static void main(String[] args) {
TreeSet<Integer> t_s=new TreeSet<>();
t_s.add(1);
t_s.add(3);
t_s.add(9);
t_s.add(7);
System.out.println(t_s);
}
}
![](https://img-blog.csdnimg.cn/img_convert/033f5dc2da1543ecba1dad15d3f0a671.png)
TreeSet的两种比较方式
方式一:
默认排序/自然排序:Javabean类实现Comparable接口指定比较规则
TreeSet对象方式一排序练习题
需求:创建TreeSet集合,并添加3个学生对象
学生对象属性:
姓名,年龄。
要求按照学生的年龄进行排序
同年龄按照姓名字母排列(暂不考虑中文)
同姓名,同年龄认为是同一个人
import java.util.TreeSet;
public class TreeSet_lx2 {
public static void main(String[] args) {
student s1=new student("zs",21);
student s2=new student("lm",31);
student s3=new student("jh",11);
TreeSet<student> t_s1=new TreeSet<>();
t_s1.add(s1);
t_s1.add(s2);
t_s1.add(s3);
System.out.println(t_s1);
}
}
import java.util.Objects;
public class student implements Comparable<student>{
private String name;
private int age;
public student() {
}
public student(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 "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(student o) {
//用来指定排序规则
//按年龄的升序来排序
return this.getAge()-o.getAge();
}
}
![](https://img-blog.csdnimg.cn/img_convert/5be5ebe9aa98598fdf086497cf6be09e.png)
public int compareTo(student o) {
//用来指定排序规则
//按年龄的升序来排序
return this.getAge()-o.getAge();
}
this:表示当前要添加的元素
o:表示已经在红黑树存在的元素
返回值:
负数:认为要添加的元素是小的,存左边
正数:认为要添加的元素是大的,存右边
0 : 认为要添加的元素已经存在,舍弃
Map系列集合
双列集合的特点
①双列集合一次需要存一对数据,分别为键和值
②键不能重复,值可以重复
③键和值是一一对应的,每一个键只能找到自己对应的值
④键+值这个整体我们称之为“键值对”或者“键值对对象”,在Java中叫做“Entry对象
Map系列集合方法
V put(K key,V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
booleanisEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数
在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回null。
在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回。
Map的遍历方式
①键找值
②键值对
③Lambda表达式
键找值遍历方式
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class map_bl1 {
public static void main(String[] args) {
Map<String,String> map=new HashMap<>();
map.put("大王","小王");
map.put("大李","小李");
map.put("大胡","小胡");
//通过键找值
//获取所有的键,把这些键放到一个单列集合当中
Set<String> k=map.keySet();
//遍历单列集合,得到每一个键
for (String key:k){
//利用map集合中的键获取对应值
String value=map.get(key);
System.out.println(key+"="+value);
}
}
}
运行结果:
![](https://img-blog.csdnimg.cn/img_convert/64ef712377cc4c62b20bb42226a1fc8d.png)
键值对遍历方式
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class map_bl2 {
public static void main(String[] args) {
Map<String,String> map2=new HashMap<>();
map2.put("大王","小王");
map2.put("大李","小李");
map2.put("大胡","小胡");
//3. Map集合的第二种遍历方式
//通过键值对对象进行遍历
//3.1通过一个方法获取所有的键值对对象,返回一个Set集合
Set<Map. Entry<String,String>> entries =map2. entrySet();
//3.2遍历entries这个集合,去得到里面的每一个键值对对象
for (Map. Entry<String,String>entry:entries) {
//3.3利用entry调用get方法获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "=" + value);
}
}
}
![](https://img-blog.csdnimg.cn/img_convert/64ef712377cc4c62b20bb42226a1fc8d.png)
Lambda表达式遍历
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class map_bl3 {
public static void main(String[] args) {
Map<String,String> map3=new HashMap<>();
map3.put("大王","小王");
map3.put("大李","小李");
map3.put("大胡","小胡");
//Map集合的第三种遍历方式
//3.利用1ambda表达式进行遍历
map3. forEach((String key,String value)-> System. out. println(key +"="+value));
}
}
![](https://img-blog.csdnimg.cn/img_convert/64ef712377cc4c62b20bb42226a1fc8d.png)
HashMap
HashMap的特点:
①HashMap是Map里面的一个实现类。
②没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
③特点都是由键决定的:无序、不重复、无索引
④HashMap跟HashSet底层原理是一模一样的,都是哈希表结构
1. HashMap底层是哈希表结构的
2.依赖hashCode方法和equals方法保证键的唯一
3.如果键存储的是自定义对象,需要重写hashCode和equals方法如果值存储自定义对象,不需要重写hashCode和equals方法
LinkedHashMap
由键决定:有序、不重复、无索引。
这里的有序指的是保证存储和取出的元素顺序一致
原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
import java.util.LinkedHashMap;
public class lxxx {
public static void main(String[] args) {
LinkedHashMap<Integer,String> lhm=new LinkedHashMap<>();
lhm.put(312,"a");
lhm.put(423,"b");
lhm.put(532,"r");
lhm.put(872,"d");
System.out.println(lhm);
}
}
![](https://img-blog.csdnimg.cn/img_convert/c107f108f6a85544f1b7259d018806cd.png)
可以观察到是有序的
TreeMap
TreeMap跟TreeSet底层原理一样,都是红黑树结构的。
由键决定特性:不重复、无索引、可排序
可排序:对键进行排序。
注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
代码书写两种排序规则:
实现Comparable接口,指定比较规则。
创建集合时传递Comparator比较器对象,指定比较规则。
TreeMap基本应用
需求:
键:整数表示id
值:字符串表示商品名称
要求:按照id的升序排列、按照id的降序排列
import java.util.Comparator;
import java.util.TreeMap;
public class lx_4 {
public static void main(String[] args) {
TreeMap<Integer,String> TM=new TreeMap<>();
TM.put(3,"可乐");
TM.put(5,"红酒");
TM.put(7,"二锅头");
TM.put(2,"中南海");
TM.put(8,"六个核桃");
System.out.println(TM);
}
}
![](https://img-blog.csdnimg.cn/img_convert/4487dd804d10ba1fd82e662f4beb4b38.png)
import java.util.Comparator;
import java.util.TreeMap;
public class lx_4 {
public static void main(String[] args) {
TreeMap<Integer,String> TM=new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//o1:当前要添加的元素
//o2:表示已经在红黑树中存在的元素
return o2 - o1;
}
});
TM.put(3,"可乐");
TM.put(5,"红酒");
TM.put(7,"二锅头");
TM.put(2,"中南海");
TM.put(8,"六个核桃");
System.out.println(TM);
}
}
![](https://img-blog.csdnimg.cn/img_convert/f4280dd56ba6b945902adbeb252afaed.png)