集合框架——List、Set接口

一、List接口

        List是Collection下面的一个子接口。        

       1、  List满足3个特点:

        1. 有序(有序不是顺序, 有序指的是怎么存,就怎么取)

        2. 有索引(可以根据索引获取元素)

        3. 可以重复(List下面的集合可以存放重复的元素)

        List是一个接口,如果要用,需要使用实现类,最常用的实现类是ArrayList。

public class Demo01List {

    public static void main(String[] args) {

        //创建一个List集合对象

        List<String> list = new ArrayList<>();

        //向集合中添加元素

        list.add("张三");

        list.add("李四");

        list.add("王叔叔");

        //打印集合

        //1. 有序

        System.out.println(list);

 

        //2. 有索引

        String value = list.get(1);

        System.out.println(value);

 

        //3. 可以重复

        list.add("王叔叔");

        System.out.println(list);

 

    }

}

    2、list集合中的方法

            List是Collection的子接口,所以List接口除了拥有Collection中所有的方法外,还有一些自己的方                法,  这些自己的方法支持对索引的操作。

    常见方法:

        void add(int index, E element): 向集合的指定位置添加元素。

        (重要)E get(int index):根据索引获取元素

        E remove(int index): 根据索引删除元素。 返回被删除的元素.

        E set(int index, E element): 替换指定索引位置的元素。

public class Demo02ListMethod {

    public static void main(String[] args) {

        method4();

    }

 

    //E set(int index, E element): 替换指定索引位置的元素。 返回值为被替换的元素

    public static void method4() {

        //创建一个集合

        List<String> list = new ArrayList<>();

        //添加元素

        list.add("hello");

        list.add("world");

        list.add("java");

 

        //使用php替换掉集合中索引为2的元素

        String str = list.set(2, "php");

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

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

    }

 

    //E remove(int index): 根据索引删除元素。 返回被删除的元素.

    public static void method3() {

        //创建一个集合

        List<String> list = new ArrayList<>();

        //添加元素

        list.add("hello");

        list.add("world");

        list.add("java");

 

        //删除索引为1的元素

        String str = list.remove(1);

        System.out.println("list:" + list); //[hello, java]

        System.out.println("str:" + str); //world

    }

 

    //E get(int index):根据索引获取元素

    public static void method2() {

        //创建一个集合

        List<String> list = new ArrayList<>();

        //添加元素

        list.add("hello");

        list.add("world");

        list.add("java");

        //根据索引获取元素

        System.out.println(list.get(1));

    }

 

    //void add(int index, E element): 向集合的指定位置添加元素。

    public static void method1() {

        //创建一个List集合

        List<String> list = new ArrayList<>();

        //添加元素

        list.add("hello");

        list.add("world");

        list.add("java");

        System.out.println("list:" + list); //[hello, world, java]

 

        //在索引为1的位置添加元素 php

        list.add(1, "php");

        System.out.println("list:" + list); //[hello, php, world, java]

    }

}

 

 

    3、ArrayList集合及其特点

        (1)ArrayList集合的特点。

        ArrayList是List接口的一个实现类,并且这个集合内部在使用数组这种数据结构去存储数据。

        ArrayList的特点是: 增删慢, 查询

       (2)LinkedList集合

            LinkedList集合也是List接口的实现类。

    LinkedList内部是一个链表(双向链表)

    LinkedList 的特点: 增删快,查找慢

    LinkedList中有一些【特有】的方法, 支持对首尾进行操作。

    void addFirst(E e): 向集合的首个位置添加元素

     void addLast·(E e):向集合尾部添加元素

      E getFirst(): 获取集合首个位置的元素

      E getLast():获取集合尾部的元素

      E removeFirst():删除首个元素。 返回被删除的元素

      E removeLast():删除最后一个元素。 返回被删除的元素

       void push(E e): 压入, 向首个位置添加元素

                E pop(): 弹出,移除第一个元素。

public class Demo02LinkedList {

    public static void main(String[] args) {

        method4();

    }

 

    /*

        void push(E e): 压入, 向首个位置添加元素

        E pop(): 弹出,移除第一个元素。

     */

    public static void method4() {

        //创建一个集合并添加元素

        LinkedList<String> list = new LinkedList<>();

        list.add("爱迪生");

        list.add("达尔文");

        list.add("达芬奇");

        System.out.println("list:" + list); //[爱迪生, 达尔文, 达芬奇]

        //void push(E e): 压入, 向首个位置添加元素

        list.push("牛顿");

        System.out.println("list:" + list); //[牛顿, 爱迪生, 达尔文, 达芬奇]

 

        //E pop(): 弹出,移除第一个元素。

        String str = list.pop();

        System.out.println("list:" + list); //[爱迪生, 达尔文, 达芬奇]

        System.out.println("str:" + str); //牛顿

    }

 

    /*

        E removeFirst():删除首个元素

        E removeLast():删除最后一个元素。

     */

    public static void method3() {

        //创建一个集合并添加元素

        LinkedList<String> list = new LinkedList<>();

        list.add("爱迪生");

        list.add("达尔文");

        list.add("达芬奇");

 

        System.out.println("list:" + list); //[爱迪生, 达尔文, 达芬奇]

 

        //调用 removeFirst() 删除首个元素

        //String str = list.removeFirst();

 

        //删除尾部元素

        String str = list.removeLast();

 

        System.out.println("删除后:" + list); //[爱迪生, 达尔文]

        System.out.println("str:" + str); //达芬奇

    }

 

    /*

        E getFirst(): 获取集合首个位置的元素

        E getLast():获取集合尾部的元素

     */

    public static void method2() {

        //创建一个集合并添加元素

        LinkedList<String> list = new LinkedList<>();

        list.add("爱迪生");

        list.add("达尔文");

        list.add("达芬奇");

 

        //获取集合中首个位置的元素并打印

        System.out.println("首个元素:" + list.getFirst()); //爱迪生

 

        //获取集合中首个位置的元素并打印

        System.out.println("尾部元素:" + list.getLast()); //达芬奇

    }

 

    /*

        void addFirst(E e): 向集合的首个位置添加元素

        void addLast(E e):向集合尾部添加元素

     */

    public static void method1() {

        //创建一个集合

        LinkedList<String> list = new LinkedList<>();

        list.add("爱迪生");

        list.add("达尔文");

        list.add("达芬奇");

 

        //打印list集合

        System.out.println("list:" + list); //[爱迪生, 达尔文, 达芬奇]

        //void addFirst(E e): 向集合的首个位置添加元素

        list.addFirst("牛顿");

        System.out.println("list:" + list); //[牛顿, 爱迪生, 达尔文, 达芬奇]

 

        list.addLast("伽利略");

        System.out.println("list:" + list); //[牛顿, 爱迪生, 达尔文, 达芬奇, 伽利略]

    }

}

 

二、Set接口

 

    1、Set 也是Collection下面的一个子接口。

    Set接口满足一下三个特点:

        1. 无序(怎么存,不一定怎么取)

        2. 没有索引(不能根据索引获取元素)

        3. 不可重复.

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

public class Demo01Set {

    public static void main(String[] args) {

        //创建一个Set集合

        Set<String> set = new HashSet<>();

        //向集合中添加元素

        set.add("张三");

        set.add("李四");

        set.add("王叔叔");

 

        //打印Set集合

        //1. 无序(怎么存,不一定怎么取)

        System.out.println(set); //[李四, 张三, 王叔叔]

 

        //2. 没有索引(不能根据索引获取元素)

        //set.get(1);

 

        //3. 不可重复.

        set.add("王叔叔");

        set.add("王叔叔");

        set.add("王叔叔");

        set.add("王叔叔");

 

        System.out.println(set);

    }

}

    2、Hashset接口

        HashSet是Set接口下的实现类,它满足Set接口的所有特点。

        1. 无序

        2. 无索引

        3. 不可重复

    如何对Set集合进行遍历?

        1. 迭代器

        2. 增强for(推荐)

 

public class Demo02HashSet {

    public static void main(String[] args) {

        //创建一个Set集合,并遍历

        Set<String> set = new HashSet<>();

        //往集合中添加元素

        set.add("张三丰");

        set.add("宋远桥");

        set.add("尹丽婷");

        set.add("张翠山");

 

        //使用迭代器遍历这个Set集合.

        //获取集合的迭代器

        Iterator<String> iterator = set.iterator();

        //循环获取

        while (iterator.hasNext()) {

            String value = iterator.next();

            System.out.println(value);

        }

 

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

 

        for(String str : set) {

            System.out.println(str);

        }

    }

}

 

3、HashCode

1、哈希值

    哈希值其实就是一个int数字, 我们可以把哈希值看成对象的一个标识,特征码。

    在Object中,有一个方法,叫做hashCode,可以获取到对象的哈希值。

    Object中的hashCode方法,哈希值是根据地址值进行计算的。

    一般来说哈希值的计算方式不会根据地址值进行计算,而是根据对象的属性进行计算。

    如果两个对象的属性完全相同,那么这两个对象的哈希值也应该相同。

    如果想要自己定义哈希值的计算方式,那么我们需要在子类中重写hashCode方法。

    哈希值是对象的一个特征码,但是哈希值并不是唯一的特征码, 对象的哈希值是允许重复的。

    总结:

        1. 哈希值就是对象的特征码

        2. 我们可以通过hashCode方法来获取对象的哈希值

        3. 如果希望自己定义哈希值的生成规则,那么我们可以在子类中重写hashCode方法。

        4. 哈希值的计算方式一般是根据属性计算,属性相同得到的哈希值也一定相同。

public class Demo01HashCode {

    public static void main(String[] args) {

        //创建一个Person对象

        Person p = new Person("刘德华", 18);

        System.out.println(p.hashCode());

        System.out.println(new Person("刘德华", 18).hashCode());

        System.out.println(new Person("刘德华", 18).hashCode());

        System.out.println(new Person("刘德华", 19).hashCode());

        System.out.println(new Person("刘德华", 19).hashCode());

        System.out.println(new Person("刘德华", 19).hashCode());

 

        System.out.println("刘德华".hashCode()); //20977295

    }

}

  2、使用HashSet存储自定义对象,并且要保证元素的唯一性。

    如果两个对象的属性完全相同,那么就当成是同一个对象。

    HashSet如何判断唯一性?

        1. 先比较两个对象的哈希值(通过hashCode方法得到哈希值比较)

            如果两个对象的哈希值不同,那么肯定是不同的对象。

            如果两个对象的哈希值相同,那么不一定是同一个对象。

        2. 如果两个对象的哈希值相同,还要调用equals方法进行比较。

            如果equals得到的结果是true,表示这两个对象是同一个对象

            如果equals方法的到的结果是false,表示这两个对象不是同一个对象。

     总结: 如果使用HashSet保存自定义对象看,那么如果要保证唯一性(如果属性完全相同,那么就是同一个对象)

           此时需要重写hashCode和equals

public class Demo02HashSet {

    public static void main(String[] args) {

        //创建一个HashSet,用来保存Dog对象

        Set<Dog> set = new HashSet<>();

        //向set集合中添加一些狗对象

        set.add(new Dog("哮天犬", 18));

        set.add(new Dog("旺财", 8));

        set.add(new Dog("王可可", 3));

        //添加一个狗对象

        set.add(new Dog("旺财", 8));

        //遍历set集合,并打印每一个狗对象

        for(Dog dog : set) {

            System.out.println(dog);

        }

    }

}

 

 

3、LinkedHashSet是Set接口的一个实现类。

    内部除了有一个哈希表之外还有一个链表。

    链表的作用是保证有序、

    Set是无序的,但是它不能保证所有的实现类都是无序的。

    LinkedHashSet就是有序的。

public class Demo03LinkedHashSet {

    public static void main(String[] args) {

        //创建一个Set集合

        Set<String> set = new LinkedHashSet<>();

        //添加元素

        set.add("张三丰");

        set.add("张翠山");

        set.add("莫声谷");

        set.add("张无忌");

        set.add("宋远桥");

 

        //打印set集合

        System.out.println(set);

    }

}

 

三、可变参数

    可变参数: 指的是方法参数的个数可以随意改变。

    格式:

        修饰符 返回值类型 方法名(参数类型... 参数名) {

            方法体

        }

        a. 可变参数方法在调用的时候,参数可以传递任意个。

        b. 这些参数的数据类型必须要一致

        c. 可变参数本质是数组,所以可以依照数组的形式使用这个可变参数。 在调用可变参数的方法时,可变参数位置也可以传递数组。

    注意事项:

        1. 一个方法中最多只能有1个可变参数。

        2. 可变参数必须在方法的最后一个位置

        3. 可变参数本质是数组,所以不能和数组构成重载

 

public class Demo01Params {

 

    public static void main(String[] args) {

        //求数字 1 2 3 4 5 的和

        int[] arr = {1,2,3,4,5};

        //调用getSum方法,将数组进行传递

        //int sum = getSum(arr);

 

        //可变参数方法在调用的时候,参数可以传递任意个。(0个, 1个或者多个)

        int sum = getSum(1, 2, 3, 4, 5, 6, 7, 8);

 

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

 

 

    }

    /*

    public static void method(int[] a) {

 

    }

 

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

 

    }

    */

    /*

        定义方法,求任意个数字的和

     */

    public static int getSum(int... arr) { // 可变参数本质是数组,所以可以按照数组的方式去使用。

        int sum = 0;

        for(int num : arr) {

            sum += num;

        }

        return sum;

    }

 

    /*

        定义方法,求任意个数字的和

     */

    /*

    public static int getSum(int[] arr) {

        //对参数数组进行求和

        int sum = 0;

        for(int num : arr) {

            sum += num;

        }

        return sum;

    }

    */

}

 

 

四、Collections工具类

 

  1. Collection 是所有单列集合的根接口

  2.     Collections 是操作集合的工具类。

  3.     Collections中常见的方法

  4.         static boolean addAll(Collection c, T... elements): 向集合中批量添加元素。参数c表示集合。参数elements表示要向此集合中添加哪些元素.

  5.         static void shuffle(List list): 对集合中的内容打乱顺序。

  6.         static void sort(List list): 对集合中的内容排序。

  7.         static void sort(List list, Comparator c) : 对集合中的内容排序。

 

public class Demo01Collections {

    public static void main(String[] args) {

        //创建一个集合

        ArrayList<String> list = new ArrayList<>();

        //Collections工具类中的addAll可以直接批量添加

        Collections.addAll(list, "aa", "bb", "cc", "dd");

        //打印集合

        System.out.println(list);

        //static void shuffle(List list): 对集合中的内容打乱顺序。

        Collections.shuffle(list);

 

        System.out.println(list);

    }

}

(1)static void sort(List list): 对集合中的内容排序。

    要使用sort方法排序的集合,里面的泛型类型必须要实现Comparable接口。

    实现这个接口才表示这个类的对象具备了排序的功能。

    这种排序叫做自然排序。

 

public class Demo02Collections {

    public static void main(String[] args) {

        //创建一个集合,保存数字

        ArrayList<Integer> numList = new ArrayList<>();

        //添加

        numList.add(200);

        numList.add(100);

        numList.add(300);

 

        //打印集合

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

 

        Collections.sort(numList);

 

        //打印集合

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

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

 

        //创建一个集合保存字符串

        ArrayList<String> strList = new ArrayList<>();

        //添加元素

        strList.add("bbb");

        strList.add("aaa");

        strList.add("ccc");

 

        //打印集合

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

 

        //对集合中的内容进行排序

        Collections.sort(strList);

 

        //打印集合

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

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

 

        //创建集合,保存Person对象

        ArrayList<Person> list = new ArrayList<>();

        //添加三个Person对象

        list.add(new Person("大幂幂", 18));

        list.add(new Person("柳岩", 16));

        list.add(new Person("金星", 20));

 

        //对这个存放Person的集合进行排序

        Collections.sort(list);

 

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

    }

}

 

(2)static void sort(List list, Comparator c) : 对集合中的内容排序。这种排序方式叫做比较器排序。

    如果某些对象本身并不具备自己排序的功能,那么我们可以去找一个法官帮他们进行比较。这个法官其实就是比较器。

    比较器用的是Comparator 接口。

    自然排序(Comparable): 自然排序,某个类实现了Comparable接口,就表示这个类的对象自己就具备类排序的功能。

    (重点)比较器排序(Comparator): 事物本身自己是并不会排序的,需要借助一个法官去帮他们排序,这个法官就是比较器。

 

public class Demo03Collections {

    public static void main(String[] args) {

        //创建一个集合,保存Student

        ArrayList<Student> list = new ArrayList<>();

        list.add(new Student("柳岩", 18));

        list.add(new Student("大幂幂", 16));

        list.add(new Student("白百合", 20));

 

        //使用比较器排序对集合中的内容进行排序

        Collections.sort(list, new Rule());

 

        //打印结果

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

    }

}

 

(3) 实现Comparable接口需要重写里面的compareTo方法。

        当我们调用Collections的sort方法时,系统内部会通过对象调用compareTo进行比较。

        返回值:

        如果返回值是一个负数,那么表示当前对象小于参数对象

        如果返回值是0,表示这两个对象相等

        如果返回值是正数,表示当前对象大于参数对象。

        升序就是我减他。

        如果要根据年龄排序,那么在这个方法里面拿当前对象的年龄减去参数对象的年龄并返回

 

@Override

    public int compareTo(Person o) {

        return this.getAge() - o.getAge();

//        return o.getAge() - this.getAge();

    }

 

    @Override

    public String toString() {

        return "Person{" +

                "name='" + name + '\'' +

                ", age=" + age +

                '}';

    }

 

    public Person() {

    }

 

    public Person(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;

    }

 

 

}

 

import java.util.Comparator;

/*

    这个类实现了Comparator接口,那么就表示这个类变成了一个比较器类。

    他可以比较两个Student对象谁大谁小。

*/

public class Rule implements Comparator<Student>{

    /*

        这个方法用来比较o1和o2这两个参数对象谁大谁小。

        如果返回值是负数,那么表示o1小于02

        如果返回值是0表示这两个对象相等。

        如果返回值是正数,表示o1大于o2

 

        公式: 升序就是1减2

     */

    @Override

    public int compare(Student o1, Student o2) {

        return o1.getAge() - o2.getAge();

    }

}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值