1. ArrayList与LinkedList的区别
(1)ArrayList是实现了基于动态数组的数据结构,LinkedList是实现了基于链表的数据结构,LinkedList是双向链表。
ArrayList对象存放在堆内存中,且是一个连续的内存区间。LinkedList在内存中不连续。
(2)对于随机访问的get和set,ArrayList优于LinkedList。
(3)对于插入和删除,LinkedList优于ArrayList。
2.Collections.sort和Arrays.sort的实现原理
Collections.sort和Arrays.sort底层都是TimSort,TimSort先找到已排好序的子序列,然后对剩余部分排序,然后合并起来。
3.List set map的区别
List set实现了collection的接口。
List:可以允许重复的对象,可以插入多个null元素,是一个有序容器,保持了每个元素的插入顺序。常用的实现类是ArrayList
LinkedList和vector。
set:不允许重复对象,是一个无序容器,无法保证每个元素的存储顺序,TreeSet通过comparator或者comparable维护了一个
排序顺序,只允许一个null元素。set的实现类有HashSet,LinkedHashSet,Treeset.
map:map不是collection的子接口或实现类,Map的每个Entry都持有两个对象,一个键一个值,Map可能会有相同的值对象
但键对象必须是唯一的。TreeMap通过comparator或者comparable维护了一个排序顺序。Map里你可以拥有随意个null值但最多只能有一
个null键。常用的实现类有HashMap LinkedHashMap Hashtable TreeMap。
4.poll()方法和remove()方法的区别
poll方法删除队列的头元素,如果队列为空,它将返回null,不会引发异常。如果队列为空,remove方法将引发NoSuchElementFoundException异常。
5.HashMap HashTable ConcurrentHash的共同点和区别
单线程用HashMap,多线程用ConcurrentHash
HashMap和HashTable都是Map集合接口的实现类。Hashtable是一个线程安全的Map实现,HashMap是线程不安全的实现,所以
HashMap的性能比Hashtable的要高一些,但如果多个线程访问同一个Map对象,使用Hashtable实现类会更好一些。Hashtable不允许使用
null作为key和value。如果把null值放入Hashtable中将会引发NullPointerException异常,但HashMap可以使用null作为key和value
由于HashMap里的key不能重复,所以HashMap里最多有一个键值对的key为null,但可以有无数个键值对的value值为null。
HashTable和ConcurrentHash都是线程安全的操作,最大区别是两者的锁的粒度和锁的方式.Hashtable用的synchronized关键字
多个线程不能进入到临界区,在临界区的外部进行等待锁的释放,concurrentHashMap采用Lock关键积极锁,多个线程进入临界区在CAS竞争
的方式获取锁。Hashtable锁住整张的Hash表,concurrentHashMap字段锁在读操作并发进行,在写操作使用重置锁。
6.遍历ArrayList时删除一个元素
ArrayList删除一个元素时后面的元素会补位。如果删除的值在ArrayList有多个,可以从后往前删除,可以用迭代器。
7.打印数组:
for(int i=0;i<array.length;i++)
{
System.out.println(array[i]);
}
for(int a:array)
System.out.println(a);
int[] array = {1,2,3,4,5};
System.out.println(Arrays.toString(array))
8.HashSet如何保证不重复的
如果元素的hash码值相同且equles判断相等,说明元素已经存在,不存入。
9.ArraList和Vector的区别
相同:底层实现都是基于数组,理论最大存储容量是Integer.Max_Value(2^31-1),他们继承的类和实现的接口都是一样的,他们的默认初始化大小都是10
不同:ArrayList是线程不安全的,相对速度快,Vector是线程安全的,Vector的线程安全是使用同步关键字(synchronized)实现的。
当其容量超过初始值时,ArrayList扩容原有初始容量的50%,Vector扩容原有的100%.
10.Collection和Collections的区别
Collection是一个接口,它是Set List等容器的父接口;Collections是一个工具类,提供了一系列的静态方法来辅助容器操作,包括对容器的搜索,排序,线程安全化等
11.如何决定使用Hashmap和TreeMap
TreeMap<k,V>的key值是要求实现java.lang.Comparable,所以迭代的时候TreeMap默认按照Key值升序排序的,TreeMap的实现基于红黑树,适用于按自然顺序或自定义顺序遍历键
HashMap<k,v>的key值实现散列hashcode();分布是散列的,不均匀的,不支持排序。适用于在Map中插入,删除,定位元素。
12.如何实现数组和List之间的转换
数组转List:String[ ] array = {'a','b','c'},List<String> list = Arrays.asList(array);
List转数组:toArray()方法内的参数如果不是object类型数组,如果是转为String类型,则需要加 new String[list.size()]:String[ ] str = list.toArray(new String[list.size()]);
13.迭代器Iterator和ListIterator
迭代器Iterator是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Iterator功能比较简单,并且只能单向移动,Iterator只提供了删除的方法:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。next()返回刚越过的元素的引用,返回值是object,需要强转需要的类型
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
移除List中值为2的元素
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
if (iterator.next().equals(2)) {
iterator.remove();
}
}
ListIterator可以在遍历中添加元素,继承了Iterator接口,同时提供了几种方法:
void hasPrevious() 判断游标前面是否有元素;
Object previous() 返回游标前面的元素,同时游标前移一位。游标前没有元素就报 java.util.NoSuchElementException 的错,所以使用前最好判断一下;
int nextIndex() 返回游标后边元素的索引位置,初始为 0 ;遍历 N 个元素结束时为 N;
int previousIndex() 返回游标前面元素的位置,初始时为 -1,同时报 java.util.NoSuchElementException 错误;
void add() 在游标前面插入一个元素。
void set(E) 更新迭代器最后一次操作的元素为 E,也就是更新最后一次调用 next() 或者 previous() 返回的元素。注意,当没有迭代,也就是没有调用 next() 或者 previous() 直接调用 set 时会报 java.lang.IllegalStateException 错;
void remove() 删除迭代器最后一次操作的元素,注意事项和 set方法 一样。
14.LinkedList是双向链表
15.ArrayList的扩容机制:
1.ArrayList创建对象时,若未指定集合大小初始化大小为0;若已指定大小,集合大小为指定的大小;
2.当第一次调用add方法时,集合长度变为10和增加的内容大小之间的较大值;
3.之后再调用add方法,先将集合扩大1.5倍,如果仍然不够,新长度为传入内容的大小;
16.对一组对象排序:
(1)对象类定义时实现Comparable接口,在main方法中调用: Collections.sort(list),list为对象的集合:
public class Student implements Comparable<Student>{
int grade
int height
public Student(int grade,int height) {
this.grade=grade;
this.height=height;
}
public int compareTo(Student student) {
int i = student.grade-this.grade;
return i==0?height.compareTo(student.height):i;
}
}
(2)构造比较器类,实现Comparator接口,重写compare方法,在main方法中调用:Collections.sort(list,new MyComparator()):
public class MyComparator implements Comparator<Student> {
public int compare(Student s1,Student s2){ //compare方法返回值大于0时,交换s1和s2
int i = s2.getGrade()-s1.getGrade();
if (i!=0){
return i;
}else {
return s2.getHeight()-s1.getHeight();
}
}
}
17.ArrayList和Array的区别:
1. Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明,而直接使用 int[] array;是不行的。
2. Array只能存储同构的对象,而ArrayList可以存储异构的对象。同构的对象是指类型相同的对象,若声明为int[]的数组就只能存放整形数据,string[]只能存放字符型数据,但声明为object[]的数组除外。
而ArrayList可以存放任何不同类型的数据(因为它里面存放的都是被装箱了的Object型对象,实际上ArrayList内部就是使用"object[] _items;"这样一个私有字段来封装对象的)
3 在CLR托管对中的存放方式,Array是始终是连续存放的,而ArrayList的存放不一定连续。
4 初始化大小,Array对象的初始化必须只定指定大小,且创建后的数组大小是固定的,而ArrayList的大小可以动态指定,其大小可以在初始化时指定,也可以不指定,也就是说该对象的空间可以任意增加。
5 Array不能够随意添加和删除其中的项,而ArrayList可以在任意位置插入和删除项。
18.HashSet和TreeSet的区别:
不同点1:底层使用的储存数据结构不同:Hashset底层使用的是HashMap哈希表结构储存,而Treeset底层用的是TreeMap树结构储存。
不同点2:储存的数据保存唯一方式不同:Hashset是通过复写hashCode()方法和equals()方法来保证的。而Treeset是通过Compareable接口的compareto方法来保证的。
不同点3:hashset无序 Treeset有序
储存原理:
hashset:底层数据结构是哈希表,本质就是哈希值储存。通过判断元素的hashcode方法和equals方法来保证元素的唯一性。当哈希值不同时就直接进行储存。
如果相同,会判断一次equals方式是否返回为true ,如果是true 则视为用的同一个元素,不用再储存。
Treeset:底层数据结构式一个二叉树,可以对set集合中的元素进行排序,这种结构,可以提高排序性能。根据比较方法的返回值决定的,只要返回的是0,就代表元素重复。