使用TreeSet存储Integer对象
TreeSet的特点是可以对存放进去的元素进行排序。
package com.sutaoyu.list; import java.util.TreeSet; public class list_test_18 { public static void main(String[] args) { TreeSet<Integer> ts = new TreeSet<>(); ts.add(3); ts.add(3); ts.add(3); ts.add(1); ts.add(1); ts.add(2); ts.add(4); ts.add(5); ts.add(7); ts.add(6); System.out.println(ts); } }
使用TreeSet存储自定义类型对象
这里还是存储之前定义的Person对象,需要实现Comparable接口并且重写compareTo方法,先根据name的字典顺序排序,然后再根据年龄进行排序。
package com.sutaoyu.TreeSet; import java.util.TreeSet; public class TreeSet_test_1 { public static void main(String[] args) { TreeSet<Person> ts = new TreeSet<>(); ts.add(new Person("tony",23)); ts.add(new Person("paul",20)); ts.add(new Person("andy",22)); ts.add(new Person("james",24)); ts.add(new Person("lucy",21)); System.out.println(ts); } }
测试类里面如果name写的是中文的话则不能进行汉语拼音排序,因为String类中重写的compareTo方法是根据char类型对应的ascii值进行排序的。
compareTo方法的返回值
TreeSet使用了二叉树的数据结构,负数放到左边,正数放到右边。
- 当compareTo方法返回0的时候,系统会认为两者一致,所以不会向集合中添加元素
- 当compareTo方法返回正数的时候,系统将元素存储到右边,所以集合存取顺序一致
- 当compareTo方法返回负数的时候,系统将元素存储到左边,所以集合会倒序存储
Comparator比较器
可以向TreeSet的构造方法中传入一个定制的Comparator,如果传入了Comparator的子类对象, 那么TreeSet就会按照传入对象中定制的规则排序。例如将Person中name按照长度排序。
定制一个CompareByNameLength类实现Comparator接口并重写compare方法,在方法里面编写排序规则
package com.monkey1024.set; import java.util.Comparator; import com.monkey1024.bean.Person; public class CompareByNameLength implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { //根据name长度进行排序 int num = p1.getName().length() - p2.getName().length(); if(num == 0){ num = p1.getName().compareTo(p2.getName()); if(num == 0){ num = p1.getAge() - p2.getAge(); } } return num; } }
测试类,向TreeSet的构造方法中传入CompareByNameLength对象
package com.monkey1024.set; import java.util.TreeSet; import com.monkey1024.bean.Person; /** * TreeSet可以对元素进行排序 * 使用TreeSet根据name长度进行排序 * */ public class TreeSetTest03 { public static void main(String[] args) { TreeSet<Person> ts = new TreeSet<>(new CompareByNameLength()); ts.add(new Person("tony", 23)); ts.add(new Person("jordan", 20)); ts.add(new Person("tim", 22)); ts.add(new Person("james", 24)); ts.add(new Person("an", 21)); System.out.println(ts); } }
练习:
1.将一个字符串中的字符按照字典顺序进行排序,要保留重复的字符。例如输入:java,打印aajv
答案:
1.向输入的字符串转换为字符数组,然后向TreeSet中添加字符
package com.monkey1024.set.exercise; import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet; /** * 问题:将一个字符串中的字符按照字典顺序进行排序,要保留重复的字符。例如输入:java,打印aajv * 分析:向输入的字符串转换为字符数组,然后向TreeSet中添加字符 */ public class Exercise03 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); //创建键盘录入对象 System.out.println("请输入一行字符串:"); String line = sc.nextLine(); //将键盘录入的字符串存储在line中 char[] arr = line.toCharArray(); //将字符串转换成字符数组 TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() { @Override public int compare(Character c1, Character c2) { int num = c1.compareTo(c2); //保存重复数据 return num == 0 ? 1 : num; } }); for(char c : arr) { ts.add(c); } for(Character ch : ts) { System.out.print(ch); } } }