title: Java面试题—集合
categories:
集合
categories:
集合
categories:
集合
categories:
Java集合,也是容器,构成于两个接口:Collection和Map接口.用于存放键值对。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4GoPShNQ-1680940906631)(/666.github.io/pic/1.png)]
韩顺平视频地址(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)]
LinkedList,ArrayList,Vector。
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.增强for
for (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了。
1) ArrayList中维护了一个Object类型的数组elementData.
2) 当创建ArrayList对象时,如果使用的是无参构造器(即没有指明大小),则初始化elementData容量为0,第一次添加,则扩容elementData为10,如果需要再次扩容elementData就为1.5倍。
3) 如果使用的指定大小的构造器,初始的大小elementData容量为指定大小,如果需要再次扩容,则直接扩容elementData为1.5倍。
还是List接口的实现子类。
1) 底层也是一个对象数组。
2) 是线程同步的,即线程安全。Vector类的操作方法有synchronized
3) 在开发的过程中,需要考虑到线程同步安全问题时,可以考虑使用Vector。
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 -> jun
jack.next = tom;
tom.next = jun;
//jun -> tom -> jack
jun.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;
}
@Override
public String toString() {
return "node name" + item;
}
}
ArrayList和LinkedList的比较:
ArrayList是可变数组,增删的效率比较低,数组可以扩容,改查的效率也比较高
LinkedList 是双向链表,通过链表追加,改查的效率比较低。
主要的两个子实现类: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:增强for
for (Object o :
set) {
System.out.println(o);
}
1) 实现了Set接口
2) 实际上是HashMap
3) 可以存放null值,但是只有一个null
4) 不保证有序,即,不保证存放元素的顺序和取出的顺序一致。
5) 不重复的元素。
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可以找到对应的value
Map 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可以有多个null
map.put(new Object(),"人人");
System.out.println(map);
}
}
选择什么集合实现类,主要取决于业务操作特点:
1) 先判断存储的类型(一组对象[单列]或者一组键值对[双列])
2) 一组对象:collection接口
允许重复:list
增删多:LinkedList(底层维护了一个双向链表)
不允许重复:Set
无序:HashSet
排序:TreeSet
3) 一组键值对:Map
键无序:HashMap(哈希表,jdk7:数组+链表,jdk8:数组+链表+红黑树)
键排序:TreeMap
键插入和取出一致:LinkedHashMap
读取文件:properties
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() {
@Override
public 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)]