1-27TreeSet简介

使用TreeSet存储Integer对象

TreeSet的特点是可以对存放进去的元素进行排序。

package com.monkey1024.set;

import java.util.TreeSet;

/**
 * TreeSet可以对元素进行排序
 * 使用TreeSet存储Integer对象
 * @author Administrator
 *
 */
public class TreeSetTest01 {

    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(5);
        ts.add(2);
        ts.add(4);
        ts.add(2);


        System.out.println(ts);
    }

}

使用TreeSet存储自定义类型对象

这里还是存储之前定义的Person对象,需要实现Comparable接口并且重写compareTo方法,先根据name的字典顺序排序,然后再根据年龄进行排序。

package com.monkey1024.bean;

/**
 * Person类
 *
 */
public class Person implements Comparable<Person>{

    private String name;
    private int age;

    public Person() {

    }

    public Person(String name, int age) {
        super();
        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;
    }

    // 重写toString方法
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public int compareTo(Person o) {
        int num = this.name.compareTo(o.getName());
        if(num != 0){
            //先用name排序
            return num;
        }else{
            //如果姓名排序一样则以age进行排序
            return this.age - o.getAge();
        }
    }


}

测试类:

package com.monkey1024.set;

import java.util.TreeSet;

import com.monkey1024.bean.Person;

/**
 * TreeSet可以对元素进行排序
 * 使用TreeSet存储Person对象
 *
 */
public class TreeSetTest02 {

    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方法返回正数的时候,系统将元素存储到右边,所以集合存取顺序一致
compare返回正数

当compareTo方法返回负数的时候,系统将元素存储到左边,所以集合会倒序存储
compare返回负数

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);
        }
    }

}
原文地址:https://www.cnblogs.com/superfly123/p/10483313.html