一、关于java.util包
1.1简介
java.util
包是Java标准类库中的一个非常重要的组成部分,它提供了一系列对程序开发非常有用的类和接口。这个包主要包含集合框架、日期时间类、事件模型、随机数生成器以及其他实用工具类。
1.2常用类及接口
-
1. 集合框架 – 集合框架是
java.util
包中最重要的部分之一,它提供了一系列的数据结构和算法,帮助开发者存储和操作数据集合。 -
•
Collection
– 集合框架的根接口,代表一组对象,这些对象称为元素。 -
•
List
– 有序集合,每个元素都有其在集合中的特定位置。 -
•
Set
– 不允许重复元素的集合。 -
•
Map
– 键值对的集合,也称为字典或哈希表。 -
•
ArrayList
– 实现了List
接口的动态数组。 -
•
LinkedList
– 实现了List
接口的双向链表。 -
•
HashSet
– 实现了Set
接口的哈希表集合。 -
•
LinkedHashSet
– 继承自HashSet
,维护元素插入顺序的集合。 -
•
TreeSet
– 实现了Set
接口的基于红黑树的集合,元素按自然顺序或自定义顺序排序。 -
•
HashMap
– 实现了Map
接口的哈希表。 -
•
LinkedHashMap
– 继承自HashMap
,维护元素插入顺序或访问顺序的映射。 -
•
TreeMap
– 实现了Map
接口的基于红黑树的映射,键按自然顺序或自定义顺序排序。 -
2. 日期时间类 – 提供了操作日期和时间的类。
-
•
Date
– 表示特定的瞬间,精确到毫秒。 -
•
Calendar
– 可以用于日期的计算,比如添加或减少天数、获取星期等。 -
•
TimeZone
– 表示时区。 -
•
Locale
– 表示特定的语言、国家和区域的设置。 -
3. 事件模型 – 用于处理事件和监听器模式。
-
•
EventObject
– 所有事件的超类。 -
•
EventListener
– 所有事件监听器接口的标记接口。 -
•
EventSource
– 能够生成事件的对象。 -
4. 随机数生成器 – 提供随机数生成的功能。
-
•
Random
– 基于线性同余生成器的随机数生成器。 -
•
java.security.SecureRandom
– 提供更安全的随机数生成。 -
5. 其他实用工具类 – 提供了一系列静态方法,用于执行各种任务。
-
•
Arrays
– 提供静态方法来操作数组,如排序、搜索等。 -
•
Collections
– 提供静态方法来操作集合,如排序、搜索等。 -
•
Objects
– 提供静态方法来操作对象,如空安全的比较、计算哈希码等。 -
•
Timer
– 可以调度任务在将来的某个时间点执行。 -
•
UUID
– 用于生成UUID(通用唯一标识符)。
1.3时间
1.3.1Date类
简介
java.util.Date
类在Java中用于表示特定的瞬间,精确到毫秒。
构造方法
Date类提供了多个构造方法,其中比较常用的有:
-
•
Date()
: 创建一个表示当前日期和时间的Date对象。 -
•
Date(long date)
: 根据指定的毫秒数创建一个Date对象,该毫秒数表示自1970年1月1日00:00:00 GMT以来的毫秒数。
方法
-
•
getTime()
: 返回自1970年1月1日00:00:00 GMT以来的毫秒数。 -
•
toString()
: 将Date对象转换为String类型。 -
•
before(Date when)
: 比较两个日期,如果当前日期早于参数日期,则返回true。 -
•
after(Date when)
: 比较两个日期,如果当前日期晚于参数日期,则返回true。
示例
import java.util.Date;
public class Main {
public static void main(String[] args) {
// 创建表示当前日期和时间的Date对象
Date currentDate = new Date();
System.out.println("当前日期和时间:" + currentDate);
// 创建一个指定日期和时间的Date对象
Date specificDate = new Date(1630454400000L); // 对应2022年9月2日12:00:00
System.out.println("指定日期和时间:" + specificDate);
// 判断日期先后
if (currentDate.after(specificDate)) {
System.out.println("当前日期晚于指定日期");
} else {
System.out.println("当前日期早于指定日期");
}
}
}
1.3.2TimeZone类
简介
在Java中,TimeZone类用于表示时区信息,并提供了对时区进行操作的方法。它可以帮助我们在处理日期和时间时,将时间转换为特定时区下的时间,并进行时区之间的转换。
构造方法
TimeZone类是一个抽象类,不能直接实例化,但它提供了一些静态方法来获取TimeZone对象:
-
•
getTimeZone(String ID)
: 返回指定ID对应的TimeZone对象,例如:”GMT+08:00″。 -
•
getDefault()
: 返回默认的TimeZone对象,通常是系统默认的时区。
方法
TimeZone类提供了一些常用的方法,包括但不限于:
-
•
getDisplayName()
: 返回时区的名称。 -
•
getID()
: 返回时区的ID。 -
•
getOffset(long date)
: 返回指定日期的偏移量,单位为毫秒。 -
•
inDaylightTime(Date date)
: 判断指定日期是否在夏令时时段内。 -
•
getAvailableIDs()
: 返回所有可用的时区ID数组。
示例
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
// 获取默认的时区
TimeZone defaultTimeZone = TimeZone.getDefault();
System.out.println("默认时区:" + defaultTimeZone.getDisplayName());
// 获取指定ID的时区
TimeZone gmt8TimeZone = TimeZone.getTimeZone("GMT+08:00");
System.out.println("GMT+08:00时区:" + gmt8TimeZone.getDisplayName());
// 进行时区转换
Date currentDate = new Date();
System.out.println("当前日期和时间:" + currentDate);
System.out.println("当前日期和时间在GMT+08:00时区:" + formatDateInTimeZone(currentDate, gmt8TimeZone));
}
// 将日期转换为指定时区下的日期
private static Date formatDateInTimeZone(Date date, TimeZone timeZone) {
long timeInUTC = date.getTime() - timeZone.getRawOffset();
return new Date(timeInUTC);
}
}
1.4集合框架
集合框架 – 集合框架是java.util
包中最重要的部分之一,它提供了一系列的数据结构和算法,帮助开发者存储和操作数据集合。
-
•
Collection
– 集合框架的根接口,代表一组对象,这些对象称为元素。 -
•
List
– 有序集合,每个元素都有其在集合中的特定位置。 -
•
Set
– 不允许重复元素的集合。 -
•
Map
– 键值对的集合,也称为字典或哈希表。 -
•
ArrayList
– 实现了List
接口的动态数组。 -
•
LinkedList
– 实现了List
接口的双向链表。 -
•
HashSet
– 实现了Set
接口的哈希表集合。 -
•
LinkedHashSet
– 继承自HashSet
,维护元素插入顺序的集合。 -
•
TreeSet
– 实现了Set
接口的基于红黑树的集合,元素按自然顺序或自定义顺序排序。 -
•
HashMap
– 实现了Map
接口的哈希表。 -
•
LinkedHashMap
– 继承自HashMap
,维护元素插入顺序或访问顺序的映射。 -
•
TreeMap
– 实现了Map
接口的基于红黑树的映射,键按自然顺序或自定义顺序排序。
在之前章节有详细介绍,这里不再赘述
1.5接口
1.5.1Comparator
简介
java.util.Comparator
接口是一个用于定义对象比较规则的接口。它允许开发者自定义对象比较逻辑,这在排序集合或者对对象进行排序操作时非常有用。Comparator
接口提供了一种灵活的比较机制,使得可以对任何对象进行排序,而不仅仅是实现了特定比较方法的对象。
方法
-
•
reversed()
: 返回与当前比较器相反的比较器(逆序排列)。 -
•
thenComparing()
: 返回一个复合比较器,用于对两个对象进行多重比较。 -
•
nullsFirst()
: 返回一个可将null元素排在非null元素之前的比较器。 -
•
nullsLast()
: 返回一个可将null元素排在非null元素之后的比较器。 -
• compare(T o1, T o2) – 比较两个对象
o1
和o2
。返回值是一个整数,它表示第一个参数相对于第二个参数是小于、等于还是大于:如果o1
小于o2
,返回负整数;如果o1
等于o2
,返回零;如果o1
大于o2
,返回正整数。
示例
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Student {
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(1, "Alice"));
studentList.add(new Student(2, "Bob"));
studentList.add(new Student(3, "Charlie"));
// 使用Comparator进行排序
Collections.sort(studentList, Comparator.comparing(Student::getName));
// 输出排序后的结果
for (Student student : studentList) {
System.out.println("ID: " + student.getId() + ", Name: " + student.getName());
}
}
}
在这个示例中,首先定义了一个Student类,然后创建了一个包含Student对象的列表studentList。接着,我们使用Comparator.comparing方法根据学生姓名对列表进行排序,最终输出排序后的结果。
1.5.2Iterator
简介
在Java中,Iterator接口提供了一种用于遍历集合元素的统一方式。通过实现Iterator接口,我们可以对集合中的元素进行迭代访问,而不需要了解集合的具体实现方式。
方法
-
•
boolean hasNext()
: 如果仍有元素可以迭代,则返回true,否则返回false。 -
•
E next()
: 返回迭代的下一个元素。 -
•
void remove()
: 从迭代器指向的集合中移除迭代器最后返回的元素(可选操作)。
示例
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
// 获取Iterator对象并进行迭代
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
System.out.println(name);
}
}
}
在这个示例中,首先创建了一个包含字符串元素的ArrayList names。然后,我们通过调用names的iterator()方法获得了一个Iterator对象,并使用while循环和next()方法对集合进行迭代访问,最终输出了每个元素的值。这种方式能够适用于任何实现了Iterable接口的集合类,如List、Set等。
1.5.3EventListener
简介
在Java中,EventListener接口是用于实现事件监听器的接口,用于处理各种类型的事件。通过实现EventListener接口,可以创建自定义的事件监听器,用于监听和响应特定类型的事件。
方法
EventListener
接口本身不定义任何方法,但是它有很多子接口,这些子接口定义了事件处理方法。例如:
-
•
ActionListener
:用于处理动作事件,如按钮点击。 -
•
ChangeListener
:用于监听ChangeEvent
,当事件源的状态发生变化时触发。 -
•
MouseListener
:用于处理鼠标事件,如鼠标点击、移动等。 -
•
MouseMotionListener
:用于处理鼠标移动和拖动事件。 -
•
KeyListener
:用于处理键盘事件,如按键和释放。
示例
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MyMouseListener implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse Clicked at: (" + e.getX() + ", " + e.getY() + ")");
}
@Override
public void mousePressed(MouseEvent e) {
// 实现鼠标按下时的处理逻辑
}
@Override
public void mouseReleased(MouseEvent e) {
// 实现鼠标释放时的处理逻辑
}
@Override
public void mouseEntered(MouseEvent e) {
// 实现鼠标进入组件时的处理逻辑
}
@Override
public void mouseExited(MouseEvent e) {
// 实现鼠标退出组件时的处理逻辑
}
}
在这个示例中,创建了一个名为MyMouseListener的类,实现了MouseListener接口,该接口定义了处理鼠标事件的方法。我们重写了MouseListener接口中的几个方法,比如mouseClicked,在该方法中实现了鼠标点击事件发生时的逻辑。通过这种方式,我们可以自定义事件监听器来响应特定的事件。
1.6工具类
1.6.1UUID类
简介
java.util.UUID
类是用于生成通用唯一标识符(UUID)的工具类。UUID是一种标准化的32位字符格式,用于在分布式系统中唯一标识信息。UUID的设计目的是在所有计算机和系统上都能生成高度唯一的标识符,即使在不同的时间和空间中也是如此。
构造方法
UUID类提供了两种构造方法:
-
1.
UUID(long mostSignificantBits, long leastSignificantBits)
: 使用指定的最高有效位和最低有效位创建一个UUID对象。 -
2.
UUID(String name)
: 根据指定的字符串名称创建一个UUID对象。该字符串必须遵循UUID的标准格式,如 “550e8400-e29b-41d4-a716-446655440000″。 -
3. UUID() – 生成一个随机生成的UUID。
UUID randomUUID = new UUID();
方法
-
•
static UUID randomUUID()
: 静态方法,用于生成一个随机的UUID。 -
•
String toString()
: 将UUID转换为字符串表示形式。 -
•
int hashCode()
: 返回此UUID的哈希码值。 -
•
boolean equals(Object obj)
: 比较两个UUID对象是否相等。
示例
import java.util.UUID;
public class Main {
public static void main(String[] args) {
// 生成一个随机的UUID
UUID uuid = UUID.randomUUID();
// 将UUID转换为字符串表示形式
String uuidString = uuid.toString();
System.out.println("Random UUID: " + uuidString);
}
}
在这个示例中,通过调用UUID.randomUUID()
方法生成一个随机的UUID对象,然后通过调用toString()
方法将其转换为字符串表示形式,并最终输出到控制台上。这样我们就可以生成一个唯一的标识符,用于在系统中标识对象或实体。
1.6.2Random类
简介
java.util.Random
类是Java标准库中提供的一个随机数生成器。它用于生成伪随机数流,这些随机数在足够长的时间内看起来是随机的,但实际上是可以重现的,因为它们是由一个初始种子值(seed)确定的。
构造方法
-
1.
Random()
: 创建一个新的随机数生成器。 -
2.
Random(long seed)
: 使用指定的种子创建一个新的随机数生成器。使用相同的种子创建的Random对象将生成相同的随机数序列。
方法
-
•
int nextInt()
: 返回一个随机的int值。 -
•
int nextInt(int bound)
: 返回一个大于等于0且小于bound的随机int值。 -
•
double nextDouble()
: 返回一个随机的double值。 -
•
void nextBytes(byte[] bytes)
: 生成随机字节并将其放入提供的byte数组中。 -
•
boolean nextBoolean()
: 返回一个随机的boolean值。
示例
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
// 使用默认构造方法创建Random对象
Random random = new Random();
// 生成一个随机整数
int randomInt = random.nextInt();
System.out.println("Random integer: " + randomInt);
// 生成一个0到99之间的随机整数
int randomIntWithinRange = random.nextInt(100);
System.out.println("Random integer within range (0-99): " + randomIntWithinRange);
// 生成一个随机double值
double randomDouble = random.nextDouble();
System.out.println("Random double: " + randomDouble);
// 生成一个随机float值
float randomFloat = random.nextFloat();
System.out.println("Random float: " + randomFloat);
// 生成一个随机long值
long randomLong = random.nextLong();
System.out.println("Random long: " + randomLong);
// 生成一个随机boolean值
boolean randomBoolean = random.nextBoolean();
System.out.println("Random boolean (true or false): " + randomBoolean);
// 使用自定义种子值创建Random对象
Random randomWithSeed = new Random(123456L);
// 再次生成随机整数,由于种子值相同,结果也将相同
int sameRandomInt = randomWithSeed.nextInt();
System.out.println("Same random integer with seed 123456: " + sameRandomInt);
// 生成一个随机高斯分布值
double randomGaussian = random.nextGaussian();
System.out.println("Random Gaussian (normal distribution) value: " + randomGaussian);
}
}
在这个示例中,首先创建了一个默认的 Random
对象,并使用它来生成不同类型的随机数。 接着,我们创建了一个带有自定义种子值的 Random
对象,并展示了如何通过指定种子值来重现相同的随机数序列。 最后,我们打印了生成的随机数,展示了 Random
类的各种用途。
1.6.3Scanner类
简介
在Java中,Scanner类是用于读取用户输入的一个方便的类,它可以从标准输入流(如键盘输入)、文件或字符串中获取输入数据。Scanner类提供了多种方法来解析基本数据类型和字符串。
构造方法
-
1.
Scanner(InputStream source)
: 通过指定输入流创建一个Scanner对象,通常用于从标准输入流(System.in)读取用户输入。 -
2.
Scanner(File source)
: 通过指定文件创建一个Scanner对象,用于从文件中读取数据。 -
3.
Scanner(String source)
: 通过指定字符串创建一个Scanner对象,用于从字符串中读取数据。
方法
-
•
int nextInt()
: 读取下一个输入项并将其解释为int类型。 -
•
double nextDouble()
: 读取下一个输入项并将其解释为double类型。 -
•
String nextLine()
: 读取下一行输入。 -
•
boolean hasNext()
: 检查是否还有输入项可读。 -
•
void close()
: 关闭Scanner对象。
示例
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
// 创建Scanner实例,使用System.in作为输入源
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int integer = scanner.nextInt();
System.out.println("您输入的整数是:" + integer);
System.out.println("请输入一个浮点数:");
double doubleValue = scanner.nextDouble();
System.out.println("您输入的浮点数是:" + doubleValue);
System.out.println("请输入一个布尔值(true/false):");
boolean booleanValue = scanner.nextBoolean();
System.out.println("您输入的布尔值是:" + booleanValue);
System.out.println("请输入一个字符串:");
String string = scanner.nextLine();
System.out.println("您输入的字符串是:" + string);
// 关闭Scanner实例
scanner.close();
}
}
在这个示例中,首先创建了一个 Scanner
实例,它默认使用 System.in
作为输入源。 接着,我们使用 nextInt()
、nextDouble()
、nextBoolean()
和 nextLine()
方法从用户那里读取不同类型的输入,并打印出来。 最后,我们调用 close()
方法关闭 Scanner
实例,释放与它关联的资源。
1.7java.util.concurrent包
1.7.1简介
java.util.concurrent 包提供了在并发编程中使用的工具类和框架。它包含了一系列用于处理并发任务的实用工具,使得在多线程环境中编写高效、安全的代码变得更加简单。
以下是 java.util.concurrent 包中一些常用的类和接口:
-
1. Executor 框架:包括 Executor、ExecutorService 和 ScheduledExecutorService 接口,以及 Executors 工厂类。这些类允许你实现异步执行任务和控制执行过程。
-
2. 线程安全集合:java.util.concurrent 包中提供了一系列线程安全的集合类,如 ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet 等。这些集合类能够在多线程环境中安全地进行读写操作,避免了传统集合类在并发情况下可能出现的线程安全问题。
-
3. 同步器和锁:该包中还包含了一些同步器和锁的实现,如 ReentrantLock、ReadWriteLock、Condition 等,它们提供了更灵活的锁机制,能够满足不同的并发控制需求。
-
4. 并发工具类:java.util.concurrent 包还提供了一些并发编程中常用的工具类,比如 CountDownLatch、CyclicBarrier、Semaphore 等。这些工具类可以帮助协调多个线程之间的执行顺序和资源的访问。
总的来说,java.util.concurrent 包为 Java 程序员提供了丰富的并发编程工具,帮助开发者更加轻松地处理多线程编程中的挑战,提高了并发程序的性能和可靠性。通过合理地利用这些工具和框架,可以写出高效、可靠的并发程序。
1.7.2CompletableFuture类
简介
在Java中,CompletableFuture类提供了一种异步编程的方式,可以用于实现异步操作和构建复杂的异步流水线。它是Java 8引入的一个重要特性,用于简化并发编程。
java.util.concurrent 包中的 CompletableFuture 类是 Java 8 引入的一个类,用于支持异步编程和构建异步操作链。CompletableFuture 提供了一种简洁而强大的方式来处理异步任务的结果,以及对多个异步任务进行组合、串联和并发控制。
以下是 CompletableFuture 类的一些主要特点和用法:
-
1. 异步操作:CompletableFuture 可以表示一个异步计算的结果,通过 CompletableFuture 的方法可以注册回调函数,在异步任务执行完成后自动触发回调函数处理结果。
-
2. 组合操作:CompletableFuture 支持对多个 CompletableFuture 进行组合操作,包括 thenCombine、thenCompose、thenApplyAsync 等方法,可以串联多个异步任务,形成复杂的异步操作链。
-
3. 异常处理:CompletableFuture 允许你通过 exceptionally 或 handle 方法来处理异步任务中产生的异常,使得异常处理变得更加灵活。
-
4. 并发控制:CompletableFuture 提供了一些方法来实现并发控制,比如 allOf、anyOf 等,能够控制多个 CompletableFuture 的执行顺序和并发度。
-
5. 超时处理:CompletableFuture 支持设置超时时间,并在超时时执行特定的操作,避免任务长时间阻塞。
使用 CompletableFuture 可以简化异步编程的复杂性,让开发者能够更加方便地处理异步任务的结果和操作。通过链式调用和组合不同的 CompletableFuture 对象,可以构建出复杂的异步任务流水线,实现高效的并发编程。
总的来说,CompletableFuture 是 Java 中处理异步编程的重要工具,它提供了丰富的方法和功能,使得异步任务的管理和处理变得更加简单和高效。
构造方法
CompletableFuture类有多个静态工厂方法来创建CompletableFuture对象,其中最常用的包括:
-
1.
static CompletableFuture<Void> runAsync(Runnable runnable)
: 异步执行指定的Runnable任务,并返回一个CompletableFuture对象。 -
2.
static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
: 异步执行指定的Supplier任务,并返回一个CompletableFuture对象,该任务产生一个结果。
方法
-
•
CompletableFuture<T> thenApply(Function<? super T,? extends U> fn)
: 当前CompletableFuture计算完成时,对其结果执行给定的函数。 -
•
CompletableFuture<T> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
: 当前CompletableFuture计算完成时,对其结果执行给定的函数,该函数返回另一个CompletableFuture。 -
•
CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
: 当当前CompletableFuture计算完成或者抛出异常时,执行给定的函数。 -
•
static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
: 等待所有的CompletableFuture对象执行完毕。
示例
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建一个CompletableFuture对象,异步执行一个简单的任务
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Async task running in the background...");
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Async task completed.");
});
// 等待异步任务执行完毕
future.get(); // 这里会阻塞直到任务完成
System.out.println("Main thread continues to run...");
}
}
在这个示例中,首先使用CompletableFuture.runAsync()
方法创建了一个CompletableFuture对象,异步执行一个简单的任务。然后使用get()
方法等待异步任务执行完毕。在主线程中,我们打印了一条消息表明主线程继续执行。这样我们就可以利用CompletableFuture类方便地实现异步编程。
1.8java.util.stream
包
1.8.1简介
java.util.stream
包是 Java 8 引入的用于支持流式处理(Stream API)的包。该包提供了一组类和接口,用于对集合数据进行函数式操作,以实现更简洁、可读性更强的代码。
以下是 java.util.stream
包中一些常用的类和接口:
-
1. Stream:
Stream
接口代表一个元素序列,可以支持各种操作来处理这个序列,如过滤、映射、归约等。 -
2. Collectors:
Collectors
类包含了一系列静态工厂方法,用于生成常见的收集器实例,例如将流元素收集到列表、集合、映射等数据结构中。 -
3. IntStream, LongStream, DoubleStream:这些接口分别表示原始类型的流,提供了针对基本数据类型的特定操作。
-
4. ParallelStream:
ParallelStream
类支持并行流操作,可以加速处理大量数据的操作。
通过使用 java.util.stream
包中提供的类和接口,开发者可以利用流式处理来简化集合数据的操作、提高代码的可读性,并且能够更方便地进行并行处理以提升性能。这些功能使得 Java 编程变得更加灵活和强大。
1.8.2Collectors类
简介
Collectors
类是 Java 中 java.util.stream
包中的一个工具类,提供了一系列静态工厂方法,用于生成常见的收集器实例,以便在流式处理中对元素进行汇总和归约操作。
通过 Collectors
类,可以方便地将流中的元素收集到不同类型的数据结构中,比如集合(List、Set)、映射(Map)、字符串(joining)、统计信息(summarizingInt、summarizingDouble 等)等。这些收集器可以帮助简化代码,并支持并行处理以提高性能。
构造方法
在 Java 中,Collectors
类是一个工具类,它提供了一系列静态工厂方法来创建不同类型的收集器。因此,Collectors
类并没有公开的构造方法。相反,它提供了诸如 toList()
、toSet()
、toMap()
等静态方法,用于创建对应的收集器实例。
这些静态方法返回的是 Collector
接口的实例,Collector
接口定义了用于执行归约操作的方式,并可用于对输入的元素进行汇总。Collector
接口中有几个重要的方法,包括 supplier()
、accumulator()
、combiner()
和 finisher()
,它们定义了收集器的行为和属性。
因此,我们通常不需要直接构造 Collectors
类的实例,而是通过调用其提供的静态工厂方法来获取特定类型的收集器。这样可以更方便地对流中的元素进行汇总和归约操作。
方法
一些常用的 Collectors
方法包括:
-
•
toList()
: 将流中的元素收集到一个 List 中。 -
•
toSet()
: 将流中的元素收集到一个 Set 中。 -
•
toMap(keyMapper, valueMapper)
: 将流中的元素根据 keyMapper 和 valueMapper 转换为 Map。 -
•
joining()
: 将流中的元素连接成一个字符串。 -
•
groupingBy(classifier)
: 根据分类函数对流中的元素进行分组。 -
•
summarizingInt(), summarizingDouble(), summarizingLong()
: 用于统计流中元素的汇总信息,如 count、sum、min、max、average 等。
-
1. 将流中的元素收集到一个 List 中:
List<String> words = Arrays.asList("apple", "banana", "orange", "grape");
List<String> collectedList = words.stream()
.collect(Collectors.toList());
System.out.println(collectedList);
-
1. 将流中的元素连接成一个字符串:
List<String> words = Arrays.asList("apple", "banana", "orange", "grape");
String concatenatedString = words.stream()
.collect(Collectors.joining(", "));
System.out.println(concatenatedString);
-
1. 根据字符串长度将元素分组:
List<String> words = Arrays.asList("apple", "banana", "orange", "grape");
Map<Integer, List<String>> groupedByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(groupedByLength);
-
1. 计算元素的数量、总和、最小值、最大值和平均值:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
IntSummaryStatistics stats = numbers.stream()
.collect(Collectors.summarizingInt(Integer::intValue));
System.out.println("Count: " + stats.getCount());
System.out.println("Sum: " + stats.getSum());
System.out.println("Min: " + stats.getMin());
System.out.println("Max: " + stats.getMax());
System.out.println("Average: " + stats.getAverage());
这些示例展示了如何使用 Collectors
类中的一些常见方法来对流进行汇总操作。您可以根据具体的需求选择合适的收集器,并结合流操作来实现各种数据处理功能。
示例
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
// 创建一个包含一些整数的List
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用Collectors.toList()方法将Stream中的元素收集到List中
List<Integer> evenNumbers = numbers.stream()
.filter(num -> num % 2 == 0)
.collect(Collectors.toList());
System.out.println("Even numbers: " + evenNumbers);
// 使用Collectors.toSet()方法将Stream中的元素收集到Set中
Set<Integer> oddNumbers = numbers.stream()
.filter(num -> num % 2 != 0)
.collect(Collectors.toSet());
System.out.println("Odd numbers: " + oddNumbers);
// 使用Collectors.toMap()方法将Stream中的元素收集到Map中
Map<Integer, String> numberMap = numbers.stream()
.collect(Collectors.toMap(
num -> num,
num -> "Number: " + num
));
System.out.println("Number map: " + numberMap);
}
}
在这个示例中,首先创建了一个包含一些整数的List。然后使用Stream API对这个List进行操作,并利用Collectors
类的方法将Stream中的元素收集到不同的数据结构中,包括List、Set和Map。最后我们打印出了收集到的结果。
1.8.3Stream类
简介
在 Java 中,Stream 是 Java 8 引入的一个全新的抽象概念,它提供了一种高效且功能强大的数据处理方式。Stream 可以让你以一种声明式的方式处理集合数据,这种方式更加简洁、灵活,并且可以充分利用多核处理器的优势。
简单来说,Stream 提供了一种对集合进行批量操作的高级抽象,它可以让你通过一系列的操作(如过滤、映射、排序、归约等)来处理集合中的元素,而无需写显式的循环。
构造方法
从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> streamFromList = list.stream(); // 从List创建Stream
Stream<String> parallelStreamFromList = list.parallelStream(); // 从List创建并行Stream
从数组创建
String[] array = {"a", "b", "c"};
Stream<String> streamFromArray = Arrays.stream(array); // 从数组创建Stream
使用Stream.of()
Stream<String> streamOfElements = Stream.of("a", "b", "c"); // 使用Stream.of()创建Stream
使用Stream.iterate()
Stream<Integer> streamIterate = Stream.iterate(0, n -> n + 2).limit(5); // 使用Stream.iterate()创建Stream
使用Stream.generate()
Stream<Double> streamGenerate = Stream.generate(Math::random).limit(3); // 使用Stream.generate()创建Stream
方法
Stream 类提供了丰富的方法来支持对集合数据的高级操作,这些方法可以分为中间操作和终端操作两种类型。中间操作用于构建 Stream 流水线,而终端操作则触发实际的处理过程并产生结果。以下是一些常用的 Stream 方法:
中间操作:
-
1. filter(Predicate) :根据给定的条件过滤元素。
-
2. map(Function) :将元素按照指定规则转换。
-
3. flatMap(Function) :将流中的每个元素都转换成另一个流,然后把所有流连接成一个流。
-
4. distinct() :去除流中重复的元素。
-
5. sorted() :对流进行排序。
-
6. limit(long maxSize) :截断流,使其最多只包含指定数量的元素。
-
7. skip(long n) :跳过指定数量的元素,返回剩余的元素。
终端操作:
-
1. forEach(Consumer) :对流中的每个元素执行指定操作。
-
2. collect(Collector) :将流中的元素累积成一个结果容器,如 List、Map 等。
-
3. reduce(BinaryOperator) :用指定的二元运算符对流中的元素进行归约操作,得到一个最终结果。
-
4. count() :返回流中元素的总个数。
-
5. anyMatch(Predicate) :检查流中是否至少有一个元素满足给定条件。
-
6. allMatch(Predicate) :检查流中是否所有元素都满足给定条件。
-
7. noneMatch(Predicate) :检查流中是否没有元素满足给定条件。
-
8. findFirst() :返回流中的第一个元素。
-
9. findAny() :返回流中的任意一个元素。
除了上述方法之外,Stream 还提供了很多其他的操作,这些方法可以根据具体的需求进行组合和使用,以实现对集合数据的灵活处理。
示例
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Emma");
// 创建一个 Stream 对象,并通过 filter 操作筛选出包含字母“a”的名字
names.stream()
.filter(name -> name.contains("a"))
.forEach(System.out::println);
}
}
在这个示例中,首先创建了一个包含几个名字的 List。然后使用 stream()
方法将其转换为 Stream 对象,在 Stream 上调用 filter
方法,传入一个 Lambda 表达式作为条件,筛选出包含字母“a”的名字。最后,我们使用 forEach
方法打印筛选出的结果。
除了 filter
和 forEach
操作之外,Stream 还提供了很多其他的操作,如 map
、reduce
、sorted
等,通过这些操作,可以非常方便地进行数据处理和转换。
需要注意的是,Stream 的操作通常是惰性求值的,也就是说,在调用终结操作(如 forEach
)之前,中间操作(如 filter
、map
)不会立即执行,而是等到终结操作触发时才会执行。这种特性使得 Stream 在处理大规模数据时更加高效。
原文始发于微信公众号(技海拾贝):Java学习九—常用包(类)之java.util包
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/295312.html