Java_基础—TreeSet原理及练习

  • 1.特点
    • TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
  • 2.使用方式
    • a.自然顺序(Comparable)
      • TreeSet类的add()方法中会把存入的对象提升为Comparable类型
      • 调用对象的compareTo()方法和集合中的对象比较
      • 根据compareTo()方法返回的结果进行存储
    • b.比较器顺序(Comparator)
      • 创建TreeSet的时候可以制定 一个Comparator
      • 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
      • add()方法内部会自动调用Comparator接口中compare()方法排序
      • 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
    • c.两种方式的区别
      • TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
      • TreeSet如果传入Comparator, 就优先按照Comparator

Test4.java

package com.soar.set;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;

public class Test4 {
    /*
     * 在一个集合中存储了无序并且重复的字符串,
     * 定义一个方法,让其有序(字典顺序),而且还不能去除重复
     * 分析:
     * ① 定义一个List集合,并存储重复的无序的字符串
     * ② 定义方法对其排序保留重复
     * ③ 打印List集合
     */
    public static void main(String[] args) {
        //① 定义一个List集合,并存储重复的无序的字符串
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("ccc");
        list.add("dddd");
        list.add("hahhaha");
        list.add("bbb");
        list.add("aaa");
        list.add("aaa");

        //② 定义方法对其排序保留重复
        sort(list);

        //③ 打印List集合
        System.out.println(list);
    }
        /*
         * 定义方法,排序并保留重复
         * 分析:
         * ① 创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
         * ② 将List集合中所有的元素添加到TreeSet集合中,对其排序,保留重复
         * ③ 清空list集合
         * ④ 将TreeSet集合中排好序的元素添加到list中
         */

    public static void sort(ArrayList<String> list) {
        //① 创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
                int num = s1.compareTo(s2);         //比较内容为主要条件
                return num == 0 ? 1 : num;          //保留重复
            }
        });
        //② 将List集合中所有的元素添加到TreeSet集合中,对其排序,保留重复
        ts.addAll(list);
        //③ 清空list集合
        list.clear();
        //④ 将TreeSet集合中排好序的元素添加到list中
        list.addAll(ts);

    }

}

Test5.java

package com.soar.set;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Test5 {
    /*
     * 从键盘接收一个字符串, 程序对其中所有字符进行排序,
     * 例如键盘输入: helloitcast程序打印:acehillostt
     * 分析:
     * ① 键盘录入字符串,Scanner
     * ② 将字符串转换为字符数组
     * ③ 定义TreeSet集合,传入比较器对字符排序,并保留重复
     * ④ 遍历字符数组打印,将每一个字符存储在TreeSet集合中
     * ⑤ 便利TreeSet集合,打印每一个字符
     */
    public static void main(String[] args) {
        //① 键盘录入字符串,Scanner
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String line = sc.nextLine();
        //② 将字符串转换为字符数组
        char[] arr = line.toCharArray();
        //③ 定义TreeSet集合,传入比较器对字符排序,并保留重复
        TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>(){

            @Override
            public int compare(Character c1, Character c2) {
                //int num = c1 - c2;            //自动拆箱
                int num = c1.compareTo(c2);
                return num == 0 ? 1 : num;
            }
        });
        //④ 遍历字符数组打印,将每一个字符存储在TreeSet集合中
        for(char c : arr){
            ts.add(c);              //自动装箱
        }
        //⑤ 便利TreeSet集合,打印每一个字符
        for(Character ch :ts){
            System.out.println(ch);
        }
    }

}

Test6.java

package com.soar.set;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Test6 {
    /*
     * 程序启动后, 可以从键盘输入接收多个整数, 
     * 直到输入quit时结束输入. 把所有输入的整数倒序排列打印.
     * 分析:
     * ① 创建Scanner对象,键盘录入
     * ② 创建TreeSet集合对象,TreeSet集合中传入比较器
     * ③ 无限循环不断的接收整数,遇到quit退出,因为退出是quit,所以键盘录入的时候,应该是字符串形式录入
     * ④ 判断是quit就退出,不是就将集合转换成Integer,并添加到集合中
     * ⑤ 遍历TreeSet集合并打印每一个元素
     */
    public static void main(String[] args) {
        //① 创建Scanner对象,键盘录入
        Scanner sc = new Scanner(System.in);
        //② 创建TreeSet集合对象,TreeSet集合中传入比较器
        TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>(){
            @Override
            public int compare(Integer i1, Integer i2) {
                //int num = i2 - i1 ;       //自动拆箱
                int num = i2.compareTo(i1);
                return num == 0 ? 1 : num;
            }
        });
        //③ 无限循环不断的接收整数,遇到quit退出,因为退出是quit,所以键盘录入的时候,应该是字符串形式录入
        while(true){
            String line = sc.nextLine();        //将键盘录入的字符串存入到line中
            if("quit".equals(line)){
                break;
            }
            //④ 判断是quit就退出,不是就将集合转换成Integer,并添加到集合中
            Integer i = Integer.parseInt(line);     //自动装箱
            ts.add(i);
        }
        //⑤ 遍历TreeSet集合并打印每一个元素
        for (Integer integer : ts) {
            System.out.println(integer);
        }
    }

}

Test7.java

package com.soar.set;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

import com.soar.bean.Student;

public class Test7 {
    /*
        * A:案例演示
        * 需求:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),
        * 按照总分从高到低输出到控制台。
        * 分析:
        * ① 定义一个学生类
        *   成员变量:姓名,语文成绩,数学成绩,英语成绩,总成绩
        *   成员方法:空参(),有参构造(语文成绩,数学成绩,英语成绩),
        *   toString()方法,在遍历集合中的Student对象打印对象引用的时候显示属性值
        * ② 键盘录入Scanner,创建键盘录入对象
        * ③ 创建TreeSet集合对象,在TreeSet的构造函数中传入比较器,按照总分比较
        * ④ 录入5个学生,所以以集合中的学生个数为判断条件,如果size是小于5就进行存储
        * ⑤ 将录入的字符串用”,“切割,会返回一个字符串数组,将字符串数组中从第二个元素转换成int数组
        * ⑥ 将转换后的结果封装成Student对象,将Student添加到TreeSet集合中
        * ⑦ 遍历TreeSet集合打印每一个Student对象
        * 
     */
    public static void main(String[] args) {
        //② 键盘录入Scanner,创建键盘录入对象
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生成绩格式是:姓名,语文成绩,数学成绩,英语成绩");
        //③ 创建TreeSet集合对象,在TreeSet的构造函数中传入比较器,按照总分比较
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>(){
            @Override
            public int compare(Student s1, Student s2) {
                int num = s1.getSum() - s2.getSum();
                return num ==0 ? 1 : num;
            }
        });
        //④ 录入5个学生,所以以集合中的学生个数为判断条件,如果size是小于5就进行存储
        while(ts.size()<5){
            //⑤ 将录入的字符串用”,“切割,会返回一个字符串数组,将字符串数组中从第二个元素转换成int数组
            String line = sc.nextLine();
            String[] arr = line.split(",");
            int chinese = Integer.parseInt(arr[1]);
            int math = Integer.parseInt(arr[2]);
            int english = Integer.parseInt(arr[3]);
            //⑥ 将转换后的结果封装成Student对象,将Student添加到TreeSet集合中
            ts.add(new Student(arr[0],chinese,math,english));
        }
        //⑦ 遍历TreeSet集合打印每一个Student对象
        System.out.println("排序后的学生信息:");
        for (Student student : ts) {
            System.out.println(student);
        }
    }

}

Student.java

package com.soar.bean;

public class Student {
    private String name;
    private int chinese;
    private int math;
    private int english;
    private int sum;

    public Student() {
        super();    
    }

    public Student(String name, int chinese, int math, int english) {
        super();
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
        this.sum = this.chinese + this.math + this.english;
    }

    public int getSum() {
        return sum;
    }

    public String toString(){
        return name + "," + chinese + "," + math +"," + english + "," + sum;
    }
}
  • 1.List
    • a.普通for循环, 使用get()逐个获取
    • b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
    • c.增强for循环, 只要可以使用Iterator的类都可以用
    • d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
  • 2.Set
    • a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
    • b.增强for循环, 只要可以使用Iterator的类都可以用
  • 3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除
posted @ 2017-07-15 18:45  Soar_Sir  阅读(517)  评论(0)    收藏  举报