> 文章列表 > Java面试题-集合

Java面试题-集合

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)]