Java集合(重要一万六千字)

学习内容

1.集合其实用起来没有多么的难,但是他难在他的底层原理,我们要去看他的源代码,然后还要知道他们之间的应用场景,在什么时候该用什么集合

1.什么是集合,他有什么好处

集合他和数组差不多,但是他比数组好用太多了,就比如说数组你只能制定长度,长度满了以后,你就不能再添加 了,或者说如果你再添加,你就只能再创建一个数组然后将数组复制过去(利用for循环)

好处就是,可以动态变化,然后可以有特定的方法增删改查。比较方便

2.集合的框架体系图

1.集合分为两种单列和双列集合

2.单列集合collection主要的子类有list和set

3.双列集合Map主要的子类有HasHMap,TreeMap,HashMaptable

4.这两种图非常重要要把他俩记下来

5.什么是单列,什么是多列,来段代码演示一下;

3.collection方法

主要就是这几种方法

3.1add添加

可以看到add(object e)就是可以添加任何类型

3.2remove删除指定元素

你可以删除对象,返回的就是Boolean类型,你也可以删除索引,来代码看一下

3.3contains查找元素是否存在

3.4size获得元素个数

3.5isEmpty判断是否为空

3.6clear清空

3.7addAll添加多个元素

这个addAll是可以添加一个集合的,

3.8containsAll查找多个元素是否都存在

3.9removeAll删除多个元素

4.collection遍历

4.1.迭代器遍历

iterator遍历器遍历

public class collection2 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new Book("红楼梦","小红",15));
        list.add(new Book("三国杀","小黄",15));
        list.add(new Book("西游记","小蓝",15));
        list.add(new Book("爱情公寓","小绿",15));
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
    }
}
class Book{
    private String name;
    private String o;
    private int age;

    public Book(String name, String o, int age) {
        this.name = name;
        this.o = o;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public String getO() {
        return o;
    }

    public void setO(String o) {
        this.o = o;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

我们来解释一下他的工作原理

创造一个iterator对象来接收list.iterator

然后在while()里面iterator.hasNext()他的作用就是来判断下一个是否还存在。

然后iterator.next是下一个对象

然后再上面那段程序里面,Book这里类的对象,编译对象还是book,意思就是iterator执行到book类的其中一个对象之后,编译的话还是按照book里面编译

他还是有快捷键的,itit就可以了

当他while循环结束之后,这个时候iterator就会指向最后一个元素,然后如果你再取iterator.next就会抛出异常

4.2增强for循环

就是上面的样子

for(元素类型 元素名:集合名/数组名){

语句

}

4.3练习题

public class test {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new dog("小黄",10));
        list.add(new dog("小王",12));
        list.add(new dog("小刘",14));
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("list+"+next);
        }
        for (Object dog : list){
            System.out.println(dog);
        }
    }
}
class dog{
    private String name;
    private int age;

    public dog() {
    }

    public dog(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 String toString() {
        return "dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

5.List

5.1基本介绍

1.list集合他的存入和取出的顺序其实是一致的,并且是可以重复的

2.每个元素都有其对应的顺序索引,他是支持索引的

3.list的实现子类其实有很多,我们之前只是展示了其中很少的一部分

5.2list接口的常用方法

我们一个个来看一下

5.2.1add在index位置插入ele元素

5.2.2addAll

5.2.3get获得指定索引的元素

比较简单

5.2.4indexOf返回该元素第一次出现的位置

5.2.4lastindexOf返回该元素最后一次出现的位置

5.2.5remove(int index):移除指定index位置的元素,并返回此元素

5.2.6object set(int index,object ele):设置指定index位置的元素为ele,相当于是替换。

5.2.7 list sublist(int fromlndex,int tolndex):返回从fromlndex到tolndex位置的子集合

由此可见他是不包含5的也就是他是不包含toIndex

完整代码在这

public class list {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("jack");
        list.add("tom");
        list.add("mark");
        list.add("lxy");
        list.add("lxy");
        list.add("jack");
        //1.add
        list.add(2,"小狗");
        System.out.println(list);
        //2.addAll
        ArrayList list1 = new ArrayList();
        list1.add("111");
        list1.add("222");
        list.add(2,list1);
        System.out.println(list);
        //4.indexOf
        System.out.println(list.indexOf("jack"));
        //5.lastindexOf
        System.out.println(list.lastIndexOf("jack"));
        //6.remove(int index):移除指定index位置的元素,并返回此元素
        //list.remove(0);
        //System.out.println(list);
        //7.object set(int index,object ele):设置指定index位置的元素为ele,
        //相当于是替换。
        list.set(0,"jack被替换了");
        System.out.println(list);
        //8. list sublist(int fromlndex,int tolndex):返回从fromlndex到
        //tolndex位置的子集合
        System.out.println( list.subList(1,5));

    }
}
5.3遍历方式

5.3.1iterator

5.3.2增强for

完整代码在这

public class list1 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("jack");
        list.add("tom");
        list.add("mark");
        list.add("lxy");
        list.add("lxy");
        list.add("jack");
        //1.iterator
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }

        System.out.println("__________");
        //2.增强for
        for (Object oj : list){
            System.out.println(oj);
        }
    }
}
5.4练习题

package List;

import java.awt.print.Book;
import java.util.ArrayList;
import java.util.Iterator;

//使用list的实现类添加三本图书,并遍历,打印如下效果
//名称: xx 价格:xx 作者:xx
//名称: xx 价格:xx 作者:xx
//名称: xx 价格:xx 作者:xx
//要求
//1)按价格排序,从低到高(使用冒泡法)
//2)要求使用arraylist,linkedlist和vector 三种集合实现
@SuppressWarnings({"all"})
public class listTest {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new book("西游记","罗贯中",18));
        list.add(new book("红楼梦","刘星岳",80));
        list.add(new book("三国志","五岑",25));
        for (Object o :list){
            System.out.println(o);
        }

        sort(list);
        System.out.println("-------");
        for (Object o :list){
            System.out.println(o);
        }

    }
    //排序
    public static void sort(ArrayList list){
        int temp = list.size();
        for (int i = 0; i < temp-1; i++) {
            for (int j = 0; j < temp-1-i; j++) {
                book book1 = (book) list.get(j);
                book book2 = (book) list.get(j+1);
                if (book1.getPrive()>book2.getPrive()){
                    list.set(j+1,book1);
                    list.set(j,book2);
                }
            }
        }
    }
}
class book{
    private String name;
    private String o;
    private int prive;

    public book(String name, String o, int prive) {
        this.name = name;
        this.o = o;
        this.prive = prive;
    }

    public String getName() {
        return name;
    }

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

    public String getO() {
        return o;
    }

    public void setO(String o) {
        this.o = o;
    }

    public int getPrive() {
        return prive;
    }

    public void setPrive(int prive) {
        this.prive = prive;
    }

    @Override
    public String toString() {
        return "book{" +
                "name='" + name + '\'' +
                ", o='" + o + '\'' +
                ", prive=" + prive +
                '}';
    }

然后我们在这里讲一下,那个冒泡排序,他的第一个循环,i其实控制的是他的循环层数,比如说你有四个数进行比较,那他循环之后就会有一个最大数在最后面,也就是他的只需要循环3次,也就是他的个数减1;

然后下面就好懂了

6ArrayList

6.1ArrayList的主要事项

1.ArrayList它里面是可以放入任何元素的,包括空null,也是可以放到里面的,而且可以放多个

2.ArrayList他的底层其实是基于数组实现的

3.ArrayList基本等同于Vector,但是ArrayList的线程是不安全的(看源码)

他是可以放多个null的

6.2ArrayList的扩容机制

刚刚我们说了,ArrayList的底层是用数组来实现的,其实在源码中他在维护一个ElementDate的一个数组

当我们创造对象的时候,如果我们使用的是无参构造器,一开始elementDate的容量其实是0,当我们添加第一个元素的时候,容量变为10,然后再次添加的话,就变为他的1.5倍,然后依次是这个样子增加

然后如果我们使用的指定大小的构造器,那么以后添加大小的话,就是*1.5这个样子

7.Vector

7.1Vector注意事项

1.和ArrayList是一样的他也是底层为elementDate数组,底层是基于数组实现的

2.Vector是线程同步的,也就是线程安全

3.在需要线程同步安全的情况下,优先考虑Vector

7.2Vector的扩容机制

他和ArrayList非常相似

当使用无参构造是,一开始他的容量是10,然后就是按两倍开始扩容

当使用有规定长度的构造器时,然后按两倍开始扩容

8.ListedList

他的底层是一个双向链表

package List;

public class Listedlist {
    public static void main(String[] args) {
        Node jack = new Node("jack");
        Node mark = new Node("mark");
        Node lxy = new Node("lxy");
        jack.next = mark;
        mark.next = lxy;
        lxy.pre = mark;
        mark.pre = jack;
        Node fist = jack;
        Node last = lxy;
        //头到尾
        while (true){
            if (fist == null){
                break;
            }
            System.out.println(fist);
            fist = fist.next;
        }

    }
}
class Node{
    public Object item;
    public Node next;
    public Node pre;
    public Node(Object name){
        this.item = name;
    }
    public String toString(){
        return "Node name" + item;
    }
}

有点难的还是

9.ArrayList和ListedList的区别

10.set

1.set他是无序的,意思就是他存放进去的数据与输出的数据不一样

2.他是不支持索引的

3.他的数据不能重复,null只能有一个

来段代码看一下

10.1遍历方式

还是那两种

1.

2.增强for循环

11.HashSet

1.HashSet实现了set的接口与方法

因为他是继承的set嘛

2.HashSet实质上是HashMap,我们可以看一下源码

3.HashSet他存入的数据与取出的顺序不一致之前在set说过了

4.不能有重复对象

11.1HashSet的底层机制

HashSet的底层其实是HashMap咱们之前也讲过,而HashSet的底层其实是数组+链表加红黑树

11.2HashSet的扩容机制

1.HashSet的底层其实是HashMap咱们之前也讲过

2.当我们在添加元素的时候,会先得到一个hash值,然后再将这个转化成索引

3.然后找的存储表table,然后如果没有则直接加入,如果有调用equals方法进行比较,如果相同则放弃添加,如果不相同,则添加到后面

4.如果链表添加到了64,则会变成红黑树

11.3执行过程

第一步

也就是个构造器,简单

第二步

add方法

第三步

执行put方法

他那个hash值其实并不是只靠hashCode得来的,还有i个移位16的操作

第四步(这一步是在HashMap的源码中的)


final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
    //上面就是定义了辅助变量
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
    //这上面就是进行了扩容,怎么扩容的就是看源码,然后<<4(位移4),然后还有一个临界值
            //0.75*那个容量,也即是12,当到达12时,就要准备扩容了
        if ((p = tab[i = (n - 1) & hash]) == null)//当你计算出那个索引后
            tab[i] = newNode(hash, key, value, null);//到这个地方
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;//然后到这里,modcount++
        if (++size > threshold)//他比较的就是那个临界值
            resize();
        afterNodeInsertion(evict);//他其实是个空方法,是留给HashMap子类实现的
        return null;//返回null就成功了
    }

分析了那么长时间,才把Java加入到里面

接下来开始分析第二次add方法

当执行第二次add的时候,其实区别就是没有在创建table表

if ((tab = table) == null || (n = tab.length) == 0)

n = (tab = resize()).length;

也就是这个,之后就是一样的了

分析第三次,相同的情况

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
    //上面就是定义了辅助变量
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;//让我们直接看这里把,这里定义了局部变量
            //下面就分成了三种情况,
            //原有元素与准备加入两个的hash值一样
            //并且满足其中一个就符合
            //1.k对象的与已有对象的内容相同
            //2.准备加入的k与node指向的节点是同一个对象
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)//判断是否是一颗红黑树
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {//这里就判断是否是一个链表
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {//如果查找后没有一样的,就添加在后面
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    //查找后有一样的就break跳出
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }
练习题

@SuppressWarnings({"all"})
public class Test {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add(new Employee("lxy",18));
        hashSet.add(new Employee("lxz",19));
        hashSet.add(new Employee("lxy",18));
        System.out.println(hashSet);
    }
}
class Employee{
    private String name;
    private int age;

    public Employee(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 String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return age == employee.age && Objects.equals(name, employee.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

12.LinkedHashset

1.他是HashSet的子类

2.他的底层是一个数组+双向链表

3.他其实也是用hash值来进行存放,不过他是用链表来维持顺序,

4.他不能存放重复数据

练习题

import java.util.LinkedHashSet;
import java.util.Objects;
@SuppressWarnings({"all"})
public class test {
    public static void main(String[] args) {
        LinkedHashSet linkedHashSet = new LinkedHashSet();
        linkedHashSet.add(new car("ixaolan",85.0));
        linkedHashSet.add(new car("xiaoh",95.0));
        linkedHashSet.add(new car("ixaolan",85.0));
        System.out.println(linkedHashSet);
    }
}
class car{
    private String name;
    private double price;

    public car(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        car car = (car) o;
        return Double.compare(price, car.price) == 0 && Objects.equals(name, car.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, price);
    }
}

13Map

13.1常用方法

13.2遍历方法

他其实就是用上面的方法,然后利用增强for或者itorate实现

练习题

package List.MAp;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

//使用hashmap添加3个员工对象,要求
//键:员工id
//值:员工对象
//并遍历显示工资》18000的员工(遍历方式最少两种)
//员工类:姓名,工资,员工id
@SuppressWarnings({"all"})
public class test {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put(12345,new player("刘星岳",15000,"12345"));
        map.put(12346,new player("范玉涵",18000,"12346"));
        map.put(12347,new player("李强",20000,"12347"));
        Collection values = map.values();
        Iterator iterator = values.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            player player = (player) next;
            if(((player) next).getPrice()>=18000){
                System.out.println(next);
            }

        }
    }
}
class player{
    private String name;
    private int price;
    private String id;

    public player() {
    }

    public player(String name, int price, String id) {
        this.name = name;
        this.price = price;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getId() {
        return id;
    }

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

    @Override
    public String toString() {
        return "player{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", id='" + id + '\'' +
                '}';
    }

14.HashMap的底层

这个地方和HashSet其实是一样的上面讲过了

可以自己debug看一下

15.HashTable

16.Properties

17.选择集合

18.作业

@SuppressWarnings({"all"})
public class Test1 {
    public static void main(String[] args) {
        news news1 = new news("新闻一","新冠确诊病例超千万,数百万印度教信徒赴恒河圣浴引民众担忧");
        news news2 = new news("新闻二","男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生");
        //(3)将新闻对象添加到arraylist集合中,并且进行倒序遍历;
        ArrayList arraylist = new ArrayList();
        arraylist.add(news1);
        arraylist.add(news2);
        Iterator iterator = arraylist.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            news news = (news) next;
            int temp = news.getSome().length();
            if (temp>=15){
                for (int i = 0; i <= 15; i++) {
                    char c = news.getSome().charAt(i);
                    System.out.print(c);
                }
            }
            System.out.println("  ");
        }
    }
}
//(1)封装一个新闻类,包含标题和内容属性,提 提供get,set方法,重写tostring方法,打印对象
//时只打印标题;
class news{
    private String name;

    private String some;

    public news(String name, String some) {
        this.name = name;
        this.some = some;
    }

    public news() {
    }

    public String getName() {
        return name;
    }

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

    public String getSome() {
        return some;
    }

    public void setSome(String some) {
        this.some = some;
    }

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

public class Test2 {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        ArrayList arrayList1 = new ArrayList();
        car car1 = new car("宝马",40000);
        car car2 = new car("宾利",5000000);
        //1.add:添加单个元素
        arrayList.add(car1);
        arrayList.add(car2);
        // 2.remove:删除指定元素 car car new car("宝马",40000);
        arrayList.remove(car2);
        // 3.contains:查找元素是否存在 car car2new car("宾利",5000000);
        System.out.println(arrayList.contains(car1));
        // 4.size:获取元素个数
        System.out.println(arrayList.size());
        // 5.isempty:判断是否为空
        System.out.println(arrayList.isEmpty());
        6.clear:清空
        arrayList.clear();
        7.addall:添加多个元素
        arrayList1.add("111");
        arrayList1.add("111");
        arrayList1.add("111");
        arrayList1.add("111");
        arrayList.addAll(arrayList1);
        System.out.println(arrayList);
        8.containsail:查找多个元素是否都存在
        System.out.println(arrayList.containsAll(arrayList1));
        9.removeall:删除多个元素
        arrayList.removeAll(arrayList);
        System.out.println(arrayList);
        使用增强for和迭代器来遍历所有的car,需要重写 car 的tostring方法


    }
}
class car{
    private String name;
    private int price;

    public car() {
    }

    public car(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

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

public class Test3 {
    public static void main(String[] args) {
        //1)使用hashmap类实例化一个map类型的对象m,键(string)和值(int)分别用于存储员
        HashMap map = new HashMap();
        map.put("jack",650);
        map.put("tom",1200);
        map.put("smith",2900);
        map.put("jack",2600);
        //2)将jack的工资更改为2600元
        System.out.println(map);
        //3) 为所有员工工资加薪100元;
        Set keySet = map.keySet();
        for (Object key:keySet){
            map.put(key,(Integer)map.get(key)+100);
        }
        //4)遍历集合中所有的工资
        Collection values = map.values();
        Iterator iterator = values.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
        //5 )遍历集合中所有的员工
        for (Object obj : keySet){
            System.out.println(obj);
        }
    }
}

1.先说一下啊HashSet是怎么去重的吧,咱们前面也说了,他是一个HashCode+equals的一个结果,他的底层是先通过算法得到一个Hash值,然后在通过Hash值得到对应的索引,如过该索引上没有数据,则可以直接存放,若有数据,则就进行equals比较(里面的遍历比较),如果比较后,不相同就加入,如果相同,就不加入

其实前五行,没有什么问题

到了下一行,p1.name就是把里面的AA换成的CC但是你要知道他为什么存放在那里,是因为他的hash值,你要把AA换成CC了,hash值不会变

然后你删除p1,现在你注意看,他要删除p1,也是要先计算Hsah值,不过现在他计算的hash值是根据1001和CC计算的,所以p1那个索引不会被删除

然后你打印其实还是两个对象

然后你存一个对象1001和CC,索引会根据他俩计算,不会对p1造成影响

然后你打印就是三个对象

你又存1001和AA这个索引就会和p1冲突,然后挂在后面,所以有4个对象

最重点的是 hashmap,对比 jdk7 和 jdk8 的版本变化

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值