Day 19 Collection集合 Set

选择排序

/**
 * @author 刘涛
 * @date 2022/8/22 9:49
 *
 * List集合去重
 *      1)新建集合思想
 *      2)如果不让你新建集合,如何完成?
 *      创建一个旧集合,添加一堆重复的字符串数据
 *      遍历旧集合,间接的  利用"选择排序的思想"
 *          使用0角标对应的元素依次和后面的元素进行比较(equals()),如果后面的元素和前面的元素一致,
 *          将后面的元素,从集合中干掉(remove(Object)),角标应该--,结束;
 *
 *
 *          使用这种完成存自定义类型
 *          List<Student>  ---存储Student类型,
 *                  保证Student类型需要重写Object的hashCode和equals()
 */
public class Test1 {
    public static void main(String[] args) {

        //创建一个旧集合
        List<String> list  = new ArrayList<>() ;

        //添加重复的字符串元素
        list.add("hello") ;
        list.add("world") ;
        list.add("hello") ;
        list.add("javaee") ;
        list.add("javaee") ;
        list.add("world") ;
        list.add("Javaee") ;
        list.add("python") ;
        list.add("python") ;

        //利用选择排序的思想
        for(int x = 0 ; x < list.size()-1; x++){//比较的次数
            for(int y = x+1; y<list.size(); y ++){//将后面的元素一一遍历出来
                //使用list.get(x)前的元素和list.get(y)进行比较,如果一致,将后面的元素干掉,角标--
                if(list.get(x).equals(list.get(y))){
                    list.remove(y) ;
                    y-- ;
                }
            }
        }
        //增强for遍历集合
        for(String s:list){
            System.out.println(s);
        }

    }
}

集合嵌套

import java.util.ArrayList;

/**
 * @author 刘涛
 * @date 2022/8/22 10:01
 * 有三个java基础班,每一个java基础班ArrayList<Student>
 * 	然后将每一个基础班存入4个学生,大的集合是ArrayList<ArrayList<Student>>,进行遍历
 *
 * 	获取学生信息
 *
 * 	       分析:
 * 	            1)有一个大的集合:里面有3个小的集合-都是ArrayList<Student>
 * 	                创建一个大的集合ArrayList<ArrayList<Student>>
 * 	            2)分别创建四个小的集合,给里面添加学生信息
 * 	            3)在将每一个小的ArrayList<Student>存储到的集合中
 * 	            4)增强for遍历大的集合 ,然后在遍历小集合
 *
 */
public class Test2 {
    public static void main(String[] args) {

        //先创建一个的集合
        ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;

        //分别创建小的集合
        //第一个java基础班
        ArrayList<Student> array1 = new ArrayList<>() ;
        //添加两个学生
        Student s1 = new Student("瞎子",25) ;
        Student s2 = new Student("ez",26)  ;
        Student s3 = new Student("螳螂",20) ;
        //添加
        array1.add(s1) ;
        array1.add(s2) ;
        array1.add(s3) ;
        //将array1添加到大集合中
        bigArray.add(array1) ;

        //第二个java基础班
        ArrayList<Student> array2 = new ArrayList<>() ;
        //创建三个学生
        Student s4 = new Student("宋江",35) ;
        Student s5 = new Student("卢俊义",32) ;
        Student s6 = new Student("武大郎",40) ;
        array2.add(s4) ;
        array2.add(s5) ;
        array2.add(s6) ;
        //将第二个集合添加到大集合中
        bigArray.add(array2) ;

        //第三个java基础班
        ArrayList<Student> array3 = new ArrayList<>() ;
        //创建三个学生
        Student s7 = new Student("曹操",45) ;
        Student s8 = new Student("周瑜",20) ;
        Student s9 = new Student("刘备",30) ;
        array3.add(s7) ;
        array3.add(s8) ;
        array3.add(s9) ;
        //将第三个集合添加到大集合中
        bigArray.add(array3) ;

        // ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ; //大集合
        for(ArrayList<Student>  array  :bigArray){
            //里面的小的集合泛型:Student
            for(Student s:array){
                System.out.println(s.getName()+"---"+s.getAge());
            }
        }
    }
}

Set

Set集合的特点:保证元素唯一,而且不能保证迭代次序

唯一,无序性(元素不重复,不能保证顺序—哈希表(key-value键值对)完成的(桶状结构))

HashSet

为什么保证元素能唯一的:

HashSet底层依赖于Map<K,V>接口的子实现类HashMap<K,V>实现的

  1. HashSet的add()方法依赖于HashMap的put 方法,这个方法间接依赖于Object类的equals和hashCode()
    •     String类型,String底层已经重写了hashCode()和equals方法
      
  2. HashCode:比较字符串的哈希码值(理解为地址值)是否一样,如果一样,比较内容是否一样
    •          英文可以,但是中文,繁写字体或简写字体,hashCode一样,内容可能不一样;必须重写equals,比较内容是否相容!
      
  3. HashSet如果存储的是自定义对象,必须自定义的类要重写Object类的equals和hashCode(),否则不是唯一的

TreeSet

Set集合的子实现类

底层数据结构是一个红黑树结构,(自平衡的二叉树结构)

依赖于TreeMap<K,V>实现的, 可以完成自然排序以及比较器排序,取决于我们使用的构造方法

  • public TreeSet() :无参构造方法:完成一种自然排序,前提:存储的数据类型必须要实现Compareable接口里面的compareTo方法
  • public TreeSet(Comparator comparator):有参构造方法实现比较器排序:存储的类型必须要实现comparator接口里面的compare()方法

public TreeSet():无参构造 自然排序

import java.util.TreeSet;

/**
 * @author 刘涛
 * @date 2022/8/22 11:25
 * 集合的TreeSet<Student> 自定义对象,如何进行排序(自然排序--->TreeSet的无参构造方法)
 * 		按照学生的年龄从小到大排序
 * 	学生的姓名和年龄
 *
 * 	一般这种:告诉你的排序主要条件,你自己分析次要条件
 * 	            主要条件:年龄从小到大,
 * 	            次要条件:年龄相等的,就是同一个人吗?,年龄相等还要判断姓名是否一样
 * 	                Student s1 = new Student("gaoyuanyuan",36) ;
 * 	                Student s2 = new Student("zhangjianing",36) ;
 */
public class TreeSetTest {
    public static void main(String[] args) {

        //自然排序--->TreeSet的无参构造方法
        //自定义类型
        //TreeSet集合:set集合的一种:元素唯一,而且按照条件要排序的 (排序条件:主要/次要)
        TreeSet<Student>  ts = new TreeSet<>() ;

        //创建一些学生对象
        Student s1  = new Student("gaoyuanyuan",36) ;
        Student s2  = new Student("gaoyuanyuan",36) ;
        Student s3  = new Student("zhangjianing",36) ;
        Student s4  = new Student("zhangsan",20) ;
        Student s5  = new Student("wenzhang",19) ;
        Student s6  = new Student("wenzhang",25) ;
        Student s7  = new Student("mayili",43) ;
        Student s8  = new Student("yaodi",30) ;
        Student s9  = new Student("mayili",43) ;

        //添加集合
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;
        ts.add(s8) ;
        ts.add(s9) ;
        //遍历
        for(Student s:ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
        /**
         *    要实现自然排序,使用TreeSet集合的无参构造方法,
         *    那么TreeSet<E>,里面的泛型E类型,必须要实现一个接口Compareable接口,
         *    重写接口的comareTo方法,否则无法进行自然排序;意味着如果TreeSet<Student>,
         *    自定义类型,那么Student这个类必须要实现Comareable接口,否则报错;
         */
    }
    
    
    ------------------------------------------------------
    
    //学生类
    //要实现自然 排序:自定义的类型要实现自然排序的接口:Comareable
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 +
                '}';
    }

    /**
     * 要进行比较的具体的方法  ,就模拟Integer类 jdk 提供的也实现了 Comareable接口完成数字的排序  里面使用三元运算符
     * @param s
     * @return
     */
    @Override
    public int compareTo(Student s) { //s就是要传进来的学生对象    s1-s9  s1就是根节点
        //主要条件就是按照学生的年龄从小到大
        int num =this.age - s.age ;//  this.age:当前类对象的地址值引用的学生年龄使用根节点-存进来的学生的年龄的
        //年龄从大到小
       // int num = s.age -this.age;

        //次要条件:年龄相同的:不一定就是同一个人
        //年龄如果是0,说明上面的年龄相等,比较姓名是否一样,姓名(英文):String类型重写了comareable方法,实现了comareTo方法,按照字典顺序比较
        int num2 = (num==0)?this.name.compareTo(s.name):num; //年龄相等,按照姓名比较,不相等;按照年龄从小打大
        return num2;
    }
}


public TreeSet(Comparator comparator): 有参构造 比较器排序

/**
 *TreeSet<Student>存储的这个学生,姓名和年龄,主要条件:按照学生的姓名的长度从小到大比较?(使用比较器排序完成)
        * //长度一样,姓名内容可能不一样,比较姓名内容;
        * // 姓名内容一样,比较年龄是否一样
        * //Student s1 = new Student("zyyzabc",35) ;
        * //Student s2 = new Student("liushishi",35) ;
        * //Student s3 = new Student("fenqing",35) ;
        * //Student s4 = new Student("fenqing",38) ;
 */
public class TreeSetTest3 {
    public static void main(String[] args) {
        //创建TreeSet集合对象,有参构造方式,完成比较器排序
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //主要条件:按照学生的姓名的长度从小到大比较 排序
                int num = s1.getName().length() - s2.getName().length() ;
                //长度一样,不一定是同一个人,还要比较:姓名的内容是否一样,按照字典比较
                int num2 = (num==0)?s1.getName().compareTo(s2.getName()):num;
                //长度一样,姓名也一样,比较年龄是否一样(年龄从小到大)
                int num3 = (num2==0)?s1.getAge()-s2.getAge():num2;
                return num3;
            }
        }) ;
        //创建学生对象
        Student s1 = new Student("gaoyuanyuan",43) ;
        Student s2 = new Student("gaoyuanyuan",43) ;
        Student s3 = new Student("zhangsanfen",43) ;
        Student s4 = new Student("zhangsanfen",25) ;
        Student s5 = new Student("liushishi",35) ;
        Student s6 = new Student("wanglihong",30) ;
        Student s7 = new Student("liushishi",35) ;
        Student s8 = new Student("wuqilong",20) ;
        Student s9 = new Student("wangwuwu",50) ;

        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;
        ts.add(s8) ;
        ts.add(s9) ;

        //遍历
        for(Student s:ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

-----------------------------------------------------------

//学生类
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 +
                '}';
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值