Java基础(==和equals,List 、Set和Map)

有两三个月没看Java基础,遇到面试题就又只有零碎的印象了。

1、Java中 == 和 equals 的区别?

一开始只清楚 == 用于处理基本数据类型(Byte、Short、Char、Int、Long、Float、Double、Boolean),而String类等引用数据类型使用equals。

实际上, == 判断左右内容是否指向同一个内存空间(因为值类型储存在栈中,引用类型仅有地址储存在栈中,内容储存在堆中)。

equals则是判断左右引用类型的内容是否相等,即在堆中的内容是否相同。

2、List,Set和Map之间的区别?

这个我对List留下的印象是数据结构中的顺序表和链表,没有考虑到Vector。

ArrayList就是用数组实现的List接口,LinkedList是用双向链表实现的。其中区别还是在于插入移除数据,数组实现显然需要开辟连续的储存空间,好处在于知道下标就可以O(1)查找,但是中间插入数据需要将之后的数全部后移一格。链表使用Node节点包括了前后节点的地址,就不需要后移了,直接修改前节点和后节点的地址就可以了,但是不能用下标意味着寻找第n个数需要从头遍历。Vector通过加入同步锁,保证了线程安全,当然额外的操作会降低效率。容量不足时自动翻倍。具体实现和ArrayList类似,是数组。

Set在Leetcode里用的多,自己只用过HashSet所以认识不够清楚。(我以前觉得HashSet基本就是K和V相等的HashMap)其实Set是容纳不重复的集合,实现也可以不用HashCode的方式的,比如TreeSet就是红黑树结构,而且TreeSet是有序的(这里的有序与Set不冲突,TreeSet是可排序输出)(LinkedHashSet是有序的)。

接下来有一个问题,既然HashSet用了散列的方式,是根据Key的哈希操作来确定位置的,那么以不同的顺序输入同一组数据,其输出是否相同呢?

public class Test1 {
    public static void main(String[] args) {
        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> set2 = new HashSet<Integer>();
        set1.add(1);
        set1.add(2);
        set1.add(3);
        set2.add(3);
        set2.add(2);
        set2.add(1);
        System.out.println(set1);
        System.out.println(set2);
    }
}
运行结果1
public static void main(String[] args) {
        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> set2 = new HashSet<Integer>();
        set1.add(1);
        set1.add(2);
        set1.add(3);
        set1.add(18);
        set2.add(1);
        set2.add(18);
        set2.add(2);
        set2.add(3);
        System.out.println(set1);
        System.out.println(set2);
    }
运行结果2

HashSet的add直接调用HashMap的put方法,且以e作为Key。HashMap的put调用hash方法,而hash方法使用.hashCode()和扰动函数,最后再用散列值对数组长度进行取模运算取得余数。 (这块涉及源码,网上找到了详细分析 https://www.cnblogs.com/ideal-20/p/11146733.html

使用了散列就要考虑冲突。解决冲突有几种简单办法:线性探查法,平方探查法,和链地址法(拉链法)。其中链地址法不计算新的Hash值,直接把H(key)相同的key值连接成一条单链表,而HashMap使用的就是链地址法。既然使用了链地址法,那么一组数据在环境中存在哈希冲突的情况下,以不同的顺序输入,那么冲突所产生的链表中的顺序将会根据输入的顺序来排列,在输出时也会根据输入的顺序的不同而不同。

已知在数组初始长度小于16的情况下,2与18会产生冲突,调整2和18添加进HashSet的顺序,输出循序也因此而改变。