常见的集合Collections、Set等

一切如你i 码农一号 2022-10-31 17:32:48

Collections

常见方法

 Collections是一个操作集合的工具类。
 static void shuffle(List<?> list):对集合中的内容打乱顺序。
 static void sort(List list):对集合中的元素进行排序(自然排序)
 static void sort(List list, Comparator c):对集合中的内容进行排序,参数c表示比较器(比较器排                                            序)
 static boolean addAll(Collection c, T... elements):批量添加元素。
            参数c:表示向哪个集合添加元素。
            参数elements:表示要添加那些元素。 该参数是可变参数,可以向该参数位置传递任意个数据。

shuffle方法

public class Demo01Collections {
    public static void main(String[] args) {
        //创建集合
        List<String> list = new ArrayList<>();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("php");
        //输出集合
        System.out.println("list:" + list);
        //对集合中的内容打乱顺序
        Collections.shuffle(list);
        //输出集合
        System.out.println("list:" + list);
    }
}

自然排序

Collections中的sort方法
    static void sort(List list):对集合中的元素进行排序(自然排序)
注意:
    使用上面这个sort方法排序的集合,里面的泛型必须要实现Comparable接口。
    如果要进行排序,集合中的元素必须要具备比较的功能,如果类实现Comparable接口,
    那么表示该类的对象就具备了比较的功能。

自然排序指的是事物本身就具备比较的功能,所以我们可以使用上面的sort方法对保存该事物的集合进行排序。

代码

/*
    自然排序的方法:
        static void sort(List list):对集合中的内容进行排序(自然排序)

    要使用上面sort排序的集合,里面的泛型类型必须要拥有比较的功能。
    如果想要让某个类型具备比较的功能,可以让该类实现Comparable接口。
    使用上面sort方法排序的集合,里面的泛型类型必须实现Comparable接口,因为只有实现该接口后,才表示该类型具备了比较的功能。

    如果某个事物本身具备比较的功能,那么我们可以直接对这种事物进行排序,这种排序方式叫做自然排序。

 */
public class Demo02Collections {
    public static void main(String[] args) {
        //创建集合,保存整数
        List<Integer> intList = new ArrayList<>();
        //向集合中添加元素
        intList.add(200);
        intList.add(100);
        intList.add(300);
        //对集合中的内容进行排序
        Collections.sort(intList);
        //输出结果
        System.out.println("intList:" + intList);//[100, 200, 300]
        System.out.println("==================================================");

        //创建集合,保存字符串
        List<String> strList = new ArrayList<>();
        //添加字符串
        strList.add("bbb");
        strList.add("aaa");
        strList.add("ccc");
        //对集合中的内容进行排序
        Collections.sort(strList);
        //输出结果
        System.out.println("strList:" + strList);//[aaa, bbb, ccc]

        //创建集合,保存Person对象,然后进行排序。
        List<Person> personList = new ArrayList<>();
        //向集合中添加Person对象
        personList.add(new Person("张三丰", 20));
        personList.add(new Person("张无忌", 22));
        personList.add(new Person("灭绝师太", 18));
        //对集合中的内容进行排序
        Collections.sort(personList);

        System.out.println("personList:" + personList);

    }
}

Person类

public class Person implements Comparable<Person>{
    private String name;
    private int age;

    /*
        当使用sort方法进行排序(自然排序)时,内部会自动调用compareTo方法比较两个元素的大小。
        如果该方法的返回值是正数,表示调用者对象大于参数对象。
        如果该方法的返回值是0,表示两个对象相等。
        如果该方法的返回值是负数,表示调用者对象小于参数对象。
        我们需要做的是在compareTo方法中编写排序的规则。
        公式:
            升序就是我(调用者)减他(参数)
            要根据什么属性进行排序,就让什么相减。
     */
    @Override
    public int compareTo(Person o) {
        //根据年龄进行升序排序。
        return this.getAge() - o.getAge();
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    get.set.构造方法
}

比较器排序

/*
    比较器排序方法:
        static void sort(List list, Comparator c):对集合中内容排序(比较器排序)。参数list是要排序的集合。参数c表示比较器。


    如果某个事物本身不具备比较的功能,那么我们就不能使用自然排序的方式对集合直接进行排序了。
    如果事物不具备不叫的功能,那么我们可以找一个法官(比较器)帮这些对象去比较,这样集合也可以进行排序。

    Comparator是一个接口,该接口表示比较器,如果要用需要使用实现类,这个实现类需要我们自己定义。

    步骤:
        1. 创建集合并添加元素
        2. 定义一个类,实现Comparator接口。
        3. 重写compare方法,并在该方法中定义比较的规则。
        4. 调用Collections的sort方法,传递集合和比较器进行排序。


    如果事物本身就具备比较的功能,那么我们可以直接使用sort方法进行排序,这种方式叫做自然排序。
    如果事物本身不具备比较的功能,那么我们可以找一个法官帮这些对象进行排序,这种方式叫做比较器排序。

 */
public class Demo03Collections {
    public static void main(String[] args) {
        //创建集合并添加元素
        List<Student> list = new ArrayList<>();
        //添加元素
        list.add(new Student("jack", 20));
        list.add(new Student("rose", 18));
        list.add(new Student("tom", 22));
        //进行排序
        Collections.sort(list, new Rule());
        //输出结果
        System.out.println(list);
    }
}
/*
    Comparator表示比较器,Rule类实现了Comparator接口,Rule类也就表示比较器了
 */
public class Rule implements Comparator<Student>{
    /*
        当调用Collections的sort方法进行比较器排序时,那么系统内部会自动调用compare方法比较两个对象的大小。
        如果该方法返回值是正数,说明第一个参数大于第二个参数。
        如果该方法的返回值是0,说明两个对象相等。
        如果该方法的返回值是负数,说明第一个参数小于第二个参数。
        排序公式:
            升序就是一减二
     */
    @Override
    public int compare(Student o1, Student o2) {
        //根据年龄升序排序
        return o1.getAge() - o2.getAge();
    }
}
public class Student {
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    get.set.构造方法
}

addAll方法

/*
    Collections中批量添加元素的方法
        static boolean addAll(Collection c, T... elements):批量向集合中添加元素。
            参数c:表示向哪个集合中添加元素
            参数elements:是一个可变参数,可以向该参数位置传递任意个数据。 该参数表示要添加的元素。
 */
public class Demo04Collections {
    public static void main(String[] args) {
        //创建集合
        List<String> list = new ArrayList<>();
        //添加元素
        //list.add("hello");
        //list.add("world");
        //list.add("java");

        //使用Collections中的addAll批量添加元素
        Collections.addAll(list, "hello", "world", "java", "php");

        System.out.println(list);

    }
}

可变参数

/*
    JDK5的时候,多了一个新的特性叫做可变参数。
    如果一个方法的参数是可变参数,那么可以在该参数位置传递任意个数据。

    可变参数格式:
        修饰符 返回值类型 方法名(参数类型... 参数名) {
            方法体;
            return 返回值;
        }

        1. 在调用可变参数的方法时,可以向可变参数位置传递任意个数据
        2. 可变参数的本质就是数组,所以可以将可变参数当成数组去使用
        3. 以为可变参数的本质是数组,所以调用可变参数的方法时,也可以向可变参数位置传递数组。

    注意:
        1. 一个方法中最多只能有一个可变参数。
        2. 方法中可变参数必须在最后一个位置。
 */
public class Demo01ChangeParam {
    public static void main(String[] args) {
        //int sum = getSum(1,2,3,4,5);
        //System.out.println(sum);

        int[] arr = {1,2,3};
        int sum = getSum(arr);
        System.out.println(sum);
    }

    public static void method(int a, int... b) {

    }

    /*
        定义方法,求任意个整数的和
     */
    public static int getSum(int... nums) {
        //定义变量sum保存累加和
        int sum = 0;
        //遍历nums,将每一个元素累加到sum
        for (int num : nums) {
            sum += num;
        }
        return sum;
    }


    /*
        定义方法,求任意个整数的和。
        参数:int[]
     */
    /*
    public static int getSum(int[] arr) {
        //定义变量,记录累加和
        int sum = 0;
        //遍历arr数组,拿到数组中的每一个元素并累加到sum上
        for (int num : arr) {
            sum += num;
        }
        //返回结果
        return sum;
    }
    */
}

Set接口

set接口特点

/*
    Set是Collection下面的一个子接口。

    Set接口有以下特点:
        1. 无索引(不能根据索引获取元素的)
        2. 不可重复(不能保存重复元素)
        3. 无序的(大部分Set集合满足的特点)(按照什么顺序存,不一定按照什么顺序取)

    Set是一个接口,如果要用需要使用实现类,Set接口下最常用的实现类是HashSet

    HashSet满足Set接口的所有的特点(无序,无索引,不可重复)

 */
public class Demo01Set {
    public static void main(String[] args) {
        //创建Set集合
        Set<String> set = new HashSet<>();
        //向集合中添加元素
        set.add("张三丰");
        set.add("张无忌");
        set.add("灭绝师太");
        set.add("金花婆婆");
        //输出集合
        //无序
        System.out.println(set);
        //无索引
        //System.out.println(set.get(1));
        //不可重复
        set.add("灭绝师太");
        set.add("灭绝师太");
        set.add("灭绝师太");
        set.add("灭绝师太");
        System.out.println(set);
    }
}

set接口遍历

/*
    Set集合的遍历。

    因为Set集合是没有索引的,所以不能使用普通for遍历,可以使用迭代器或增强for遍历,强烈推荐增强for
 */
public class Demo02Set {
    public static void main(String[] args) {
        //创建Set集合
        Set<String> set = new HashSet<>();
        //添加元素
        set.add("张三丰");
        set.add("张无忌");
        set.add("灭绝师太");
        set.add("金花婆婆");
        //使用增强for遍历集合(和之前增强for遍历一模一样)
        for (String str : set) {
            System.out.println(str);
        }
    }
}

哈希值

/*
    哈希值其实就是一个int数字,我们可以将哈希值看成对象的一个标识(特征码)
    在Object中有一个方法叫做hashCode,可以获取对象的哈希值。
        int hashCode():获取对象的哈希值。

    Object中的hashCode方法,哈希值的计算方式是根据对象的地址值计算的。
    对象的哈希值根据地址值计算一般来说意义不大,我们更多的是希望哈希值是根据属性计算的,如果两个对象的属性完全相同,
    哈希值也应该相同。
    如果想要自己定义哈希值的计算规则,需要重写hashCode方法。
    哈希值是对象的一个标识,但并不是唯一的标识,对象的哈希值允许重复。

 */
public class Demo01HashCode {
    public static void main(String[] args) {
        //创建Person对象
        Person p = new Person("张三丰", 100);
        //获取该对象的哈希值然后输出
        System.out.println(p.hashCode());


        Person p2 = new Person("张三丰", 100);
        System.out.println(p2.hashCode());
    }
}
public class Person {
    private String name;
    private int age;

    //alt + insert 直接生成hashCode方法
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }


    //重写hashCode方法,自己定义哈希值的计算规则
    //根据Person的name和age属性计算哈希值。
    //ctrl + o:重写方法
    /*
    @Override
    public int hashCode() {
        return name.hashCode() * 31 + age;
    }
    */
    /*
        Person p1 = new Person("张三", 10);   3 * 2 + 10 -> 16
        Person p2 = new Person("李四", 9);    4 * 2 + 9 -> 17

        "张三" -> 3
        "李四" -> 4
     */

    get..set.构造方法
}

HashSet保证唯一性练习

/*
    要求:使用HashSet保存学生对象,然后并遍历。
         学生对象要保证唯一性(如果学生的姓名和年龄相同,就看成是同一个学生)

     HashSet判断唯一性的过程
        1.先比较对象的哈希值。
            如果哈希值不同,肯定是不同的对象。
            如果哈希值相同,不一定是同一个对象。
        2. 如果哈希值相同,还会调用equals进行比较。
            如果equals的结果是true,表示对象相同。
            如果equals的结果是false,表示对象不同

     结论:
        如果使用HashSet存储自定义对象并保证唯一性(对象的属性相同就看成是同一个对象),需要同时重写hashCode和equals,缺一不可。
 */
public class Demo01HashSet {
    public static void main(String[] args) {
        //创建HashSet集合
        Set<Student> set = new HashSet<>();
        //添加元素
        set.add(new Student("柳岩", 36));
        set.add(new Student("李小璐", 34));
        set.add(new Student("马蓉", 32));

        set.add(new Student("柳岩", 36));

        //遍历集合,输出集合中的每一个学生对象
        for (Student stu : set) {
            System.out.println(stu);
        }

    }
}
public class Student {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    get..set..构造方法
}

...全文
525 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

7,005

社区成员

发帖
与我相关
我的任务
社区描述
阿丹的社区,分享工作日常,和业务技能点,认真写好每一篇文章,共同探讨,共同进步,成就一亿技术人,欢迎大家加入。
htmljavaidea 个人社区 北京·海淀区
社区管理员
  • 一切如你i
  • scdn_wyy
  • 孙阿哈
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

在这里,你可以:

  1. 看到大家丰富多彩的业务多样性。
  2. 浏览各大网站的精彩推荐和分享。
  3. 得到社区最好的资源。
  4. 参与更好的进行社区运营的交流和互动。

 

欢迎你入住阿丹社区云,开始打造属于你的技术社区。

试试用AI创作助手写篇文章吧