18.java 容器都有哪些?
集合(list,set,Map。。)
19.Collection 和 Collections 有什么区别?
1、Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
2、Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
20.List、Set、Map 之间的区别是什么?
list和set是实现了collection接口、
List:1.可以允许重复的对象。
2.可以插入多个null元素。
3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
Set:1.不允许重复对象
2. 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
3. 只允许一个 null 元素
4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
1.Map不是collection的子接口或者实现类。Map是一个接口。
2.Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。
3. TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
4. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。
5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
21.HashMap 和 Hashtable 有什么区别?
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口。主要的区别有:线程安全性,同步(synchronization),以及速度。
1.Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
2.HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
3.HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。(在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap))
4.另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。fail-fast机制如果不理解原理,可以查看这篇文章:http://www.cnblogs.com/alexlo/archive/2013/03/14/2959233.html
5.由于HashMap非线程安全,在只有一个线程访问的情况下,效率要高于HashTable。
6.HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
7.Hashtable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
8..两者通过hash值散列到hash表的算法不一样:
,HashTbale是古老的除留余数法,直接使用hashcode
22.如何决定使用 HashMap 还是 TreeMap?
(1)HashMap:适用于在Map中插入、删除和定位元素。
(2)Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
(3)HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap.
(4)HashMap 非线程安全 TreeMap 非线程安全
(5)HashMap的结果是没有排序的,而TreeMap输出的结果是排好序的。
在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。
23.说一下 HashMap 的实现原理?
hashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用LinkedList来解决碰撞问题,当发生碰撞了,对象将会储存在LinkedList的下一个节点中。 HashMap在每个LinkedList节点中储存键值对对象。
当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的LinkedList中。键对象的equals()方法用来找到键值对。 https://zhangshixi.iteye.com/blog/672697
24.说一下 HashSet 的实现原理?
https://blog.csdn.net/guoweimelon/article/details/50804799
25.ArrayList 和 LinkedList 的区别是什么?
1、ArrayList和LinkedList可想从名字分析,它们一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,此外,它们两个都是对List接口的实现。
前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列
2、当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
3、当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
4、从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
5、ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
26.如何实现数组和 List 之间的转换?
1.list转set
Set set = new HashSet(new ArrayList());
2.set转list
List list = new ArrayList(new HashSet());
3.数组转为list
List stooges = Arrays.asList("Larry", "Moe", "Curly");
或者
String[] arr = {"1", "2"};
List list = Arrays.asList(arr);
4.数组转为set
int[] a = { 1, 2, 3 };
Set set = new HashSet(Arrays.asList(a));
5.map的相关操作。
Map map = new HashMap();
map.put("1", "a");
map.put('2', 'b');
map.put('3', 'c');
System.out.println(map);
// 输出所有的值
System.out.println(map.keySet());
// 输出所有的键
System.out.println(map.values());
// 将map的值转化为List
List list = new ArrayList(map.values());
System.out.println(list);
// 将map的值转化为Set
Set set = new HashSet(map.values());
System.out.println(set);
6.list转数组
List list = Arrays.asList("a","b");
String[] arr = (String[])list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(arr));
27.ArrayList 和 Vector 的区别是什么?
(1):Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比;
(2):ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍;
(3):Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数。
28.Array 和 ArrayList 有何区别?
Array([]):最高效;但是其容量固定且无法动态改变;
ArrayList: 容量可动态增长;但牺牲效率;
基于效率和类型检验,应尽可能使用Array,无法确定数组大小时才使用ArrayList!
不过当你试着解决更一般化的问题时,Array的功能就可能过于受限。
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型
Array大小固定,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性:比如 :addAll(),removeAll(),iterator()等等。
对于基本数据类型,集合使用自动装箱来减少编码工作量。但是,当处理固定大小基本数据类型的时候,这种方式相对较慢。
29. Queue中offer&add与poll&remove与peek&element的区别
offer,add区别:
一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。
poll,remove区别:
remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似,
但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。
peek,element区别:
element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null
30.哪些集合类是线程安全的?
Hashtable StringBuffer
31.迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
32.Iterator 怎么使用?有什么特点?
Java中的Iterator功能比较简单,并且只能单向移动: (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。 (2) 使用next()获得序列中的下一个元素。 (3) 使用hasNext()检查序列中是否还有元素。 (4) 使用remove()将迭代器新返回的元素删除。 Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
33.Iterator 和 ListIterator 有什么区别?
1. iterator()方法在set和list接口中都有定义,但是ListIterator()仅存在于list接口中(或实现类中);
2. ListIterator有add()方法,可以向List中添加对象,而Iterator不能
3. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
4. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
5. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。
34.怎么确保一个集合不能被修改?
私有化,或者return Collections.unmodifiableList(list);