codecamp

集合

笔者能力有限,总结有误的地方,请读者协作更正。

1.HashMap和HashTable和ConcurrentHashMap?

1)HashMap和HashTable的区别?

HashMap可以接受null;HashTable不可以;

HashMap是非线程安全的,存储的是键值对,速度很快;

HashTable是线程安全的,但是不推荐使用

2)HashMap的put()和get()方法?

HashMap基于hashing原理,使用put将key-value对象到HashMap中;使用get获取存储的对象;

当我们put的时候,先调用key的hashCode()方法,返回HashCode用于找到bucket位置来存储Entry对象;

3)HashMap的碰撞探测以及碰撞探测的解决方法? 当两个对象的HashCode相同时会发生什么?

因为HashCode相关,它们的bucket位置相同,碰撞就会发生。因为HashMap使用链表存储对象,这个Entry(包含键值对的Map.Entry对象)会存储在链表中。

4)如果两个键的hashCode相同,如何获取键值对对象?

调用get方法,通过键值对的hashCode找到bucket的位置,会调用keys.equals( )方法去链表中找到对象。

使用不可变的,声明为final的对象,能减少碰撞的发生,提供效率; 由于键值对的不可变性,使用String,interger这样的包装类能有效的提供获取对象的速度;

5)HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?

默认负载因子大小是0.75;初始大小是16;

当一个map填满了75%的buckey时候,会创建原来HashMap大小两倍的bucket数组,来重新调整map的大小,并将原来的对象放入新的bucket数组中;

6)重新调整HashMap大小存在什么问题?

可能会产生条件竞争; 因为在重新调整大小的时候,存储在链表的元素的次序会反过来,HashMap并不会将元素放在链表的尾部,而是放在头部,避免尾部遍历; 条件竞争产生,就会死循环; 多线程情况下,不使用HashMap,它是非线程安全的,通常都使用线程安全的CurrentHashMap;

7)为什么String,integer这样的wrappr类适合作为键?

String最常用,因为包装类是final的,不可变的,已经重写了equals()hashCode()方法; 计算hashCode,是为了防止键值改变;不可变性能减少hash碰撞,提升HashMap性能;

8)我们可以使用自定义的对象作为键么?

可以使用任何对象作为键,但是需要遵循equals和hashcode方法的规则,最重要的是要确保作为键值的对象插入Map之后不可变。

9)可以使用ConcurrentHashMap替代hashTable么?

Hashtable是线程安全的,但是ConcurrentHashMap同步性更好; ConcurrentHashMap在内部使用了同步锁,只锁住一部分; 当然可以替代Hashtable,但是线程安全性没有hashTable高;

2.谈一谈HashMap的工作原理?

HashMap基于hashing原理,通过put()和get()方法来存储对象和获取对象;

我们将键值对传给put()时,它调用键对象的hashcode()方法来计算hash值,然后找到bucket位置来存储值对象;

获取对象的时候,通过键对象的equals()方法找到正确的键值对,然后返回值对象;

HashMap使用链表来解决碰撞问题,当碰撞发生时,对象会存储到链表的下一个节点,hashMap在每个链表节点中存储键值对对象。

两个不同的键值对象的Hashcode相同时候,会将它存储到同个bucket位置的链表中,通过键值对的equals()方法来找到键值对。

HashMap的好处非常多,在电子商务的应用中使用HashMap作为缓存,考虑到性能和非线程安全性,常用ConcurentHashMap代替HashMap;

3.为什么Map接口不继承Collection接口?

. Set是无序集合,并且不允许重复的元素

· List是有序的集合,并且允许重复的元素

·Map被设计为键值对的集合,不是一组对象规范,所以不需要继承Collection 接口

4.Comparable和comparator的不同之处?

Comparable接口来自java.lang包,它有一个compareTo(Object obj)方法用来给Object排序

Comparator接口是java.util包,他有一个compare(Object obj1, Object obj2)方法用来给objects排序

5.如何对Object的List进行排序?

对数组,使用Arrays.sort( )方法 对集合,使用Collections.sort( )方法

6.Java中set和List的区别?

Set:无序,不可重复;没有索引,仅仅允许一个null值,类有HashSet、LinkedHashMap、TreeSet

List:有序,可以重复;有索引,允许多个null值,可以按照插入顺序显示,类有Vector、ArrayList、LinkedList

7.ArrayList和Vector的区别?

Vector是同步的,ArrayList是不同步的,ArrayList是集合框架的组成部分

8.如何保证一个集合线程安全?

Vector、HashTable、Properties和Stack是同步的,是线程安全的;

使用Collections.synchronizedList( )方法,可以保证List线程安全;

使用Collections.synchronizedSet( )方法可以保证set类线程安全;

9.HashCode()和equals()方法的重要性?如何使用?

HashCode()和equals()方法定义在Object类中;

如果Equals()方法比较两个对象返回true,那么它们的HashCode()的返回值一样

10.Java集合框架是什么?说出集合框架的优点?

看图描述;

好处:减少开发成本,代码质量提高,减少维护,复用性高等。

11.Iterater和ListIterator之间的区别?

Iterater使用来遍历set和list集合,只能向前遍历

ListIterator只可以遍历List集合,可以双向遍历 ListIterator继承iterator;

12.遍历List集合的同步方式?

使用for-each循环; 使用迭代器 List<String> strList = new ArrayList<>(); //1. 使用for-each循环 for(String obj : strList){ System.out.println(obj); }

    
    //2. using iterator
    Iterator<String> it = strList.iterator();
    while(it.hasNext()){
    String obj = it.next();
    System.out.println(obj);
    }

13.在迭代一个集合的时候,怎样避免ConcurrentModificationException?

能够使用并发集合类来避免ConcurrentModificationException,比方使用CopyOnWriteArrayList。 而不是ArrayList。

14.为何Iterator接口没有详细的实现?

接口只提供规范,为何要实现,谁要实现,谁来提供方法

15.Map接口提供了哪些不同的集合视图?

Set keyset():返回map中包括的全部key的一个Set视图。

Collection values():返回一个map中包括的全部value的一个Collection视图。

Set<Map.Entry<K,V>> entrySet():返回一个map中包括的全部映射的一个集合视图。

16.怎样决定选用HashMap还是TreeMap?

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而。假如你须要对一个有序的key集合进行遍历,TreeMap是更好的选择。

基于你的collection的大小,或许向HashMap中加入元素会更快。将map换为TreeMap进行有序key的遍历。

17.EnumSet是什么?

是枚举类的集合实现

18.BlockingQueue是什么?

是队列,是集合框架的一部分,主要用于实现生产者-消费者模式

19.怎样对一组对象进行排序?

假设我们需要对一个对象数组进行排序,我们能够使用Arrays.sort()方法。 假设我们须要排序一个对象列表,我们能够使用Collection.sort()方法。

20.集合框架了实现了哪些通用算法?

Java集合框架提供经常使用的算法实现,比方排序和搜索。Collections类包括这些方法实现。大部分算法是操作List的,但一部分对全部类型的集合都是可用的。部分算法有排序、搜索、混编、最大最小值。

21.与Java集合框架相关的有哪些最好的实践?

(1)依据需要选择正确的集合类型。比方,假设指定了大小,我们会选用Array而非ArrayList。

假设我们想依据插入顺序遍历一个Map,我们须要使用TreeMap。假设我们不想反复。我们应该使用Set。

(2)一些集合类同意指定初始容量。所以假设我们能够预计到存储元素的数量,我们能够使用它,就避免了又一次哈希或大小调整。

(3)基于接口编程,而非基于实现编程。它同意我们后来轻易地改变实现。

(4)总是使用类型安全的泛型。避免在执行时出现ClassCastException。

(5)使用JDK提供的不可变类作为Map的key,能够避免自己实现hashCode()和equals()。

(6)尽可能使用Collections工具类,或者获取仅读、同步或空的集合,而非编写自己的实现。

它将会提供代码重用性,它有着更好的稳定性和可维护性。

  1. 下面是几章集合图 如果你能看图说话,将集合相关的重要知识点都能说出来,那么这一块知识点就没有多大的问题了。

图1:

图2:

图3:

泛型
多线程
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

第2章 数据库

SQL

第4章 hadoop

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }