Java集合容器面试题(2020最新版)
Java集合容器面试题(2020最新版)
集合为什么不能存放基本数据类型
Java集合不能存放基本数据类型,只能存放对象的引用。每个集合元素都是一个引用变量,实际内容都存放在堆内或方法区里面,但是基本数据类型是在栈内存上分配空间的,栈上的数据随时会被收回。
数组和集合的比较
数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。如下:
数组能存放基本数据类型和对象,而集合类存放的都是对象,集合类不能存放基本数据类型。数组和集合存放的对象皆为对象的引用地址。 数组容易固定无法动态改变,集合类容量动态改变。 集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式。 集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可实现各种复杂操作,大大提高了软件的开发效率。
集合容器
Collection和Map,是集合容器的根接口。
Collection的子接口:
Set:接口—实现类: HashSet、LinkedHashSet
Set的子接口SortedSet接口—实现类:TreeSet List:接口—实现类: LinkedList,Vector,ArrayList
List常用方法
增:add、addAll 删:remove 改:set 查:get、subList、listIterator(可执行遍历过程中的增删改查) 遍历:普通for、增强for、forEach、iterator(collection接口方法,遍历及移除)
public class showMessage {
public static void main ( String[ ] args) {
PG pg1 = new PG ( 01 , 24 , "张三" , 10000.0 , 85 ) ;
Employee pg2 = new PG ( 02 , 26 , "李四" , 12000.0 , 95 ) ;
Employee pm1 = new PM ( 1001 , 45 , "tom" , 70000.0 , 90 ) ;
Employee pm2 = new PM ( 1002 , 37 , "jim" , 65000.0 , 87 ) ;
List< ? super Employee> list = new ArrayList < > ( ) ;
list. add ( pg1) ;
list. add ( pg2) ;
list. add ( pm1) ;
list. add ( pm2) ;
for ( int i = 0 ; i < list. size ( ) ; i++ ) {
Employee employee = ( Employee) list. get ( i) ;
employee. show ( ) ;
}
list. forEach ( emp - > {
Employee emp1 = ( Employee) emp;
emp1. show ( ) ;
} ) ;
ListIterator< ? super Employee> listIterator = list. listIterator ( ) ;
while ( listIterator. hasNext ( ) ) {
Employee employee = ( Employee) listIterator. next ( ) ;
employee. show ( ) ;
}
for ( Object o : list) {
Employee o1 = ( Employee) o;
o1. show ( ) ;
}
}
}
Set使用方式
如果存放自定义的引用对象,需重写hashCode和equals方法。 HashSet、LinkedHashSet元素可以为null值,TreeSet不可以。
Map常用方法
增:put 删:remove、clear 判断:isEmpty、containsValue、containsKey 查:get 遍历:keySet、entrySet
public class ShowMessage {
public static void main ( String[ ] args) {
Map< Integer, Employee> map = new HashMap < > ( 4 ) ;
PG pg1 = new PG ( 01 , 24 , "张三" , 10000.0 , 85 ) ;
Employee pg2 = new PG ( 02 , 26 , "李四" , 12000.0 , 95 ) ;
Employee pm1 = new PM ( 1001 , 45 , "tom" , 70000.0 , 90 ) ;
Employee pm2 = new PM ( 1002 , 37 , "jim" , 65000.0 , 87 ) ;
map. put ( pg1. getId ( ) , pg1) ;
map. put ( pg2. getId ( ) , pg2) ;
map. put ( pm1. getId ( ) , pm1) ;
map. put ( pm2. getId ( ) , pm2) ;
for ( Map. Entry< Integer, Employee> key : map. entrySet ( ) ) {
key. getValue ( ) . show ( ) ;
}
for ( Integer key : map. keySet ( ) ) {
map. get ( key) . show ( ) ;
}
}
}
集合排序
Collections.sort(List list):自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,内部比较器。
public class User implements Comparable < User> {
private Integer id;
private String name;
private Integer age;
@Override
public int compareTo ( User user) {
Objects. requireNonNull ( user) ;
if ( this == user) {
return 0 ;
}
int result = this . age. compareTo ( user. age) ;
if ( result== 0 ) {
result = this . id. compareTo ( user. id) ;
}
return result;
}
}
Collections.sort(List list,Comparator c):定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口(java.util包)的比较器对象c,同时实现compare()其方法;,外部比较器。
Collections. sort ( userList, ( user1, user2) - > {
int result = user2. getAge ( ) . compareTo ( user1. getAge ( ) ) ;
if ( result == 0 ) {
result = user2. getId ( ) . compareTo ( user1. getId ( ) ) ;
}
return result;
} ) ;
第一种方法不够灵活,实体类实现了comparable接口(java.lang包)后,会增加耦合,如果在项目中不同的位置需要根据不同的属性调用排序方法时,需要反复修改比较规则(按name还是按age),二者只能选择其一,会起冲突。第二种就很好地解决了这个问题,在需要的地方,创建个内部类的实例,重写其比较方法即可。
集合新特性
private static void demo2 ( ) {
List< Integer> num = new ArrayList < > ( ) ;
Collections. addAll ( num, 1 , 10 , 1 , 2 , 3 , 3 , 2 ) ;
List< Integer> collect = num. stream ( ) . distinct ( ) . collect ( Collectors. toList ( ) ) ;
}
private static void demo1 ( ) {
List< User> userList = new ArrayList < > ( 10 ) ;
Collections. addAll ( userList,
new User ( 1 , "jim" , 20 ) ,
new User ( 3 , "tom" , 18 ) ,
new User ( 2 , "lily" , 18 ) ,
new User ( 5 , "zhangsan" , 18 ) ,
new User ( 5 , "zhm" , 18 ) ,
new User ( 4 , "kim" , 18 ) ) ;
userList. removeIf ( ( user - > user. getName ( ) . contains ( "m" ) ) ) ;
Stream< User> userStream = userList. parallelStream ( ) ;
userStream = userStream. filter ( user - > ! user. getName ( ) . contains ( "m" ) ) ;
List< User> collect = userStream. collect ( Collectors. toList ( ) ) ;
List< User> collect = userList. parallelStream ( ) . filter ( user - > ! user. getName ( ) . contains ( "m" ) ) . collect ( Collectors. toList ( ) ) ;
}
集合脑图