概念类
一、数组和集合的区别
1.长度:数组长度是固定的,一旦创建无法改变;集合长度可变,可随时动态增删元素。
2.存储内容:数组可以存储基本类型和引用类型;集合只能存储引用类型。
3.类型限制:数组只能存储同一种类型的元素;集合不指定泛型可以存储任意对象,加泛型后可以限制存储类型。
二、Java中的集合

Java集合的核心是Collection和Map两大根接口,它们最本质的区别是Collection存的是单个元素,而Map存的是Key-Value形式的键值对。
集合的三个派系为List、Set和Map。
List:有序的、可重复的,按照插入顺序保存,通过索引(下表)访问,允许元素重复,主要实现类有ArrayList和LinkedList。
ArrayList:底层为动态数组,查询快(随机访问)但增删慢(需要移动元素),适合读多写少。
LinkedList:底层为双向链表,查询慢(需要便利)但增删快(只改指针),适合写多都少。
Set:无序,不可重复,不允许重复元素,无序是指不保证插入顺序,没有索引。常见实现类有HashSet、TreeSet和LinkedHashSet。
HashSet:基于HashMap实现,HashMap的Key即HashSet存储的元素,利用哈市Code()和equels()保证唯一性。
TreeSet:基于TreeMap实现,用的红黑树结构,会按照元素大小自动排序。
LinkedHashSet:继承自HashSet,使用双向链表维护元素插入顺序
Map:键值对,键唯一。Key唯一,Value可重复。主要实现由HashMap、LinkedHashMap、TreeMap、和Hashtable。
HashMap:JDK1.8后底层为数组+链表+红黑树。当链表长度大于阈值(默认为8)时,链表会转化为红黑树来提高查询效率。
LinkedHashMap:继承自HashMap,增加了一条双向链表,保证了键值对的插入顺序。
Hashtable:数组+链表组成的,数组是 HashTable 的主体,链表则是主要为了解决哈希冲突而存在的。
TreeMap:红黑树,自平衡的二叉查找树,自动排序(按Key排序)。
三、Java中线程安全的集合
Java.util包中线程安全的主要有两个。线程安全,但性能低下。(旧版)
Vector:线程安全的动态数组,内部方法基本都经过synchronized修饰。
Hashtable:线程安全的哈希表,HashTable 的加锁方法是给每个方法加上 synchronized 关键字。
java.util.concurrent 包提供的都是线程安全的集合:
1.并发List:
CopyOnWriteArrayList:写时复制,写加锁,读不加锁,适合读多写少。
写操作:
1.加锁,保证只有一个线程写
2.复制一份新数组
3.在新数组中修改
4.把引用指向新数组
读操作:不加锁,直接读。
2.并发Set:
CopyOnWriteArraySet:底层就是CopyOnWriteArrayList,线程安全,适合读多写少
ConcurrentSkipListSet:是线程安全的有序的集合。底层是使用ConcurrentSkipListMap实现。
3.并发Map:
ConcurrentHashMap:
JDK7以前加的是分段锁Sement(默认16段),每段一把锁,支持16个线程并发写。
JDK8以后取消了分段锁Sement。
结构为数组+链表+红黑树。
数组:table,真正存数据。
链表:哈希冲突时拉链。
红黑树:链表太长时优化查询。链表长度≥8且数组长度≥64–>红黑树。树节点≤6–>链表
线程安全的实现:
数组位置为空时,用CAS尝试插入,不加锁;不为空,用synchronized锁链表/树的头节点。
ConcurrentSkipListMap:实现了一个基于SkipList(跳表)算法的可排序的并发集合,SkipList是一种可以在对数预期时间内完成搜索、插入、删除等操作的数据结构,通过维护多个指向其他元素的“跳跃”链接来实现高效查找。
四、Collections和Collection的区别
Collection是一个接口,它是所有集合类的基础接口。它定义了一组通用的操作和方法,如添加、删除、遍历等,用于操作和管理一组对象。Collection接口有许多实现类,如List、Set和Queue等。
而Collections是一个工具类,位于java.util包中。它提供了一系列静态方法,用于对集合进行操作和算法。Collections类中的方法包括排序、查找、替换、反转、随机化等等,这些方法可以对实现了Collection接口的集合进行操作,如List和Set。
五、集合的遍历方法
1.普通for循环:可以使用带有索引的普通 for 循环来遍历 List。
import java.util.ArrayList;
import java.util.List;
public class ListForLoopExample {
public static void main(String[] args) {
// 创建并初始化一个List
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
fruits.add("Grape");
// 使用普通for循环遍历List
for (int i = 0; i < fruits.size(); i++) {
String fruit = fruits.get(i);
System.out.println("Fruit at index " + i + ": " + fruit);
}
}
}
2.增强for:用于循环访问数组或集合中的元素。
import java.util.ArrayList;
import java.util.List;
public class ListForLoopExample {
public static void main(String[] args) {
// 创建并初始化一个List
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
fruits.add("Grape");
// 使用普通for循环遍历List
for (int i = 0; i < fruits.size(); i++) {
String fruit = fruits.get(i);
System.out.println("Fruit at index " + i + ": " + fruit);
}
}
}
3.迭代器:可以使用迭代器来遍历集合,特别适用于需要删除元素的情况。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
public static void main(String[] args) {
// 创建集合并添加元素
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 获取迭代器
Iterator<String> iterator = list.iterator();
// 使用迭代器遍历集合
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
4.for-each:Java 8引入了 forEach 方法,可以对集合进行快速遍历。
import java.util.ArrayList;
import java.util.List;
public class ForEachExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
for (String fruit : fruits) {
System.out.println(fruit);
}
}
}

网硕互联帮助中心




评论前必须登录!
注册