Java基础(21)asList()方法、集合嵌套、Set集合、HashSet集合、LinkedHashSet集合、TreeSet集合

本文详细介绍了Java中的asList()方法,包括其使用及注意事项;探讨了ArrayList的集合嵌套,展示了如何通过集合嵌套处理多层数据结构;深入讲解了Set接口及其具体实现类HashSet、LinkedHashSet和TreeSet,包括它们的特点、数据结构以及使用场景,特别提到了HashSet的去重功能和TreeSet的排序机制。

1. asList()方法

1. Arrays工具类的asList(T … t)方法的使用:将数组转化成集合
2. 传进来基本类型数组和引用类型数组的差别

public class TestDemo01 {
    public static void main(String[] args) {

        //传入引用类型
        List<String> strings = Arrays.asList("abc", "def", "ghi", "jkl");
        List<Integer> integers = Arrays.asList(111, 222, 333, 444, 555);
        System.out.println(strings);   //[abc, def, ghi, jkl]
        System.out.println(integers);   //[111, 222, 333, 444, 555]

        //传入一个基本类型的数组
        int[] arr = {10,20,30,40,50};
        List<int[]> ints = Arrays.asList(arr);
        System.out.println(ints.get(0)[1]);   //20 获取第一个数组的第二个元素
        System.out.println(ints.toString());   //[[I@3f99bd52]  存的是数组的地址值

        //传进来一个对象数组
        Integer[] integers1 = {12,22,32,42,52};
        List<Integer> integerList = Arrays.asList(integers1);
        System.out.println(integerList.get(1));   //22
        System.out.println(integerList);   //[12, 22, 32, 42, 52]

        //传进来多个基本类型的数组,转化的集合是:在这个集合中,放入了多个数组对象
        int[] arr1 = {11,12,13,14,15};
        int[] arr2 = {21,22,23,24,25};
        int[] arr3 = {31,32,33,34,35};
        List<int[]> intList = Arrays.asList(arr1, arr2, arr3);
        System.out.println(intList);

        //传进来多个对象数组,那么就把这个对象数组作为整体,放到集合中
        Integer[] arr4 = {12,22,32,42,52};
        Integer[] arr5 = {44,55,66,77,88};
        Integer[] arr6 = {31,41,51,61,71};
        List<Integer[]> integersList = Arrays.asList(arr4, arr5, arr6);
        System.out.println(integersList);
    }
}

在这里插入图片描述
3. 【注意事项】asList()得到的集合的长度是不可变的,也就是说不能对该集合进行add()和remove()方法

2. 集合嵌套之ArrayList嵌套ArrayList

1. 引入:我们班有学生,每一个学生是不是一个对象。所以我们可以使用一个集合表示我们班级的学生。ArrayList。但是呢,我们旁边是不是还有班级,每个班级是不是也是一个ArrayList。 而我现在有多个ArrayList。也要用集合存储,怎么办呢?集合嵌套之ArrayList嵌套ArrayList
2. 代码示例

public class TestDemo02 {
    public static void main(String[] args) {
        ArrayList<Student> javaList = new ArrayList<>();
        javaList.add(new Student("ez",23));
        javaList.add(new Student("vn",24));

        ArrayList<Student> webList = new ArrayList<>();
        webList.add(new Student("noc",33));
        webList.add(new Student("mf",35));

        ArrayList<Student> linuxList = new ArrayList<>();
        linuxList.add(new Student("tf",36));
        linuxList.add(new Student("ag",38));

        //集合嵌套
        ArrayList<ArrayList<Student>> allList = new ArrayList<>();
        allList.add(javaList);
        allList.add(webList);
        allList.add(linuxList);

        //获取每一个人的信息:增强for
        for (ArrayList<Student> minList : allList) {
            for (Student student : minList) {
                System.out.println(student.getName() + "===" + student.getAge());
            }
        }
    }
}

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

3. Set集合

1. Set集合概述:一个不包含重复元素的Collection接口的子接口
2. Set集合的结构图
在这里插入图片描述

4. HashSet集合

1. HashSet概述:构造一个新的空set,其底层 HashMap 实例的默认初始容量是16
2. HashSet的数据结构:HashSet的底层是哈希表,元素无序(存取顺序不一致),不允许有重复元素,线程不安全。
3. HashSet集合存储基本类型的元素

public class TestDemo01 {
    public static void main(String[] args) {
        HashSet<String> stringHashSet = new HashSet<>();
        stringHashSet.add("张三");
        stringHashSet.add("李四");
        stringHashSet.add("王五");
        stringHashSet.add("张三");
        stringHashSet.add("伊泽瑞尔");
        stringHashSet.add("古拉加斯");
        stringHashSet.add("李四");
        stringHashSet.add("伊泽瑞尔");
        stringHashSet.add("赵六");

        System.out.println(stringHashSet);   //[李四, 张三, 王五, 赵六, 古拉加斯, 伊泽瑞尔]

        for (String s : stringHashSet) {
            System.out.println(s);   //李四    张三    王五    赵六    古拉加斯    伊泽瑞尔
        }

        System.out.println("================================");

        HashSet<Integer> integerHashSet = new HashSet<>();
        integerHashSet.add(11);
        integerHashSet.add(21);
        integerHashSet.add(31);
        integerHashSet.add(11);
        integerHashSet.add(22);
        integerHashSet.add(44);
        integerHashSet.add(31);
        integerHashSet.add(11);

        System.out.println(integerHashSet);   //[21, 22, 11, 44, 31]

        for (Integer integer : integerHashSet) {
            System.out.println(integer);    //21   22   11   44   31
        }
    }
}

4. HashSet集合存储引用类型元素

//没有重写hashCode()方法和equals()方法时
public class TestDemo02 {
    public static void main(String[] args) {
        HashSet<Student> studentHashSet = new HashSet<>();
        studentHashSet.add(new Student("ez",22));
        studentHashSet.add(new Student("tf",23));
        studentHashSet.add(new Student("vn",24));
        studentHashSet.add(new Student("ez",22));
        studentHashSet.add(new Student("vn",24));
        studentHashSet.add(new Student("ag",26));

        for (Student student : studentHashSet) {
            System.out.println(student.getName()+"==="+student.getAge());
        }
        /**
         * vn===24
         * ag===26
         * ez===22
         * ez===22
         * vn===24
         * tf===23
         * 这时候发现集合中重复的元素并没有被删掉
         * 因为HashSet集合保证元素唯一性是靠元素重写hashCode()方法和equals()方法来保证的
         * 如果元素不重写hashCode()方法和equals()方法,那么无法保证元素的唯一性
         */
    }
}

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

===============================================================

//重写hashCode()方法和equals()方法之后
public class TestDemo01 {
    public static void main(String[] args) {
        HashSet<Student> studentHashSet = new HashSet<>();
        studentHashSet.add(new Student("ez",22));
        studentHashSet.add(new Student("tf",23));
        studentHashSet.add(new Student("vn",24));
        studentHashSet.add(new Student("ez",22));
        studentHashSet.add(new Student("vn",24));
        studentHashSet.add(new Student("ag",26));

        for (Student student : studentHashSet) {
            System.out.println(student.getName()+"==="+student.getAge());
        }

        /**
         * vn===24
         * ez===22
         * ag===26
         * tf===23
         */

    }
}

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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }
}

在这里插入图片描述
5. HashSet遍历集合

public class TestDemo02 {
    public static void main(String[] args) {
        HashSet<Integer> integerHashSet = new HashSet<>();
        integerHashSet.add(11);
        integerHashSet.add(22);
        integerHashSet.add(33);
        integerHashSet.add(44);

        //方式1:迭代器
        Iterator<Integer> iterator = integerHashSet.iterator();
        while (iterator.hasNext()) {
            Integer num = iterator.next();
            System.out.println(num);
        }

        //方式2:增强for
        for (Integer integer : integerHashSet) {
            System.out.println(integer);
        }
        
        //方式3:forEach()
        integerHashSet.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });
    }
}

6. ArrayList去重元素的方法:HashSet(Collection < ? extends E > c):构造一个包含指定 collection 中的元素的新 set

public class TestDemo03 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(11);
        arrayList.add(21);
        arrayList.add(31);
        arrayList.add(11);
        arrayList.add(21);
        arrayList.add(51);
        arrayList.add(151);
        arrayList.add(116);

        System.out.println(arrayList);   //[11, 21, 31, 11, 21, 51, 151, 116]

        HashSet<Integer> integers = new HashSet<>(arrayList);
        System.out.println(integers);    //[51, 116, 21, 151, 11, 31]
    }
}

5. LinkedHashSet集合

1. LinkedHashSet概述:元素有序且唯一。线程不安全,效率高
2. LinkedHashSet底层数据结构:链表+哈希表。链表保证元素有序,哈希表保证元素唯一

public class TestDemo01 {
    public static void main(String[] args) {
        LinkedHashSet<Integer> integerLinkedHashSet = new LinkedHashSet<>();
        integerLinkedHashSet.add(11);
        integerLinkedHashSet.add(21);
        integerLinkedHashSet.add(31);
        integerLinkedHashSet.add(11);
        integerLinkedHashSet.add(41);
        integerLinkedHashSet.add(21);
        integerLinkedHashSet.add(51);
        integerLinkedHashSet.add(61);
        integerLinkedHashSet.add(31);

        System.out.println(integerLinkedHashSet);   //[11, 21, 31, 41, 51, 61]
    }
}

6. TreeSet集合

1. TreeSet集合概述:底层数据结构是二叉树,元素唯一,且能对元素进行排序
在这里插入图片描述
2. 对TreeSet的排序的两种方法
(1)自然排序:当你使用空参构造是,使用的就是自然排序。要求元素实现Comparable这个接口并重写compareTo()方法,根据比较的方法返回值的正负0,来决定元素在二叉树中放置的位置

//基本类型默认重写Comparable接口
public class TestDemo01 {
    public static void main(String[] args) {
        /**
         * Integer类实现了Comparable这个接口,重写了 compareTo
         *          public int compareTo (Integer anotherInteger){
         *             return compare(this.value, anotherInteger.value);
         *         }
         */
        TreeSet<Integer> integerTreeSet = new TreeSet<>();
        integerTreeSet.add(20);
        integerTreeSet.add(18);
        integerTreeSet.add(23);
        integerTreeSet.add(22);
        integerTreeSet.add(17);
        integerTreeSet.add(24);
        integerTreeSet.add(19);
        integerTreeSet.add(18);
        integerTreeSet.add(24);

        System.out.println(integerTreeSet);   //[17, 18, 19, 20, 22, 23, 24]
    }
}

========================================================================

//引用类型要自己手动重写Comparable接口
public class TestDemo02 {
    public static void main(String[] args) {
        TreeSet<Student> studentTreeSet = new TreeSet<>();
        studentTreeSet.add(new Student("vn",23));
        studentTreeSet.add(new Student("tf",25));
        studentTreeSet.add(new Student("ag",24));
        studentTreeSet.add(new Student("ez",27));

        for (Student student : studentTreeSet) {
            System.out.println(student.getName()+"==="+student.getAge());
        }

        /**
         * vn===23
         * ag===24
         * tf===25
         * ez===27
         */
    }
}

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 int compareTo(Student s) {
        //先按照年龄大小来排序
        //this.xx - s.xx  从小到大排序
        int num = this.age - s.age;
        //年龄大小相同,并不能说明是同一个对象,还得比较名字是否相同
        int num2 = num==0 ? this.name.compareTo(s.name) : num;

        //从小到大排
        return num2;
    }
}

(2)比较器排序:TreeSet(Comparator < ? super E > comparator):构造一个新的空 TreeSet,它根据指定比较器进行排序

public class TestDemo03 {
    public static void main(String[] args) {
        TreeSet<Integer> integerTreeSet = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //前-后:从小到大排序
                return o1 - o2;
            }
        });

        integerTreeSet.add(11);
        integerTreeSet.add(22);
        integerTreeSet.add(33);
        integerTreeSet.add(11);
        integerTreeSet.add(4);
        integerTreeSet.add(66);

        System.out.println(integerTreeSet);   //[4, 11, 22, 33, 66]

    }
}

======================================================================

//使用比较器,按照年龄大小来排序
public class TestDemo01 {
    public static void main(String[] args) {
        TreeSet<Student> studentTreeSet = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //比较年龄
                int num1 = o1.getAge() - o2.getAge();
                //如果年龄一样并不能说明是同一个对象,还要比较姓名是否一样
                int num2 = num1==0 ? o1.getName().compareTo(o2.getName()) : num1;

                return num2;
            }
        });
        studentTreeSet.add(new Student("ez",24));
        studentTreeSet.add(new Student("tf",25));
        studentTreeSet.add(new Student("tf",55));
        studentTreeSet.add(new Student("noc",27));
        studentTreeSet.add(new Student("vn",33));
        studentTreeSet.add(new Student("vn",33));

        for (Student student : studentTreeSet) {
            System.out.println(student.getName() + "===" + student.getAge());
        }
        /**
        ez===24
		tf===25
		noc===27
		vn===33
		tf===55
        */
    }
}

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

3. Comparator比较器
(1)Comparator比较器不光是TreeSet能用,其他的有些类也能使用
(2)比如Collection.sort()或者Arrays.sort()。可以将Comparator传递给sort()方法

public class TestDemo02 {
    public static void main(String[] args) {
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(11);
        integers.add(33);
        integers.add(44);
        integers.add(22);
        integers.add(66);
        integers.add(55);

        integers.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //从小到大
                return o1 - o2;
            }
        });

        System.out.println(integers);   //[11, 22, 33, 44, 55, 66]

        System.out.println("===========================================");

        int[] arr = {66,54,123,865,34,63};
        //默认从小到大排序
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));   //[34, 54, 63, 66, 123, 865]

        Integer[] arr2 = {66,54,123,865,34,63};
        Arrays.sort(arr2, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //从大到小排列
                return o2 - o1;
            }
        });
        System.out.println(Arrays.toString(arr2));   //[865, 123, 66, 63, 54, 34]
    }
}

4. TreeSet集合的两个练习
(1)编写一个程序,获取10个1至20的随机数,要求随机数不能重复

//编写一个程序,获取10个1至20的随机数,要求随机数不能重复
public class TestDemo01 {
    public static void main(String[] args) {
        Random r = new Random();
        TreeSet<Integer> integerTreeSet = new TreeSet<>();
        for (int i = 0; i < 10; i++) {
            int num = r.nextInt(20) + 1;
            integerTreeSet.add(num);
        }
        System.out.println(integerTreeSet);   //[1, 2, 3, 6, 9, 12, 13, 18, 19]
    }
}

(2)键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

//键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
public class TestDemo02 {
    public static void main(String[] args) {
        TreeSet<Student> studentTreeSet = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int num1 = o1.sumNum() - o2.sumNum();
                int num2 = num1 == 0 ? o1.getName().compareTo(o1.getName()) : num1;
                //带负号:从高到低
                return -num2;
            }
        });

        for (int i = 1; i < 4; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第" + i +"个学生的姓名");
            String s = sc.nextLine();
            System.out.println("请输入第" + i +"个学生的语文成绩");
            int yw = sc.nextInt();
            System.out.println("请输入第" + i +"个学生的数学成绩");
            int sx = sc.nextInt();
            System.out.println("请输入第" + i +"个学生的英语成绩");
            int yy = sc.nextInt();

            Student student = new Student(s, yw, sx, yy);
            studentTreeSet.add(student);
        }

        int i = 1;
        for (Student student : studentTreeSet) {
            System.out.println("第" + i++ +"个学生的姓名:" + student.getName() + ",总分是:" + student.sumNum());
        }
    }
}

class Student{
    private String name;
    private int chineseNum;
    private int mathNum;
    private int englishNum;

    public Student() {
    }

    public Student(String name, int chineseNum, int mathNum, int englishNum) {
        this.name = name;
        this.chineseNum = chineseNum;
        this.mathNum = mathNum;
        this.englishNum = englishNum;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getChineseNum() {
        return chineseNum;
    }

    public void setChineseNum(int chineseNum) {
        this.chineseNum = chineseNum;
    }

    public int getMathNum() {
        return mathNum;
    }

    public void setMathNum(int mathNum) {
        this.mathNum = mathNum;
    }

    public int getEnglishNum() {
        return englishNum;
    }

    public void setEnglishNum(int englishNum) {
        this.englishNum = englishNum;
    }

    public int sumNum(){
        return chineseNum + mathNum + englishNum;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值