Java集合
概述
- 数组和集合的元素存储的个数问题
- 数组定义后类型确定,长度固定
- 集合类型可以不固定,大小是可变的
- 数组和集合存储元素的类型问题
- 基本类型和引用类型的数据数组都可以存储
- 集合只能存储引用类型的数据
- 数组和集合适用的场景
- 数组适合数据个数和类型确定的场景
- 集合和C语言的链表很像,适合数据个数不确定,且要做增删元素的场景
Collection集合
特点
Collection是单列集合,每个元素只包含一个值,Map是双列集合,每个元素包含两个值(键值对)
-
List系列集合:添加的元素有序、可重复、有索引
-
Set系列集合:添加的元素无序、不重复、无索引
-
HashSet:无序、不重复、无索引;采取哈希表存储数据,从JDK1.8开始采用数组+链表+红黑树组成。
让HashSet去除自定义类重复:重写equals()和hashCode()方法
-
LinkedHashSet:有序、不重复、无索引,在哈希表的基础上将每个元素之间用双链表连接,记录存储的顺序从而实现有序
-
TreeSet:按照大小默认升序排序、不重复、无索引,基于红黑树实现排序,增删改查性能较好
-
遍历集合
iterator()方法:返回一个迭代器对象,可以实现对集合的遍历
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
增强型for循环
- 既可以遍历集合也可以遍历数组,其内部原理是一个Iterator迭代器,遍历集合相当于是迭代器的简化写法
- 实现Iterable接口的类才可以使用迭代器和增强for
for (String s : list) {
System.out.println(s);
}
Lambda表达式遍历集合
forEach(Consumer<? super T> action)方法
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// 可以简化为:
list.forEach(s -> System.out.println(s));
// 极简写法:
list.forEach(System.out::println);
for循环(List集合存在索引)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
存储自定义类型的对象
ArrayList<Movie> movies = new ArrayList<>();
movies.add(new Movie("《你好,李焕英》", 95, "郑秀文"));
movies.forEach(System.out::println);
集合的并发修改异常问题的解决方法
在用迭代器和(增强型)for循环遍历集合且直接用集合删除元素时可能出现
错误示例:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("123");
list.add("123");
list.add("345");
list.forEach(s -> {
if (s.equals("123")) {
list.remove("123");
}
});
}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList.forEach(ArrayList.java:1262)
at com.collection.Demo1.main(Demo1.java:15)
由于forEach在迭代下一个元素会给指针进行+1操作,remove也相当于进行+1操作,如果此时要删除两个相邻的重复的元素就会造成漏删的情况。
解决方法:使用迭代器的remove()方法或手动在for循环if内部进行-1操作
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
if (iterator.next().equals("123")) {
iterator.remove();
}
}
Map集合
特点
Map集合是一种双列集合,每个元素包含两个数据(键值对),格式为key=value
体系特点
- Map集合的键是无序、不重复、无索引的(Set集合底层由Map集合实现),值可以重复
- Map集合后面重复的键所对应的值会覆盖前面重复键的值
- Map集合的键值对都可以为null
实现类特点(和Set基本相同)
- HashMap:无序、不重复、无索引,值可以重复
- LinkedHashMap:有序、不重复、无索引,值可以重复
- TreeMap:排序、不重复、无索引,值不做要求
API
三种遍历方法
Map<String, Integer> info = new HashMap<>();
info.put("java", 4);
info.put("asp", 2);
// 1、键找值
Set<String> selects = info.keySet();
for (String select : selects) {
System.out.println(select + info.get(select));
}
// 2、键值对
Set<Map.Entry<String, Integer>> entries = info.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey() + entry.getValue());
}
// 3、lambda表达式
info.forEach((k,v)-> System.out.println(k+v));
Properties
-
Properties其实就是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用。
-
Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
-
属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。
Properties和IO流结合的方法
构造器 | 说明 |
---|---|
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
public Object setProperty(String key, String value) | 保存键值对(put) |
public String getProperty(String key) | 使用此属性列表中指定的键搜索属性值 (get) |
public Set |
所有键的名称的集合 (keySet()) |
泛型
泛型类
-
定义类时同时定义了泛型的类就是泛型类。
-
泛型类的格式:修饰符 class 类名<泛型变量>{}
public class MyArrayList<T>{} //此处泛型变量T可以随便写为任意标识,常见的如E、T、K、V等
-
作用:编译阶段可以指定数据类型,类似于集合的作用
泛型方法
-
定义方法时同时定义了泛型的方法就是泛型方法。
-
泛型方法的格式:修饰符 <泛型变量> 方法返回值 方法名称(形参列表){}
public <T> void show(T t){}
-
作用:方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性
泛型接口
-
使用了泛型定义的接口就是泛型接口。
-
泛型接口的格式:修饰符 interface 接口名称<泛型变量>{}
public interface Data<E>{}
-
作用:泛型接口可以让实现类选择当前功能需要操作的数据类型
泛型通配符
? 可以在使用泛型的时候代表一切类型
泛型的上下限:
- ? extends Car:?必须是Car或者其子类 泛型上限
- ? super Car : ?必须是Car或者其父类 泛型下限
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南