Java集合框架面试题(更新中)
说出 collection 的常用子接口?说出 3 个以上的常 用方法?都有什么作用?
1. Collection具有两个比较常用的子接口,List和Set;
2. Collection中的常用方法
1、添加
Boolean add(E e):在集合中添加一个对象,如果添加成功,返回true,如果失败,返回false
Boolean addAll(Collection<?extend E> e):在集合中添加另一个集合,成功true,失败false;
2、删除
Boolean remove(object obj):删除一个对象,会改变集合的长度
Boolean removeAll(Colleciton con);删除一个集合,还有两个集合中相同的元素
void clear():删除所有
3、判断
Boolean contains(object obj):在集合中是否包含指定的对象
Boolean containsAll(Collection con):在集合是否包含另一个集合
Boolean isEmpty( ):判断集合是否为空
4、获取
int size( ):得到集合的尺寸大小 数组:length 字符串:length( );
Iterator iterator( ):取出元素的方式。迭代器。该对象必须依赖于绝缘体容器,因为每一个容器的数据结构都不同。所以该迭代器对象是在容器中进行内部实现的,对于使用容器者而言,绝缘体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法,Iterator接口就是对所有的collection容器进行元素取出的公共接口。将每一个容器中的取出方式进行了封装,并对外暴露,这样无论是什么容器或者数据结构,只要内部取出方式实现了Iterator接口,都可以通过该接口取出这些容器中的元素。他的出现,将容器的取出方式和容器的数据结构相分离,降低了耦合性,而取出方式因为直接在访问容器的元素,并依赖具体的数据结构,所以被定义在了容器中。通过内部类来实现Iterator接口。
1 | Collection c = new ArrayList(); |
for(object obj:con)用于数组和集合(高级for循环)
注意:迭代要强转,只能有一个next( )方法,否则会有NoSuchElementException异常。
5、交集
boolean retainAll(Collection c):返回两个集合的交集元素,删除其他元素,功能和removeAll相反。有A,B两个集合,做完交集后,A集合中的元素发生变化,取得是A和B相同的元素,B不变化。boolean值的问题-------->只要A集合变化,那么返回true.否则false
6、集合转数组
Object[ ] toArray():把集合转换成对象。
如果向 TreeSet 中加入类对象,需要做什么?
实现Comparable接口重写compareTo方法或者在TreesSet创建对象时传入自定义的比较类
Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是 equals()? 它们有何区别?
从它俩的区别谈起,==是用来判断两者是否是同一对象(同一事物),而equals是用来判断是否引用同一个对象。再看一下Set里面存的是
对象,还是对象的引用。根据java的存储机制可知,set里面存放的是对象的引用,所以当两个元素只要满足了equals()时就已经指向同一个对象,
也就出现了重复元素。所以应该用equals()来判断。
ArrayList 和 Vector 的区别?
1.ArrayList是线程不安全的,Vector是线程安全的
2.ArrayList扩容是原来一半,Vector是原来的一倍
集合当中能存放基本数据类型的数据吗?
Java集合不能存放基本数据类型,只能存放对象的引用。
每个集合元素都是一个引用变量,实际内容都存放在堆内或方法区里面,
但是基本数据类型是在栈内存上分配空间的,栈上的数据随时会被收回。
如何解决?
可以通过包装类,把基本数据类型转化为对象类型,存放引用。
更方便的,由于有了自动拆箱和装箱功能,基本数据类型和其对应对象
之间的转换变得很方便,把基本数据类型存入集合中可以自动存,系统
会自动将其装箱成封装类,然后将其加入到集合当中。
ArrayList 与数组的区别?
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
java 集合框架的四种主要接口是
Collection:存储无序的、不唯一的数据;其下有List和Set两大接口。
List:存储有序的、不唯一的数据;
Set:存储无序的、唯一的数据;
Map:以键值对的形式存储数据,以键取值。键不能重复,但值可以重复。
HashMap 和 Hashtable 的区别?
1 HashMap不是线程安全的
HashMap是map接口的子类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和null value,而hashtable不允许。
2 HashTable是线程安全。
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差
Collection 框架中实现比较方法
Java集合框架中需要比较大小的集合包括TreeMap、TreeSet,其中TreeMap会根据key-value对中key的大小进行排序,而TreeSet则会对集合元素进行排序。
因此TreeMap的key、TreeSet的集合元素,都需要可以比较大小。集合框架中之比较大小的有两种方式:
A.自然排序:对于自然排序来说,要求TreeMap中的所有key都实现Comparable接口,实现该接口时需要实现一个int compareTo(T o)方法,用于判断当前对象与o对象之间的大小关系。如果该方法返回正整数,则说明当前对象大于o对象;如果该方法返回0,说明两个对象相等;如果该方法返回负整数,则说明当前对象小于o对象;JDK的很多类都已经实现了Comparable接口,例如String、Date、BigDecimal等。
B.定制排序:定制排序需要在创建TreeMap或TreeSet时传入一个Comparator对象,此时TreeMap或TreeSet不再要求key、集合元素本身是可比较大小的,而是由Comparator来负责比较集合元素的大小。Comparator本身只是一个接口,因此创建Comparator对象只能是创建它的实现类的对象,Comparator的实现类需要实现int compare(T o1, T o2)方法,该方法用于判断o1、o2两个对象的大小,如果该方法返回正整数,则说明o1大于o2、如果该方法返回负整数,则说明o1小于o2、如果返回0,则说明两个对象相等。
在 Java 中,HashMap 中是用哪些方法来解决哈希冲突的?
解决哈希冲突的方法有三种,分别是:
1 | ```再散列法(二次哈希法)```:再次使用一个不同的哈希算法再计算一次 (第一次%16换另一个数进行%运算) |
可以发现源码中并没有直接使用Object中的hashCode方法,而是再让h无符号右移了16位
为何不直接使用Object提供的hashCode?
为了将哈希码保留一半,将高低位都参与运算,减少内存开销,减少哈希冲突
直接使用会造成空间浪费
(h = key.hashCode()) ^ (h >>> 16); //32 —>16 保留一半(原本32右移16位去掉了一半)
put内部逻辑:
1.哈希表索引下标计算:
i = (n-1) & hash //与运算
保证求出的索引下标都在哈希表的长度范围之内
2.n为哈希表的长度
n必须为2 的n次方,保证哈希表中的所有索引下标都会被访问到
若n=15,则以下位置永远不可能存储元素
0011,0101,1001,1011,1101,1111
接下来再看源码:
1 | final V putVal(int hash, K key, V value, boolean onlyIfAbsent, |
为何HashMap中JDK1.8要引入红黑树?
当链表长度过长时,会将哈希表查找的时间复杂度退化为O(n),树化会保证即便在哈希冲突严重时,查找的时间复杂度也为O(logn)
当红黑树结点个数在扩容或者删除元素时减少为6以下,在下次resize()过程中会将红黑树退化为链表,节省空间
Collection 和 Collections 的区别?
1、Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
2、Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。