SortedSet
TreeSet
Collections
所有单值集合
1 SortedSet
特点:有序 唯一
实现类:TreeSet
利用TreeSet特有的对数据进行升序,再放到ArryList进行for+下标倒序打印,或者利用自身的pollLast()取出最后元素并删除打印
import java.util.*;
public class Exec1{
public static void main(String[] args){
TreeSet<Integer> set = new TreeSet<>();
Collections.addAll(set,45,23,78,100,66);
// 数值大小升序
// [23, 45, 66, 78, 100]
System.out.println(set);
// 降序打印所有的元素
// 倒序【想用下标=>ArrayList】
// [23, 45, 66, 78, 100]
// => list [list不会改变原来集合中元素的顺序]
ArrayList<Integer> list = new ArrayList<>(set);
for(int index = list.size()-1; index >= 0; index--){
System.out.println(list.get(index));
}
// [23, 45, 66, 78, 100]
// 取出并删除最后一个
// 100 => [23, 45, 66, 78]
// 只要集合中有元素 => 条件 【while】
while(!set.isEmpty()){
System.out.println(set.pollLast());
}
}
}
2.TreeSet
特点:有序 唯一
数据结构:二叉树【红黑树】【自平衡二叉搜索树】
左子树:<根节点
右子树:>根节点
遍历:中序遍历
2.1 TreeSet1 - 基础用法
特有的方法:
first() 返回第一个元素【最小-泛型升序】
pollFirst() 返回+删除第一个元素
last() 返回最后一个元素【最大的-泛型升序】
pollLast() 返回+删除最后一个元素
* Integer的自然顺序-数值大小升序
* String的自然顺序-内容每一个字符 升序
2.2TreeSet2-定义规则
如果一个元素想要加入TreeSet中 需要泛型具有比较规则
如何具有比较规则-》implements Comparable<泛型>
泛型-跟谁比较
实现接口注定需要覆盖接口中的抽象方法
@Override
public int compareTo(泛型 old){
升序
return 新的xx - 旧的xx 【基本数据类型】
return 新的xx.compareTo(旧的xx)【引用数据类型】
降序
return 旧的xx - 新的xx; 【基本数据类型】
/return 旧的xx.compareTo(新的xx);【引用数据类型】
}
class String implements Comparable<String>....
2.3 TreeSet3-多个属性参与排序
如果多个属性参与排序
优先按照xxx排序 再按照yyy排序
if(xxx不一样的时候)
return xxx-。。。;
if(yyy不一样的时候)
return yyy-。。。;
* 所有属性都一样 舍弃 return 0;
* 所有属性都一样 也不能放弃任何一个元素 return 1;// 【非0】
2.4 TreeSet4-return 1【没有return 0】
TreeSet中各个方法出现的现象:【原因:只看compareTo】
add(元素) 打破TreeSet的唯一性【同一个地址都可以添加多次】
remove(元素) 永远删不掉
contains(元素) 永远返回 false
2.5 TreeSet5 - 遍历+删除
1 TreeSet中数据 => ArrayList
利用ArrayList有下标
for+下标 / 倒序删除
2 迭代器的遍历+迭代器的删除
2.6 TreeSet6 - 修改内容
如果要修改的属性参与比较规则的生成[compareTo/compare]
不能直接修改 采用 1删2改3添加
如果属性没有参与比较规则 直接修改
简单练习
import java.util.*;
public class Exec4{
public static void main(String[] args){
TreeSet<Food> set = new TreeSet<>();
Food f1 = new Food("猪耳朵拌黄瓜",23,2);
Food f2 = new Food("小鸡炖蘑菇",45,1);
Food f3 = new Food("82年的茅台",18000,0);
Food f4 = new Food("西红柿鸡蛋汤",25,3);
Food f5 = new Food("炒饼",7,4);
Food f6 = new Food("辣椒炒肉",23,1);
Collections.addAll(set,f1,f2,f3,f4,f5,f6);
//System.out.println(set);
//打印集合对象的时候显示:
//[XXX菜:XXX类型,YYY菜:YYY类型...]
System.out.println(set);
// 最近西红柿太贵了 删掉所有西红柿相关的菜
// 遍历+判断+删除 =》 CME
// 迭代器的遍历+迭代器的删除
for(Iterator<Food> car = set.iterator();car.hasNext();){
Food ff = car.next();
if(ff.name.contains("西红柿"))
car.remove();
}
System.out.println(set.size());
// 今天我开心 所有酒水打八折
// 遍历+修改【1删2改3添加】
LinkedList<Food> temp = new LinkedList<>();
for(Iterator<Food> car = set.iterator();car.hasNext();){
Food ff = car.next();
if(ff.type == 0){
//1 删除
car.remove();
//2 修改
ff.price *= 0.8;
//3 添加
temp.add(ff);
}
}
set.addAll(temp);
System.out.println(set);
}
}
class Food implements Comparable<Food>{
static String[] data = {"酒水","热菜","凉菜","汤","主食"};
String name;
int price;
int type;//[0:酒水 1:热菜 2:凉菜 3:汤 4:主食]
public Food(String name,int price,int type){
this.name = name;
this.price = price;
this.type = type;
}
@Override
public int compareTo(Food old){
//所有的菜优先按照价格降序排序
//如果价格一样的话 那么按照类型升序排序
//如果价格 类型都一样的话 那么按照名字升序排序
//如果都一样 那么也不能舍弃
if(this.price != old.price)
return old.price - this.price;
if(this.type != old.type)
return this.type - old.type;
if(!this.name.equals(old.name))
return this.name.compareTo(old.name);
return 1;
}
@Override
public String toString(){
// [0:酒水 1:热菜 2:凉菜 3:汤 4:主食]
return name+":"+data[type]+" "+price;
}
}
2.7 TreeSet的构造方法
1 要求泛型自身具有比较能力
// class 泛型 implements Comparable<泛型>{}
TreeSet<泛型> set = new TreeSet<>();
2 TreeSet特点:有序-比较顺序 唯一
// 要求泛型自身具有比较能力
TreeSet<泛型> set = new TreeSet<>(Collection);
3 TreeSet set = new TreeSet(Comparator)
应用场景:1 原有自然顺序不可改 2 类型没有顺序但是不可改类型
// 按照比较器的规则【按照定制排序】
BJQ bb = new BJQ();
TreeSet<Integer> set = new TreeSet<>(bb);
Collections.addAll(set,34,23,45);
System.out.println(set);// 降序
//========================================
// BJQ是一个比较器
class BJQ implements Comparator<Integer>{
// 谁 vs 谁
@Override
public int compare(Integer x, Integer y){
// 新的 旧的
// 内部的逻辑与compareTo相同
return y-x;
}
}
根据构造方法 然后提供比较器进行排序
import java.util.*;
public class Exec6{
public static void main(String[] args){
TreeSet<String> set = new TreeSet<>(new BJQ());
Collections.addAll(set,"12月22","3月8","12月20","5月17");
//升序排序
System.out.println(set);
}
}
class BJQ implements Comparator<String>{
@Override
public int compare(String x, String old){
// x 和 old格式 xx月xx
// data[0]-月 data[1]-日
String[] data = x.split("月");
// temp[0]-月 temp[1]-日
String[] temp = old.split("月");
// 优先按照月份进行升序
// 月份相同 按照日进行升序
if(!data[0].equals(temp[0])){
return Integer.parseInt(data[0])
- Integer.parseInt(temp[0]);
}
return Integer.parseInt(data[1])
- Integer.parseInt(temp[1]);
}
}
BJQ设计成单例模式 通过类名调用 不能造对象
import java.util.*;
public class Exec7{
public static void main(String[] args){
TreeSet<Teacher> set = new TreeSet<>(BJQ.getOnly());
Teacher t1 = new Teacher("汪老师",30,10000);
Teacher t2 = new Teacher("张三",30,10000.1);
Collections.addAll(set,t1,t2);
for(Teacher t : set){
System.out.println(t);
}
}
}
//脱离开老师类制定他的排序规则
//优先按照工资降序排序
//工资一样的话 按照年龄升序排序
//年龄一样的话 按照姓名长度升序排序
//所有属性都一样 舍弃 -》 单例模式
class BJQ implements Comparator<Teacher>{
// 1 私有化构造方法 【外界不可以new BJQ()】
private BJQ(){}
// 2 创建一个私有的 静态的 属于本类类型的对象
private static BJQ only = new BJQ();
// 3 提供一个公共的 静态的 返回本类类型的方法
public static BJQ getOnly(){
return only;
}
@Override
public int compare(Teacher x, Teacher old){
if(x.getSalary() != old.getSalary())
// 强转【忽略小数点】
// double => Double
return Double.valueOf(old.getSalary()).compareTo(Double.valueOf(x.getSalary()));
if(x.getAge() != old.getAge())
return x.getAge() - old.getAge();
//return x.getName().length()-old.getName().length();
if(!x.getName().equals(old.getName()))
return x.getName().length()-old.getName().length();
return 0;
}
}
//封装 不能动
class Teacher{
String name;
int age;
double salary;
public Teacher(String name,int age,double salary){
this.name = name;
this.age = age;
this.salary = salary;
}
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;
}
public double getSalary(){
return salary;
}
public void setSalary(double salary){
this.salary = salary;
}
@Override
public String toString(){
return name + "[" + age + "]" + salary;
}
}
Collections针对List进行的方法
Collections针对List集合提供方法
Collections.sort(List):按照集合的泛型的自然顺序排序
Collections.sort(List,Comparator):按照比较器的定制顺序排序
Collections.reverse(List):反转List中的数据
List ll = Collections.synchronizedList(List对象);将线程不安全的List转为线程安全的List集合
例子
public static void main(String[] args){
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,56,23,100);
System.out.println(list);// 56 23 100
Collections.sort(list);// Integer的自然顺序
System.out.println(list);// 23 56 100
Collections.sort(list, new BJQ());
System.out.println(list);// 100 56 23
Collections.reverse(list);
System.out.println(list);// 23 56 100
}
}
class BJQ implements Comparator<Integer>{
@Override
public int compare(Integer x, Integer y){
return y - x;
}
}
collections针对所有单值集合提供的方法
Collections针对所有单值集合提供的方法
T Collections.max(Collection);按照泛型的自然顺序返回集合中的"最大"值【前提:升序】【取最后一个】
T Collections.max(Collection,Comparator);按照比较器的定制顺序返回"最大"值【前提:升序】【取最后一个】
T Collections.min(Collection);按照泛型的自然顺序返回集合中的"最小"值【前提:升序】【取第一个】
T Collections.min(Collection,Comparator);按照比较器的定制顺序返回"最小"值【前提:升序】【取第一个】
Collections.addAll(Collection, T ... x); 往集合中一次添加多个元素
int Collections.frequency(Collection,元素);某个元素在集合中出现的次数
举例
public static void main(String[] args){
HashSet<Integer> set = new HashSet<>();
Collections.addAll(set,34,56,100,66);
int num = Collections.frequency(set,34);
System.out.println(num);
// Integer 的自然顺序来的【升序】
// 最大值=最后一个
//Integer max = Collections.max(set);
//System.out.println(max);// 100
// Integer max = Collections.max(set, new BJQ());
// System.out.println(max);// 34
//Integer min = Collections.min(set);
//System.out.println(min);// 34
Integer min = Collections.min(set, new BJQ());
System.out.println(min);// 100
}
}
class BJQ implements Comparator<Integer>{
@Override
public int compare(Integer x, Integer y){
return y - x;
}
}