Java基础

1、List 和 Set 的区别

1.1 异同点

首先List最重要的特点是能保证数据存入的顺序性,而set由于是根据hash映射的地址,因此是无序的。
其次,list可以存储相同的内容,允许多个null值,set不允许数据重复,只允许一个null值。

List和set都是集成Collection接口的。
List包括,ArrayList、LinkedList、Vector.其中ArrayList类似于数组,可以随意访问,适合查找频繁的场景,而LinkedList则适合插入删除频繁的场景。
Set包括,HashSet,TreeSet,LinkedSet;HashSet是基于HashMap实现的,TreeSet可以对保存的数据自动排序。

1.2、List、Set的使用场景

如果知道数据的索引位置,那可以用List中的ArrayList,可以很快的查找到数据。如果经常的增删数据则用LinkedList。
如果希望容器中的数据按照插入顺序进行存储,比如最近访问列表等,需要按照时间的先后顺序存储的,就可以用List。
如果是希望容器中的数据是不重复的,只保留一份,那就使用set,其中TreeSet还支持对存入数据进行排序。

2、HashSet 是如何保证不重复的

HashSet是由HasnMap实现的,可以直接看源码中HashSet的构造函数,直接new了一个hashMap

  public HashSet() {
        map = new HashMap<>();
    }

所以,HashSet和HashMap的去重方式是一样的,可以看一下HashSet的add方法,直接调用了hasMap.put
方法,如下:

 public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {//主要判重逻辑
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

可以看到上面的主要判重逻辑代码,首先,判断了原有元素e.hash与新传入key的hash,e是已存在的键值对中的元素,e.hash实际就是已经存在的key值的hash值。判断完后,判断key是否相同。如果重复,则用新的值替换旧的值。

3、HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)?

 HashMap不是线程安全的。
详细说明为什么会出现线程不安全->传送门
 线程不安全主要是由于HashMap有扩容机制,HashMap的初始大小是16,如果超过了16,就会进行扩容,在扩容的过程中,如果两个线程同时达到了需要进行rehash的时候,会对链表进行重排,此时,在取链表数据时,可能会发生链表循环。以下是源码:

 void resize(int newCapacity) {
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }

        Entry[] newTable = new Entry[newCapacity];
        boolean oldAltHashing = useAltHashing;
        useAltHashing |= sun.misc.VM.isBooted() &&
                (newCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
        boolean rehash = oldAltHashing ^ useAltHashing;
        transfer(newTable, rehash);//此处会进行数据重新存放到一个新的数组里面去。
        table = newTable;
        threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
    }

    /**
     * 如果两个线程同时到达该方法,此时对于两个线程来说newTable是固定,且都保存一份数组
     * 如果其中一个线程正确执行完,另外一个线程就有可能造成链表环。
     */
    void transfer(Entry[] newTable, boolean rehash) {
        int newCapacity = newTable.length;
        for (Entry<K,V> e : table) {
            while(null != e) {
                Entry<K,V> next = e.next;
                if (rehash) {
                    e.hash = null == e.key ? 0 : hash(e.key);
                }
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
                e = next;
            }
        }
    }

4、HashMap 的扩容过程

hashmap有threshold,如果当前数组容量大于threshold,就会进行数组扩容,扩容大小是当前数组长度的2倍。
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
阈值等于 容量乘以负载因子与最大容量中较小的值。
数组扩大后,会对原有hashmap重新hash并定位。

5、HashMap 1.7 与 1.8 的 区别,说明 1.8 做了哪些优化,如何优化的?

hashMap1.8在hashMap的链表中增加了红黑树,如果链表长度超过了8,就会调用方法把 链表转换为红黑树,如果链表长度小于

6、final finally finalize

final是修饰符,可以修饰在类上,表示该类不能被继承;修饰在方法上,表示该方法不能被重写,但是可以重载;修饰在变量上面,如果是基本类型,值不能变,是对象的话,表示该变量引用不能被修改。
finally 是异常捕获时候使用的,一般在finally中执行关闭资源操作,即使在try中return了,也会执行finally中的代码。实际finally是在return前执行的。
finalize是垃圾回收时显示声明用的,finallize方法调用了,不一定会执行gc过程。

7、强引用 、软引用、 弱引用、虚引用

强引用:
Object o=new Object();
这是最常见的实例化对象的方法,这种方法就是强引用,除非设置 o = null;否则在垃圾回收时不会被清理。
软引用:
SoftReference:
会在内存溢出之前进行一次检查,将所有软引用内存释放。一般软引用可以用来做临时缓存;应用场景比如,需要读取经常使用的图片,图片可以缓存在内存中,加快读取速度,也可以从远程下载,放在内存中的话,因为图片size比较大,容易引起OOM,可以使用softReference,在发生内存溢出时才清理。此时如果还要请求图片,才重新从远程去下载图片。
用法:

Object o=new Object();  
SoftReference<Object> softRef = new SoftReference<Object>(o);

弱引用:
在gc之前,清除弱引用内存。主要用来检测对象是不是被标记为可回收对象。

import java.lang.ref.WeakReference;

public class Main {
    public static void main(String[] args) {

        WeakReference<String> sr = new WeakReference<String>(new String("hello"));

        System.out.println(sr.get());
        System.gc();                //通知JVM的gc进行垃圾回收
        System.out.println(sr.get());
    }
}
  输出结果为:
hello
null

虚引用就像名字一样是一个虚的,只要执行垃圾回收都会把他回收掉。虚引用的get方法永远获取的都是null值,主要用来判断这个对象是否已经从内存里面删除了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容

  • 九种基本数据类型的大小,以及他们的封装类。(1)九种基本数据类型和封装类 (2)自动装箱和自动拆箱 什么是自动装箱...
    关玮琳linSir阅读 1,883评论 0 47
  • 标签:【每日一题】 到目前为止,整理了Android四大组件、Android基本常识、还有这个Java基础面试题,...
    草帽团长阅读 1,269评论 3 15
  • 印度电影《摔跤吧!爸爸》火了很多天,我和诚先生才抽时间去电影院看。走出影院,照例是要跟诚先生品评一番的,只是不约而...
    烟火万象阅读 340评论 1 1
  • 人生的每一场相遇,都是缘分,没有对错。人生的每一个清晨,都该努力,不能拖延。 ​​
    太阳当空照1阅读 141评论 0 0
  • 金句来自李笑来老师 原文如图 只字不差的阅读是基础的基础。 一字之差,生死两隔。 隐私保护, 这句话是我人生的一次...
    邢慧宇阅读 407评论 0 1