Java高级~避坑总结,知识点整理【持续更新....】

1. 集合中重写equals()方法
  1. 集合只能存储引用数据类型,基本数据类型是自动装箱成包装类,包装类重写了equals方法,所以也是比较的值
  2. 向Collection接口的实现类的对象中添加数据obj时,即向list中添加对象时,要求 对象所在类要重写equals

Person.class

public class Person {
    private String name;
    private int 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;
    }

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

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

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

测试

    public static void main(String[] args) {
        Collection coll  = new ArrayList();
        coll.add(new String("Tom"));
        System.out.println("String相等的判断 :" + coll.contains(new String("Tom")));  // true

        coll.add(12);
        System.out.println("基本数据类型的比较 : " + coll.contains(12)); // true

        coll.add(new Person("Jerry", 22));
        System.out.println("对象的比较 : "+ coll.contains(new Person("Jerry", 22))); // true  , 如果没有重写Person中的equals方法,得到的就是false
    }
2. ArrayList源码分析

jdk1.7和jdk1.8略有不同

jdk 1.7

  1. 底层创建了长度是10的Object[]数组 elementData

java.util.ArrayList;

2. 扩容,并复制原有数组元素到新的数组中。
list.add(),如果此次的添加导致底层elementData数组容量不够,则扩容。默认情况下,扩容为原来的1.5倍。

jdk 1.8
4. 底层 Object[] elementData初始化为{},并没有创建长度为10的数组

list.add(123)//第一次调用add时,底层才创建了长度10的数组,并将123添加到elementData[0]中

jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存

结论,建议开发中使用带参的构造器,ArrayList list = new ArrayList(int capacity),减少扩容操作,降低损耗。

3. LinkedList源码分析

内部声明了Node类型的first和last属性,默认值为null,LinkedList的底层结构是双向链表。

Node定义为

向链表中添加一个元素,相当于在链表尾部加上一个Node结点

4. Vector源码分析

jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。扩容方面,默认扩容为原来的数组的2倍

5. ArrayList、LinkedList、Vector三者的异同

相同点:

  • 三个类都是实现了List接口
  • 存储数据的特点相同:存储有序的,可重复的数据

不同点:

  • ArrayList:作为List接口的主要实现类,线程不安全的,效率高。底层使用Object[] elementData存储
  • LinkedList:作为频繁的插入,删除操作,使用此类效率比ArrayList高,底层使用双向链表
    数组的添加删除操作,需要移动所需添加元素后的所有的数据。链表的添加删除,只需要改变指针指向。如果不指定位置,直接在list最后添加元素,使用ArrayList效率更高。这种情况下,不需要移动数组元素,减少操作指针的效率损失。
  • Vector:作为List接口的古老实现类,线程安全,效率高。底层使用Object[] elementData存储
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值