Java面试题-集合
title: Java面试题—集合
categories:
- 面试题
tags: - Java
- 后端开发
date: 2023-02-27 19:26:00
集合
categories:
- 面试题
tags: - Java
- 后端开发
date: 2023-02-27 19:26:00
集合
categories:
- 面试题
tags: - Java
- 后端开发
date: 2023-02-27 19:26:00
集合
categories:
- 面试题
tags: [‘Java’,‘后端开发’]
date: 2023-02-27 19:26:00
集合概述
Java集合,也是容器,构成于两个接口:Collection和Map接口.用于存放键值对。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4GoPShNQ-1680940906631)(/666.github.io/pic/1.png)]
说说List,Set,Queue,Map四种集合的区别。
- List比较适合存储有序的、可以重复的元素
- Set常用于存储无序的、不可重复的元素
- Queue按照特定的排队规则来确定先后顺序,存储的元素是有序的且可以重复
- Map查询比较快,其中key无序且不重复,value无序但可重复,一个键key对应一个value值
跟着视频复习一遍吧
韩顺平视频地址(https://www.bilibili.com/video/BV1YA411T76k/?spm_id_from=333.337.search-card.all.click&vd_source=7c6c7bb18c7ca81e3c9e3e6722861c9d)
主要的两大类,需要背
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ofFemIK-1680940906632)(/666.github.io/pic/47.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9PlAnWeH-1680940906633)(/666.github.io/pic/48.png)]
List接口的三种实现方法
LinkedList,ArrayList,Vector。
List的三种输出方式
package com.jun.List_;import java.util.ArrayList;
import java.util.Iterator;/** @Author: jun* @Date:2023/4/4 16:37* @概述:*/
public class ListFor {@SuppressWarnings("all")public static void main(String[] args) {ArrayList list = new ArrayList();for (int i = 0; i < 12; i++) {list.add("jun"+i);}System.out.println(list);//三种遍历方式//1.迭代器Iterator iterator = list.iterator();while (iterator.hasNext()) {Object next = iterator.next();System.out.println("迭代器输出:"+next);}//2.增强forfor (Object j :list) {System.out.println("增强for输出:"+j);}//3.常规for输出for (int i = 0; i < list.size(); i++) {System.out.println("常规for输出:"+list.get(i));}}
}
ArrayList是线程不安全的,因为没有添加 synchronized互斥锁,线程之前会同时进行操作,会导致脏读,幻读,错读。
所以在多线程情况下就不要使用ArrayList了。
ArrayList底层结构和源码分析
1) ArrayList中维护了一个Object类型的数组elementData.
2) 当创建ArrayList对象时,如果使用的是无参构造器(即没有指明大小),则初始化elementData容量为0,第一次添加,则扩容elementData为10,如果需要再次扩容elementData就为1.5倍。
3) 如果使用的指定大小的构造器,初始的大小elementData容量为指定大小,如果需要再次扩容,则直接扩容elementData为1.5倍。
Vector底层结构和源码分析
还是List接口的实现子类。
1) 底层也是一个对象数组。
2) 是线程同步的,即线程安全。Vector类的操作方法有synchronized
3) 在开发的过程中,需要考虑到线程同步安全问题时,可以考虑使用Vector。
LinkedList底层结构和源码分析
1) LinkedList底层实现了双向链表和双端队列特点
2) 可以添加任意元素(元素可以重复),包括null
3) 线程不安全,没有实现同步。
😂
双向链表
package com.jun.List_;/** @Author: jun* @Date:2023/4/7 19:12* @概述:*/
public class LinkedList01_ {public static void main(String[] args) {//模拟一个简单的双向链表node jack = new node("jack");node tom = new node("tom");node jun = new node("jun");//连接三个节点,形成双向链表//jack -> tom -> junjack.next = tom;tom.next = jun;//jun -> tom -> jackjun.pre = tom;tom.pre = jack;node first = jack; //让first引用指向jack,就是双向链表的头结点node last = jun; //让last引用指向jun.就是双向链表的尾结点System.out.println("从头到尾遍历");while (true) {if (first == null) {break;}//输出first信息System.out.println(first);first = first.next;}System.out.println("从尾到头遍历");//演示,从尾到头遍历while (true) {if (last == null) {break;}//输出first信息System.out.println(last);last = last.pre;}}}//定义一个node,表示一个双向连表的节点
class node{public Object item; //真正存放数据public node next; //指向下一个结点public node pre; //public node(Object name){this.item = name;}@Overridepublic String toString() {return "node name" + item;}
}
ArrayList和LinkedList比较
ArrayList和LinkedList的比较:
ArrayList是可变数组,增删的效率比较低,数组可以扩容,改查的效率也比较高
LinkedList 是双向链表,通过链表追加,改查的效率比较低。
Set接口
主要的两个子实现类:HashSet和TreeSet
1)接口无序:添加和取出的顺序不一致,没有索引
2)不允许重复元素,最多包含一个null
3)JDK API中Set接口的实现类有AbstractSet , ConcurrentHashMap.KeySetView , ConcurrentSkipListSet , CopyOnWriteArraySet , EnumSet , HashSet , JobStateReasons , LinkedHashSet , TreeSet
package com.jun.Set;import java.util.HashSet;/** @Author: jun* @Date:2023/4/7 20:05* @概述:*/
public class SetMethod {public static void main(String[] args) {//1. 以Set接口的实现类HashSet 为例//2. set接口的实现类对象,不能存放重复的元素//3. 无序,即添加的顺序与取出的数据不一致//4. 注意:取出的顺序是始终一致的,不会每次都不一样HashSet set = new HashSet();set.add("john");set.add("lucy");set.add("jun");set.add("jack");set.add(null);set.add(null);System.out.println(set);}
}
遍历方式
//方式1:迭代器Iterator iterator = set.iterator();while (iterator.hasNext()) {Object obj = iterator.next();System.out.println(obj);}//方式2:增强forfor (Object o :set) {System.out.println(o);}
HashSet
1) 实现了Set接口
2) 实际上是HashMap
3) 可以存放null值,但是只有一个null
4) 不保证有序,即,不保证存放元素的顺序和取出的顺序一致。
5) 不重复的元素。
Map
package com.jun.map_;import java.util.HashMap;
import java.util.Map;/** @Author: jun* @Date:2023/4/8 10:13* @概述:*/
public class Map_ {public static void main(String[] args) {//1.Map用于保存具有映射关系的数据Key-Value//2.Map与Collection并列存在,用于保存具有映射关系的数据:Key-Value(双列元素)//3.Map中的Key和Value可以是任何引用类型的数据,会封装到HashMap&Node对象中//4.一般情况下以String类作为Map的Key//5.key和value之间存在单向一对一的关系,即通过指定的key可以找到对应的valueMap map = new HashMap();map.put("no1","jun");map.put("no2","lili");map.put("no1","zhang");//当有相同的k,就等价于替换map.put("no3","lili");//value可以重复map.put(null,null);//map中的key可以为null,value也可以为null//两者的细微不同是,key只能一个为null,而value可以有多个nullmap.put(new Object(),"人人");System.out.println(map);}
}
开发中如何选择集合实现类
选择什么集合实现类,主要取决于业务操作特点:
1) 先判断存储的类型(一组对象[单列]或者一组键值对[双列])
2) 一组对象:collection接口
允许重复:list
增删多:LinkedList(底层维护了一个双向链表)
不允许重复:Set
无序:HashSet
排序:TreeSet
3) 一组键值对:Map
键无序:HashMap(哈希表,jdk7:数组+链表,jdk8:数组+链表+红黑树)
键排序:TreeMap
键插入和取出一致:LinkedHashMap
读取文件:properties
Collections工具类
package com.jun.collection_;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;/** @Author: jun* @Date:2023/4/8 15:24* @概述:*/
@SuppressWarnings({"all"})
public class Collections_tool {public static void main(String[] args) {//创建ArrayList集合,用于测试List list = new ArrayList();list.add("jun01");list.add("jun02");list.add("jun03");list.add("jun04");//reverse(List):反转List中元素的顺序Collections.reverse(list);System.out.println(list);//result:[jun04, jun03, jun02, jun01]//shuffle(List):对List集合元素进行随机排序Collections.shuffle(list);System.out.println(list);//[jun02, jun03, jun01, jun04]//sort(List):根据元素的自然顺序对指定List集合元素按升序排序Collections.sort(list);System.out.println(list);//[jun01, jun02, jun03, jun04]//swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换Collections.swap(list,0,1);System.out.println(list);//[jun02, jun01, jun03, jun04]//Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素System.out.println(Collections.max(list));Object maxObject = Collections.max(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {return ((String)o1).length() - ((String) o2).length();}});System.out.println(maxObject);}
}
脑瓜子痛
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQko03fx-1680940906633)(/666.github.io/pic/f4aa9cd4d88b8eda7d695ba4f1c6cbb0_1.jpg)]