Java-Collection集合下List、Set其常用实现类讲解

前言

  • Java集合分为两种Map集合和Collection集合,本次讲解的为Collection集合
  • Collection集合又分为Set集合和List集合
    • set集合:无序,不重复的集合
    • List集合:有序,可重复的集合

注意:

  1. 如果是在数组里面存入自创对象,那么这个对象要尽量重写equals()方法

**原因:**数组在进行查询时,删除等操作的时候,是根据存放的元素的equals方法来判断的,

如果没有重写equals()方法,那么执行的就是Object类里面的方法,使用的为[==]号来判断,比较的为对象在内存中的地址

执行完毕后,很可能达不到预期的结果,下方没有举例,可以自行测试。

  1. 如果使用Set集合存放自创对象,那么这个对象要重写equals()和hashCode()两个方法

**原因:**Set集合在进行添加的时候,会先调用元素的hashCode()方法,然后把得到的值经过某种计算,得出来的值就是要存放的位置。

  • 如果这个位置有元素了,那么再调用当前元素的equals()方法去比较存在的元素
    • 如果方法返回值为true,则相同,那么就不会添加这个元素
    • 如果这个方法返回值为false,则不相同,那么就会把新增的元素放到已存在元素的下一位(next)上
  • 如果这个位置没有元素,则会把元素放到这个位置上

在这里插入图片描述

1、Collection

下面所有集合都继承于它,所以它的方法可以共用的,所以先讲它的方法

  • 集合可以存放任意类型的数据,不像数组一样,只能存放一种类型的数据
  • 集合可以不用指定数据个数,数组创建出来需要指定个数,一旦定死,不能再多了

1.1、增加

add(Object o):添加一个数据

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args){
        Collection list = new ArrayList<>();

        list.add(123); // int类型
        list.add("张三"); // Strig类型
        list.add(true); // boolean 类型
        list.add(new User("李四",20)); // Object类型

        System.out.println(list); // [123, 张三, true, User{name='李四', age=20}]
    }
}

addAll(Collection c):把参数集合添加到当前集合里,成功返回true,反之为false

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args){
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        System.out.println(list); // [123, 张三, true, User{name='李四', age=20}]

        Collection list2 = new ArrayList<>();
        list2.add("后面都是我小弟");

        boolean b = list2.addAll(list);
        System.out.println(b); // true
        System.out.println(list2); // [后面都是我小弟, 123, 张三, true, User{name='李四', age=20}]
    }
}

1.2、删除

remove():删除指定元素,成功返回true,反之为false

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        list.remove(123);
        System.out.println(list); // [张三, true, User{name='李四', age=20}]
    }
}

removeAll(Colloection o):删除参数集合与自己集合所拥有的相同元素,成功返回true,反之为false

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        Collection list2 = new ArrayList<>();
        list2.add("张三");

        boolean b = list.removeAll(list2);
        System.out.println(b); // true
        System.out.println(list); // [123, true, User{name='李四', age=20}]


    }
}

clear():清空集合

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        list.clear();

        System.out.println(list); // []
    }
}

1.3、修改

暂无

1.4、查询

contains(Object o):返回布尔值,判断集合是否包含指定元素

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        boolean contains = list.contains(123);
        System.out.println(contains); // true

        boolean contains2 = list.contains(321);

        System.out.println(contains2); // false

    }
}

containsAll(Collection c):返回布尔值,判断集合是否包含参数集合内的所有元素

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        Collection list2 = new ArrayList<>();
        list2.add("张三");
        list2.add(123);

        System.out.println(list.containsAll(list2)); // true

    }
}

1.5、遍历

遍历使用普通的for循环或者增强for循环都可以遍历,这里使用iterator迭代器进行遍历

iterator只能用做遍历集合使用,常用的方法有两个:

  • hasNext():返回布尔值,判断是否还有下一个
  • next():指针往下移动一位,并返回当前指针指向的结果
  • remove():删除指针当前指向的这一位,这里就不进行演示了

两个方法常搭配while()循环使用

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        Iterator iterator = list.iterator();

        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }

    }
}

结果

在这里插入图片描述

1.6、其他

(1)、retainAll()

上面提到了removeAll方法,参数为集合,表示为移除与参数集合里面相同的元素,这个方法恰恰相反,

只保留与参数集合里面相同的元素。

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        Collection list2 = new ArrayList<>();
        list2.add(123);

        list.retainAll(list2);

        System.out.println(list); // [123]
    }
}
(2)、size()

返回集合的长度

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        System.out.println(list.size()); // 4
    }
}
(3)、toArray()

将集合转为数组返回

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        Collection list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四", 20));

        Object[] objects = list.toArray();

        for (Object object : objects) {
            System.out.println(object);
        }
    }
}

结果
在这里插入图片描述

2、List

List存放的是一组有序的,可重复的集合

特点:

  • 正常一个一个存入数组中,有下标概念,可以使用数组下标进行一些特有的操作

2.1、ArrayList(常用)

ArrayList集合,底层其实也是用数组实现的,只不过底层帮我们做了自动扩容等处理。

进行查询,修改操作性能要好,对于删除,在指定位置新增数据性能要差,因为删除前面的一条数据后,后面的数据要一个一个往前移动一位,新增则是往后移动一位,性能要差。

因为List集合继承了Collection集合,所以Collection有的方法ArrayList也有,就不再进行讲解演示,这里只演示使用下标进行特有操作的方法

数据结构图

在这里插入图片描述

2.1.1、添加

add(int index, Object o):可以在指定下标上添加元素,下标默认从0开始

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        System.out.println(list); // [123, 张三, true, User{name='李四', age=20}]

        list.add(1,"王五");
        System.out.println(list); // [123, 王五, 张三, true, User{name='李四', age=20}]

    }
}

addAll(int index, Collection c):可以在指定下标上添加参数集合内的元素

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        System.out.println(list); // [123, 张三, true, User{name='李四', age=20}]

        ArrayList list2 = new ArrayList<>();
        list2.add("王五");
        list2.add("赵六");
        list2.add("田七");

        list.addAll(1,list2);
        System.out.println(list); // [123, 王五, 赵六, 田七, 张三, true, User{name='李四', age=20}]

    }
}
2.1.2、删除

remove(int index):移除指定下标的元素

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        System.out.println(list); // [123, 张三, true, User{name='李四', age=20}]

        list.remove(0);
        System.out.println(list); // [张三, true, User{name='李四', age=20}]
    }
}
2.1.3、修改

set(int index, Object o):修改指定下标位置的元素

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        System.out.println(list); // [123, 张三, true, User{name='李四', age=20}]

        list.set(0,234);
        System.out.println(list); // [234, 张三, true, User{name='李四', age=20}]

    }
}
2.1.4、查询

除了Collection的contains方法,List还提供了get(int index):根据下标获取元素的方法

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        Object o = list.get(0);
        System.out.println(o); // 123
    }
}

indexOf(Object o):获取指定元素首次出现位置的下标值,如果不存在则返回-1

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        int i = list.indexOf(true);
        System.out.println(i); // 2

        System.out.println(list.indexOf("王五")); // -1
    }
}

lastIndexOf(Object o): 获取指定元素最后一次添加的下标值(因为List可以存放重复的数据),如果不存在则返回-1

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));
        list.add(123);

        int i = list.lastIndexOf(123);
        System.out.println(i); // 4

    }
}
2.1.5、其他
(1)、subList

subList(int formIndex, int toIndex):截取指定索引范围内的元素**(左闭右开原则)**

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("李四",20));

        List list1 = list.subList(1, 3);
        System.out.println(list1); // [张三, true]
    }
}

(2)、isEmpty

判断集合长度是否为0,放回布尔值,如果为0则返回true,反之为false,并不能判断集合是否为null

package com.tcc.test;


import com.tcc.entity.User;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();

        boolean empty = list.isEmpty();
        System.out.println(empty); // true

        list.add(123);
        System.out.println(list.isEmpty());// false

        list = null;
        System.out.println(list.isEmpty()); // Exception in thread "main" java.lang.NullPointerException
    }
}
2.1.6、源码查看
(1)、ArrayList使用什么存储数据的,默认大小是多少
  1. ArrayList是使用数组来进行存储的

在这里插入图片描述

  1. JDK7之前,默认大小为10,JDK8默认为{},直到进行新增操作是,才默认赋初始值10

创建时


在这里插入图片描述

新增时


在这里插入图片描述

(2)、自动扩容机制是怎么进行的
  1. 首先进行的就是上面的先判断elementData是否为初始值,如果为初始值,则把容量提升为10
  2. 然后对提升后的容量进行处理

在这里插入图片描述

2.2、LinkedList

使用链表形式存入数据

LinkedListArrayList恰恰相反,进行查询操作性能要差,但是进行删除和指定位置新增性能要好,因为数据结构原因,所以后面数据不需要做任何操作。

数据结构图

在这里插入图片描述

ArrayList有的方法它基本也都有,它也有自己一些独特的方法

2.2.1、添加(offer/offerFirst/offerLast)

offer(Object o):将指定的元素添加为此列表的尾部(最后一个元素),就是add()方法

push(Object o):将自定的元素添加到此列表的头部,调用了addFirst()方法,和这个方法一样,没有返回值

offerFirst(Object o):在集合的最前面插入指定元素,调用了addFirst()方法,但是添加了布尔类型的返回值

offerLast:在集合的最后面插入指定元素,调用了addLast()方法,但是添加了布尔类型的返回值

package com.tcc.test;


import java.util.LinkedList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        LinkedList list = new LinkedList();

        list.add(123);
        list.add("张三");
        list.add(true);

        list.offerFirst(111);
        list.offer(333);
        list.offerLast(222);

        System.out.println(list); // [111, 123, 张三, true, 333, 222]

    }
}
2.2.2、查询(peek/peekFirst/peekLast)

peek(): 查询但不删除此列表的第一个元素,如果此列表为空,则返回 null

peekFirst():查询但不删除此列表的第一个元素,如果此列表为空,则返回 null (和peek方法一模一样)。

peekLast():查询但不删除此列表的最后一个元素,如果此列表为空,则返回 null

package com.tcc.test;


import java.util.LinkedList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        LinkedList list = new LinkedList();

        list.add(123);
        list.add("张三");
        list.add(true);

        System.out.println(list.peek()); // 123
        System.out.println(list.peekFirst()); // 123
        System.out.println(list.peekLast()); // true

    }
}
2.2.3、删除

第一类:如果要删除的链表为null(集合没有内容),则抛出NoSuchElementException异常

remove():调用了removeFirst()方法,并返回被删除的元素

removeFirst():删除集合中第一个元素,并返回被删除的元素

removeLast():删除集合中最后一个元素,并返回被删除的元素

package com.tcc.test;


import com.tcc.entity.User;

import java.util.LinkedList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        LinkedList list = new LinkedList();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("张三",20));

        Object o1 = list.remove();
        System.out.println(o1); // 123

        Object o2 = list.removeFirst();
        System.out.println(o2); // 张三

        Object o3 = list.removeLast();
        System.out.println(o3); // User{name='张三', age=20}

        System.out.println(list); // [true]

    }
}

第二类:如果要查询并删除的链表为null(集合没有内容),则返回null,不抛出异常

pop():调用了removeFirst()方法,并返回被删除的元素

pollFirst():删除集合中第一个元素,并返回被删除的元素(如果为null则返回null)

pollLast():删除集合中最后一个元素,并返回被删除的元素()

package com.tcc.test;


import com.tcc.entity.User;

import java.util.LinkedList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        LinkedList list = new LinkedList();

        list.add(123);
        list.add("张三");
        list.add(true);
        list.add(new User("张三",20));

        Object o1 = list.pop();
        System.out.println(o1); // 123

        Object o2 = list.pollFirst();
        System.out.println(o2); // 张三

        Object o3 = list.pollLast();
        System.out.println(o3); // User{name='张三', age=20}

        System.out.println(list); // [true]

    }
}

两类同时测试,进行比较

package com.tcc.test;


import com.tcc.entity.User;

import java.util.LinkedList;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        LinkedList list = new LinkedList();

        // 第二类
//        Object p1 = list.pop();
//        System.out.println(p1); // 因为调用的是removeFirst方法,所以也会抛出NoSuchElementException异常

        Object p2 = list.pollFirst();
        System.out.println(p2); // null

        Object p3 = list.pollLast();
        System.out.println(p3); // null

        // 第一类
//        Object o1 = list.remove();
//        System.out.println(o1); // 因为调用的是removeFirst方法,所以也会抛出NoSuchElementException异常

//        Object o2 = list.removeFirst();
//        System.out.println(o2); // 会抛出NoSuchElementException异常

//        Object o3 = list.removeLast();
//        System.out.println(o3); // 会抛出NoSuchElementException异常

        System.out.println(list); // []

    }
}

2.3、Vector

最古老的一个集合,Java1.0出现的,是线程安全的一个集合,但是现在基本不使用了,有其他更好的方式,这里也就不进行讲解了

在这里插入图片描述

在这里插入图片描述

3、Set

Set集合存放的是一组无序的,不可重复的集合

Set集合没有下标概念,所以方法基本都是Collection的方法,除了特殊方法,其余方法就不进行演示

使用Set集合的时候,要对集合存放的对象重写hashCode()和equals()方法,原因前言里面有

重写hashCode()方法的基本原则

  • 在程序运行时,同一个对象多次调用hashCode()方法返回值应该相同
  • 当两个对象的equals()方法比较返回true时,这两个对象的hashCode()方法的返回值也应相等
  • 对象中作equals()方法比较的属性(Field),都应该用来计算hashCode

3.1、HashSet(常用)

作为Set接口的主要实现类,线程不安全的,可以存储null值

没有特殊方法,展示一下非重无序

普通元素


package com.tcc.test;

import java.util.HashSet;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        HashSet set = new HashSet();
        set.add(123);
        set.add("张三");
        set.add(true);
        set.add(123);

        System.out.println(set); // [张三, 123, true]

    }
}

没有重写hashCode和equals方法的元素


package com.tcc.test;

import com.tcc.entity.User;

import java.util.HashSet;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        HashSet set = new HashSet();
        set.add(123);
        set.add("张三");
        set.add(true);
        set.add(new User("张三",22));
        set.add(new User("张三",22));

        System.out.println(set); // [张三, User{name='张三', age=22}, 123, User{name='张三', age=22}, true]

    }
}

重写了hashCode和equals方法的元素


package com.tcc.test;

import com.tcc.entity.User;

import java.util.HashSet;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        HashSet set = new HashSet();
        set.add(123);
        set.add("张三");
        set.add(true);
        set.add(new User("张三",22));
        set.add(new User("张三",22));

        System.out.println(set); // [张三, User{name1='张三', age1=22}, 123, true]

    }
}

3.2、LinkedSet

作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历

package com.tcc.test;

import com.tcc.entity.User;

import java.util.LinkedHashSet;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        LinkedHashSet set = new LinkedHashSet<>();
        set.add(new User("张三",22));
        set.add(123);
        set.add("张三");
        set.add(true);

        System.out.println(set); // [User{name='张三', age=22}, 123, 张三, true]
    }
}

3.3、TreeSet

可以按照添加对象的指定顺序,进行排序

TreeSet和后面写的TreeMap采用红黑树的存储结构

特点:有序,查询速度比List快

3.3.1、自然排序(实现Comparable接口)

比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()

注意

  • 如果使用自然排序,必须实现Comparable接口,否则会异常
  • 不能在TreeSet里面添加不同类的对象
  • 如果比较值相同则只显示一条数据

基本包装类型


package com.tcc.test;

import java.util.TreeSet;

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        TreeSet set = new TreeSet<>();
        set.add(456);
        set.add(123);
        set.add(234);

        System.out.println(set); // [123, 234, 456]
    }
}

自写类


  1. 重写compareTo方法(只写一种即可)

    // 按姓名从小到大排序
    @Override
    public int compareTo(Object o) {
        if (o instanceof User){
            User user = (User)o;
            // 调用的是String方法的compareTo方法,比较的是ASCII码值
            return this.name.compareTo(user.name);
        }
        return 0;
    }
    
    // 按年龄从小到大排序
    @Override
    public int compareTo(Object o) {
        if (o instanceof User){
            User user = (User)o;
            // 调用的是String方法的compareTo方法
            return this.age.compareTo(user.age);
        }
        return 0;
    }
    
  2. 按照姓名测试

    package com.tcc.test;
    
    import com.tcc.entity.User;
    
    import java.util.TreeSet;
    
    /**
     * @author 宇辰
     * @date 2022/8/31-8:53
     **/
    public class Test{
        public static void main(String[] args) {
            TreeSet set = new TreeSet<>();
            set.add(new User("zsy",24));
            set.add(new User("tom",22));
            set.add(new User("asc",23));
            set.add(new User("asc",24));
    
            System.out.println(set); // [User{name='asc', age=23}, User{name='tom', age=22}, User{name='zsy', age=24}]
    
        }
    }
    
  3. 按照年龄测试

    package com.tcc.test;
    
    import com.tcc.entity.User;
    
    import java.util.TreeSet;
    
    /**
     * @author 宇辰
     * @date 2022/8/31-8:53
     **/
    public class Test{
        public static void main(String[] args) {
            TreeSet set = new TreeSet<>();
            set.add(new User("zsy",24));
            set.add(new User("tom",22));
            set.add(new User("asc",23));
            set.add(new User("asc",24));
    
            System.out.println(set); // [User{name='tom', age=22}, User{name='asc', age=23}, User{name='zsy', age=24}]
    
        }
    }
    
3.3.2、定制排序(Comparator)

比较两个对象是否相同的标准为:compare()返回0,不再是equals()

package com.tcc.test;

import com.tcc.entity.User;

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

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {
        // 创建接口的实现类,当做参数传入TreeSet中
        Comparator<Object> com = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof User && o2 instanceof User){
                    User u1 = (User)o1;
                    User u2 = (User)o2;
                    return Integer.compare(u1.getAge(),u2.getAge());
                }
                return 0;
            }
        };

        TreeSet set = new TreeSet<>(com);
        set.add(new User("zsy",24));
        set.add(new User("tom",22));
        set.add(new User("asc",23));
        set.add(new User("asc",24));

        System.out.println(set); // [User{name='tom', age=22}, User{name='asc', age=23}, User{name='zsy', age=24}]

    }
}
3.3.3定制排序拓展(lamdba)
  1. 因为Comparator接口里面只有一个方法需要实现,所以这种接口成为函数式接口,可以使用lamdba表达式

  2. 也可以查看接口上的注解,一般有@FunctionalInterface这个注解的,就代表这个接口只有一个方法需要实现,可以使用lamdba表达式

    在这里插入图片描述

package com.tcc.test;

import com.tcc.entity.User;

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

/**
 * @author 宇辰
 * @date 2022/8/31-8:53
 **/
public class Test{
    public static void main(String[] args) {

        // = 后面的内容可以拿变量接收,也可以直接放入TreeSet构造函数的参数中
        Comparator com = (Object o1,Object o2) -> {
            if (o1 instanceof User && o2 instanceof User){
                User u1 = (User)o1;
                User u2 = (User)o2;
                return Integer.compare(u1.getAge(),u2.getAge());
            }
            return 0;
        };

        TreeSet set = new TreeSet<>(com);
        set.add(new User("zsy",24));
        set.add(new User("tom",22));
        set.add(new User("asc",23));
        set.add(new User("asc",24));

        System.out.println(set); // [User{name='tom', age=22}, User{name='asc', age=23}, User{name='zsy', age=24}]

    }
}

3.4、源码查看

  • LinkedSet继承于HashSet所以都使用的是后者的add方法
  • 从下面可以看出,Set集合底层基本都是使用的Map集合的方法,所以Map集合底层源码才是主要的

构造方法

从构造方法可以看出,HashSet底层是使用的HashMap集合


在这里插入图片描述

添加方法

添加方法,就是把参数值,当做Map集合的Key,它的Value就是一个空对象


在这里插入图片描述

删除方法

删除方法就是调用Map集合的remove方法,根据Key删除存放在Map集合里的元素


在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值