Java 中的类型(通过 单列集合Set 引出)
Java 中的类型可以分为 基本类型 和 引用类型 两大类,其中集合类型属于引用类型的重要组成部分。以下是详细分类:
一、基本类型(Primitive Types)
基本类型是 Java 内置的基础数据类型,直接存储值(而非对象),共有 8 种:
- 整数类型:
byte
(1 字节,范围:-128 ~ 127)short
(2 字节,范围:-32768 ~ 32767)int
(4 字节,范围:-2³¹ ~ 2³¹-1,最常用)long
(8 字节,范围:-2⁶³ ~ 2⁶³-1,需加后缀L
,如100L
)
- 浮点类型:
float
(4 字节,单精度,需加后缀F
,如3.14F
)double
(8 字节,双精度,默认浮点类型,如3.14
)
- 字符类型:
char
(2 字节,存储 Unicode 字符,如'A'
、'中'
)
- 布尔类型:
boolean
(1 字节,值为true
或false
,用于逻辑判断)
二、引用类型(Reference Types)
引用类型存储的是对象的引用(内存地址),而非对象本身。主要包括:
1. 类(Class)
- 自定义类:如
User
、Order
、Permission
等你自己定义的类。 - 系统内置类:如
String
(字符串)、Integer
(整数包装类)、Date
(日期)等。
2. 接口(Interface)
- 系统内置接口:如
List
、Set
、Map
(集合框架的核心接口)、Runnable
(多线程接口)等。 - 自定义接口:如
PermissionService
、OrderRepository
等。
3. 数组(Array)
- 存储相同类型元素的容器,如
int[]
(整数数组)、String[]
(字符串数组)、User[]
(对象数组)。
4. 枚举(Enum)
- 固定常量集合,如之前提到的
PermissionName
枚举(ORDER_CREATE
、ORDER_READ
等)。
5. 注解(Annotation)
- 用于标记或配置代码的特殊类型,如
@Entity
、@RequestMapping
等。
三、集合类型(Collection Types)
集合类型是 引用类型中专门用于存储多个元素的容器,属于 java.util
包下的接口及实现类,主要分为两大类:
1. 单列集合(Collection
接口体系)
存储单个元素的集合,核心接口是 Collection
,主要子接口:
List
:有序、可重复的集合(允许元素重复,按插入顺序保存)- 实现类:
ArrayList
(基于数组,查询快)、LinkedList
(基于链表,增删快)、Vector
(线程安全,效率低)。 - 用途:如存储订单列表、用户列表(需要保留顺序,允许重复)。
- 实现类:
Set
:无序、不可重复的集合(不允许元素重复,无固定顺序)- 实现类:
HashSet
(基于哈希表,效率高)、LinkedHashSet
(保留插入顺序)、TreeSet
(自动排序)、EnumSet
(存储枚举)。 - 用途:如存储角色的权限集合(不允许重复权限)、去重场景。
- 实现类:
Queue
:队列(先进先出,FIFO)- 实现类:
LinkedList
(双端队列)、PriorityQueue
(优先级队列)。 - 用途:如任务调度、消息队列。
- 实现类:
2. 双列集合(Map
接口体系)
存储键值对(key-value
)的集合,核心接口是 Map
,每个元素包含一个键(key
)和一个值(value
):
- 实现类:
HashMap
(基于哈希表,键无序,效率高)LinkedHashMap
(键保留插入顺序)TreeMap
(键自动排序)Hashtable
(线程安全,效率低)
- 用途:如存储用户 ID 与用户对象的映射(
key=用户ID
,value=User对象
)、配置参数(key=参数名
,value=参数值
)。
四、总结
Java 类型的整体分类如下:
plaintext
Java 类型
├─ 基本类型(8种):byte、short、int、long、float、double、char、boolean
└─ 引用类型
├─ 类(Class):自定义类、String 等
├─ 接口(Interface):List、Set、Map 等
├─ 数组(Array):int[]、User[] 等
├─ 枚举(Enum):PermissionName 等
├─ 注解(Annotation):@Entity 等
└─ 集合类型(属于接口/类的实现)
├─ 单列集合(Collection):List、Set、Queue
└─ 双列集合(Map):HashMap、TreeMap 等
其中,集合类型是开发中最常用的引用类型之一,用于高效管理多个元素(如权限集合、订单列表、键值对配置等),根据是否允许重复、是否需要顺序等需求选择具体实现类即可。
各实现类对比表
实现类 | 底层结构 | 排序性 | 线程安全 | 允许 null | 典型场景 |
---|---|---|---|---|---|
HashSet |
哈希表 | 无序 | 否 | 是(1 个) | 普通去重场景 |
TreeSet |
红黑树 | 有序 | 否 | 否 | 需要排序的场景 |
LinkedHashSet |
哈希表 + 双向链表 | 插入序 | 否 | 是(1 个) | 需要保持顺序的去重场景 |
EnumSet |
位向量 | 枚举序 | 否 | 否 | 枚举类型集合 |
CopyOnWriteArraySet |
数组(写时复制) | 插入序 | 是 | 是 | 多线程读多写少场景 |
在 Java 中,Set
接口有多个实现类,各自具有不同的特性和适用场景,除了HashSet
之外,常用的还有以下几种:
1. TreeSet
- 特性:
- 基于红黑树(一种自平衡二叉查找树)实现
- 元素会按照自然顺序(如数字从小到大、字符串字典序)或自定义排序规则(通过
Comparator
)自动排序 - 不允许
null
值(添加null
会抛NullPointerException
)
- 适用场景:
- 需要对元素进行排序的场景(如排行榜、有序列表)
- 频繁需要范围查询(如 “获取大于 X 的所有元素”)
- 示例:
Set<Integer> treeSet = new TreeSet<>(); treeSet.add(3); treeSet.add(1); treeSet.add(2); System.out.println(treeSet); // 输出 [1, 2, 3](自动排序)
2. LinkedHashSet
特性:
- 基于哈希表(
HashMap
)+ 双向链表实现 - 保留元素的插入顺序(遍历顺序与添加顺序一致)
- 允许
null
值(仅允许一个null
) - 性能略低于
HashSet
(因为需要维护链表),但高于TreeSet
- 基于哈希表(
适用场景:
- 需要保证元素顺序的去重场景(如历史记录、日志顺序)
示例:
java
运行
Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("b"); linkedHashSet.add("a"); linkedHashSet.add("c"); System.out.println(linkedHashSet); // 输出 [b, a, c](保持插入顺序)
3. EnumSet
特性:
- 专门用于存储枚举类型的元素,是一个抽象类,通过静态方法(如
allOf()
、of()
)创建实例 - 内部以位向量形式存储,性能极高(比
HashSet
更高效) - 不允许
null
值,元素必须是同一枚举类的实例
- 专门用于存储枚举类型的元素,是一个抽象类,通过静态方法(如
适用场景:
- 需要操作枚举常量集合的场景(如权限控制中的枚举权限集合)
示例:
java
运行
// 假设有一个权限枚举PermissionEnum enum PermissionEnum { ORDER_CREATE, ORDER_READ, ORDER_UPDATE } Set<PermissionEnum> enumSet = EnumSet.of(PermissionEnum.ORDER_CREATE, PermissionEnum.ORDER_READ); System.out.println(enumSet); // 输出 [ORDER_CREATE, ORDER_READ]
4. CopyOnWriteArraySet
特性:
- 基于
CopyOnWriteArrayList
实现,是线程安全的Set
- 内部通过 “写时复制” 机制保证线程安全:修改集合时会创建底层数组的副本,读写分离
- 适合读多写少的场景,写入操作效率低(因为要复制数组)
- 基于
适用场景:
- 多线程环境下,频繁读取但很少修改的集合(如配置项集合)
示例:
java
运行
Set<String> copySet = new CopyOnWriteArraySet<>(); copySet.add("a"); copySet.add("b");
示例 1:使用
HashSet
存储用户标签(去重)
场景:给用户添加兴趣标签,确保标签不重复
java
运行
import java.util.HashSet;
import java.util.Set;
public class UserTagExample {
public static void main(String[] args) {
// 创建HashSet存储标签(自动去重)
Set<String> userTags = new HashSet<>();
// 添加标签(故意重复添加"旅行")
userTags.add("音乐");
userTags.add("旅行");
userTags.add("阅读");
userTags.add("旅行"); // 重复添加,会被自动忽略
// 打印结果(无序,无重复)
System.out.println("用户标签:" + userTags);
// 输出可能为:用户标签:[音乐, 旅行, 阅读](顺序不固定)
// 检查是否包含某个标签
boolean hasMusic = userTags.contains("音乐");
System.out.println("是否喜欢音乐:" + hasMusic); // 输出:true
// 移除标签
userTags.remove("阅读");
System.out.println("移除阅读后的标签:" + userTags); // [音乐, 旅行]
}
}
示例 2:使用 LinkedHashSet
记录访问历史(保留顺序)
场景:记录用户访问过的页面 URL,需要保持访问顺序且去重
java
运行
import java.util.LinkedHashSet;
import java.util.Set;
public class VisitHistoryExample {
public static void main(String[] args) {
// 创建LinkedHashSet存储访问历史(保留插入顺序)
Set<String> visitHistory = new LinkedHashSet<>();
// 模拟用户访问页面
visitHistory.add("/home");
visitHistory.add("/product/123");
visitHistory.add("/cart");
visitHistory.add("/home"); // 重复访问首页,自动去重但不改变顺序
// 打印历史(顺序与添加顺序一致)
System.out.println("访问历史:");
for (String url : visitHistory) {
System.out.println("- " + url);
}
// 输出:
// - /home
// - /product/123
// - /cart
}
}
示例 3:使用 TreeSet
存储成绩并排序
场景:存储学生成绩,自动按分数从低到高排序
java
运行
import java.util.TreeSet;
import java.util.Set;
public class ScoreSortExample {
public static void main(String[] args) {
// 创建TreeSet存储成绩(自动排序)
Set<Integer> scores = new TreeSet<>();
// 添加成绩(无序添加)
scores.add(85);
scores.add(92);
scores.add(78);
scores.add(92); // 重复成绩,自动去重
// 打印结果(自动按自然顺序排序)
System.out.println("成绩排序:" + scores); // 输出:[78, 85, 92]
// 自定义排序(按分数从高到低,需要传入Comparator)
Set<Integer> descendingScores = new TreeSet<>((a, b) -> b - a);
descendingScores.addAll(scores);
System.out.println("成绩倒序:" + descendingScores); // 输出:[92, 85, 78]
}
}
示例 4:使用 EnumSet
管理权限枚举
场景:用枚举表示系统权限,用 EnumSet
高效管理角色权限
java
运行
import java.util.EnumSet;
import java.util.Set;
// 定义权限枚举
enum Permission {
READ, WRITE, DELETE, ADMIN
}
public class PermissionExample {
public static void main(String[] args) {
// 创建EnumSet存储"普通用户"权限
Set<Permission> userPermissions = EnumSet.of(Permission.READ, Permission.WRITE);
// 创建EnumSet存储"管理员"权限(包含所有权限)
Set<Permission> adminPermissions = EnumSet.allOf(Permission.class);
// 检查权限
boolean canDelete = userPermissions.contains(Permission.DELETE);
System.out.println("普通用户能否删除:" + canDelete); // 输出:false
System.out.println("管理员权限:" + adminPermissions);
// 输出:[READ, WRITE, DELETE, ADMIN](按枚举定义顺序)
}
}
示例 5:使用 CopyOnWriteArraySet
处理多线程场景
场景:多线程环境下,多个线程同时读取和偶尔修改的集合(如在线用户列表)
java
运行
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
public class ThreadSafeSetExample {
public static void main(String[] args) {
// 创建线程安全的Set
Set<String> onlineUsers = new CopyOnWriteArraySet<>();
// 模拟多线程添加用户
new Thread(() -> onlineUsers.add("user1")).start();
new Thread(() -> onlineUsers.add("user2")).start();
new Thread(() -> onlineUsers.add("user1")).start(); // 重复添加,自动去重
// 等待线程执行完成(简化处理,实际需用同步工具)
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println("在线用户:" + onlineUsers); // 输出:[user1, user2](顺序可能不同)
}
}
各示例总结
实现类 | 核心特点 | 示例场景 |
---|---|---|
HashSet |
无序、去重、效率高 | 存储标签、去重数据 |
LinkedHashSet |
保留插入顺序、去重 | 访问历史、有序去重 |
TreeSet |
自动排序、去重 | 成绩排名、有序集合 |
EnumSet |
专门存储枚举、效率极高 | 权限管理、枚举常量集合 |
CopyOnWriteArraySet |
线程安全、读多写少 | 多线程环境下的共享集合 |
本作品采用《CC 协议》,转载必须注明作者和本文链接