Collection集合和Map集合的知识梳理

Set集合的特点:无序不可重复

HashSet集合:无序不可重复,可以存储 null 对象

A:底层代码是哈希表(动态数组)+链表+红黑树

B:存储自定义对象,需要重写 hashCode() 方法和 equals() 方法

通过 HashSet 存储对象,会根据对象的 hashCode() 生成hash值,根据 hash 生成索引,根据索引找到 hash 表中的位置;判断位置上是否有对象,没有对象直接插入,有对象则通过 equals() 判断内容是否相同,如果相同则不插入,不同则根据链表往下检索,直到重复或者链表没有下一个对象,准备插入最后的时候判断链表是否超过 8 个对象,当链表超过 8 个对象时,总储存的对象大于64则把链表转换成红黑树,当 hash 表总储存的对象大于负载因子值(0.75),则会进行数组的扩容,扩容为原本的 2 倍

TreeSet集合:无序可排序,不可重复,不能存储 null 对象的集合

A:底层代码是红黑树(是一个平衡的二叉树结构)

B:使用 TreeSet 存储对象,对象类要么实现自然排序,要么传递比较器

自然排序:存储进 TreeSet 集合的对象类必须实现 Comparable 接口,重写 comparaTo(),在 ComparaTo() 里制定排序规则,返回正数存储的对象往右子树方向,返回负数存储的对象往左子树方向,返回0则不存储

比较器:在创建TreeSet 集合对象的时候,传递 Comparator 接口的实现类对象,重写 Comparator 接口的 compare() ,在 compare() 里制定排序规则

 总结:TreeSet 和 HashSet 的使用场景具体看题目要求是否需要排序,HashSet性能优于 TreeSet 能够节省内存,需要排序则选择 TreeSet 

 Collection集合的总结:

List:有序,可重复

        ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高

        LinkedList:底层数据结构是链表,查询慢,增删快,线程不安全,效率高

        Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低

Set:无序不重复

        HashSet:底层数据结构是哈希表,依赖 hashCode() 和 equals() 保证元素的唯一性

        TreeSet:底层数据结构是红黑树,使用自然排序或者传递比较器实现元素的排序,根据底层代码比较的返回值是否为 0 来决定元素的唯一性

针对Collection集合我们到底使用谁呢?

唯一吗?

        是:Set

                排序吗?

                        是:TreeSet

                        否:HashSet

如果你知道是 Set,但是不知道是哪个 Set,就用 HashSet

        否:List

                要安全吗?

                        是:Vector

                        否:ArrayList 或者 LinkedList

                                查询多:ArrayList

                                增删多:LinkedList

如果你知道是List,但是不知道是哪个List,就用 ArrayList,如果你知道是Collection集合,但是不知道使用谁,就用 ArrayList,如果你知道用集合,就用 ArrayList

 

Map集合

Map 集合与 Collection 集合在集合框架中属于并列存在,Map 中的元素是两个对象,一个对象为键值,另一个对象为 value 值。键值不可以重复,但是 value 值可以重复,因此 Map 集合可以用来存储多个对象的集合。

常见的方法:添加(map.put())和 删除(map.remove())

HashMap:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Demo01 {
    public static void main(String[] args) {
        HashMap<String,Integer> map = new HashMap<>();
        map.put("zs",20);
        map.put("ls",18);
        map.put("ww",18);
        map.put("z6",22);
        map.put("t7",24);
        map.put("ls",20);
        System.out.println("------KeySet()------")
        //map.keySet() 返回 HashMap 的键值
        Set<String> set = map.keySet();
        //迭代器获取 set 集合的 key
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = it.next();
            Integer value = map.get(key);
            System.out.println(key + ":" + value);
        }
            System.out.println("------entrySet()-------");
            //把Entry存放到Set集合中
            Set<Map.Entry<String, Integer>> set1 = /*把key和value存放到Entry对象中*/map.entrySet();
            //迭代Set集合获取Entry对象
            Iterator<Map.Entry<String, Integer>> it1 = set1.iterator();
            while(it1.hasNext()){
                Map.Entry<String, Integer> entry = it1.next();
                System.out.println(entry.getKey()+":"+entry.getValue());
            }
    }
}
import java.util.HashMap;

public class Demo02 {
    public static void main(String[] args) {
        HashMap<Person, User> map = new HashMap<>();
        map.put(new Person(1),new User(1));
        map.put(new Person(2),new User(2));
        map.put(new Person(1),new User(2));
        map.put(new Person(2),new User(1));
        map.put(new Person(1),new User(1));
        System.out.println(map);
    }
}

//-----------------类分割线------------------

import java.util.Objects;

public class Person {
    private int id;

    public Person(int id) {
        this.id = id;
    }

    public Person() {
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                '}';
    }
}

//--------------------类分割线------------------------

public class User {
    private int id;

    public User() {
    }

    public User(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                '}';
    }
}

遍历出来的结果只有两个对象,并且在Person类id相同的情况下,后添加的会覆盖前面添加的

TreeMap:

import java.util.TreeMap;

public class Demo02 {
    public static void main(String[] args) {
        TreeMap<User,String> map = new TreeMap<>();
        map.put(new User(1),"zs");
        map.put(new User(5),"ls");
        map.put(new User(3),"ww");
        map.put(new User(4),"z6");
        map.put(new User(2),"t7");
        //id从小到大排序
        System.out.println(map);
    }
}

//------------------类分割线------------------

public class User implements Comparable<User>{
    private int id;

    public User() {
    }

    public User(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                '}';
    }

    @Override
    public int compareTo(User user) {
        return this.getId() - user.getId();
    }
}

结论:无论 TreeMap 还是 TreeSet 需要排序则都要通过重写 compareTo(), HashMap 还是 HashSet 需要排序则都要通过重写 hashCode() 和 equals() 方法来实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值