一、Stream的概念与特点
- 流(Stream):是Java 8中引入的一个关键抽象概念,它允许你以声明方式处理数据集合(包括数组)。Stream自己不会存储元素,也不会改变源对象,它只是对数据源进行操作。
- 惰性求值:Stream中的操作是惰性求值的,即在调用终端操作之前,中间操作不会立即执行。这意味着可以构建一个操作序列,然后在需要时一次性执行,以减少不必要的计算。
- 函数式编程:Stream API基于函数式编程的理念,提供了丰富的中间操作和终端操作,可以通过函数式接口来实现自定义操作。
二、Stream的创建
Stream可以通过多种方式创建,主要包括以下几种:
-
通过集合的stream()或parallelStream()方法:
stream()
:返回一个顺序流。parallelStream()
:返回一个并行流,适合处理大数据集以利用多核处理器的优势。
示例代码:
List<String> list = Arrays.asList("Apple", "Banana", "Cherry"); Stream<String> stream = list.stream(); Stream<String> parallelStream = list.parallelStream();
Stream方法
1. 循环遍历 --> forEach()
该方法为终止方法 , 调用后stream流关闭
```
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三丰");
list.add("张大彪");
list.add("吕不韦");
list.add("张三");
list.add("赵姬");
list.add("张翠山");
list.add("嫪毐");
Stream<String> stream = list.stream();
stream.forEach(s -> System.out.println(s));
```
2. 统计元素个数 --> count()
该方法为终止方法 , 调用后stream流关闭
```
long count = stream.count();
System.out.println(count);
```
3. 根据某个条件进行元素过滤 --> filter()
```
stream.filter( s -> s.startsWith("张"));
```
4. 转换元素类型或进行元素映射 --> map()
map()
方法可以对流中的每个元素应用一个函数,并将该函数的结果收集到一个新的流中。它接收一个Function
函数式接口的实现,该函数式接口定义了一个apply
方法,该方法接受一个参数并返回结果。
java
// 假设我们要将每个名字转换为大写
Stream<String> mappedStream = stream.map(String::toUpperCase);
List<String> mappedList = mappedStream.collect(Collectors.toList());
mappedList.forEach(System.out::println);
5. 排序 --> sorted()
sorted()
方法可以对流中的元素进行排序。默认情况下,它使用元素的自然排序(如果元素实现了Comparable
接口)。你也可以提供一个自定义的Comparator
来指定排序规则。
java
// 使用自然排序(假设名字可以按字典顺序排序)
Stream<String> sortedStream = stream.sorted();
List<String> sortedList = sortedStream.collect(Collectors.toList());
sortedList.forEach(System.out::println);
// 或者使用自定义排序(例如,按名字长度排序)
Stream<String> sortedByLengthStream = stream.sorted(Comparator.comparingInt(String::length));
List<String> sortedByLengthList = sortedByLengthStream.collect(Collectors.toList());
sortedByLengthList.forEach(System.out::println);
6. 查找最小或最大元素 --> min() 和 max()
min()
和max()
方法分别返回流中的最小或最大元素。它们需要一个Comparator
来比较元素,但如果元素实现了Comparable
接口,则可以省略Comparator
。
java
// 查找最长的名字
Optional<String> longestName = stream.max(Comparator.comparingInt(String::length));
longestName.ifPresent(System.out::println);
// 查找最短的名字(假设没有空字符串)
Optional<String> shortestName = stream.min(Comparator.comparingInt(String::length));
shortestName.ifPresent(System.out::println);
需求:
-
第一个队伍只要名字为3个字的成员姓名;//filter
2. 第一个队伍筛选之后只要前3个人;//limit 3. 第二个队伍只要姓张的成员姓名;//filter 4. 第二个队伍筛选之后不要前2个人;//skip 5. 将两个队伍合并为一个队伍;//concat 6. 打印整个队伍的姓名信息。//forEeach
代码:
public class Demo04Stream {
public static void main(String[] args) {
ArrayList<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
ArrayList<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
//将两个集合变成Stream流
Stream<String> teamA = one.stream();
Stream<String> teamB = two.stream();
//Stream<String> listA = teamA.filter(s -> s.length() == 3).limit(3);
//Stream<String> listB = teamB.filter(s -> s.startsWith("张")).skip(2);
//合并
Stream.concat(teamA.filter(s -> s.length() == 3).limit(3),teamB.filter(s -> s.startsWith("张")).skip(2)).forEach(s -> System.out.println(s));
}
}