一、Stream流
1、Stream的更优写法
Stream流,不同于I / O Stream。在Java8中,得益于Lambda所带来的函数式编程,引入了全新的Stream流,用于解决已有集合类库中既有的弊端。
Stream流是JDK8之后出现的,把真正的函数式编程思想引入到Java中。
例如:
使用传统的方式, 循环遍历集合, 对集合中的数据进行过滤, 筛选出姓张的, 名字是3个字
上面的代码,为了实现简单的过滤输出,就使用了3个循环。
循环只是做事情的一种方式,而不是目的,为达达目的,还可以使用更优雅的Stream流的写法
2、Stream流的使用
-
生成流
通过数据源(集合、数组等)生成流。如:list.stream()
-
中间操作
一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据 过滤/映射,然后返回一个新的流,交给下一个操作。例如:filter()过滤方法
-
终结操作
一个流只能有一个终结操作,当这个操作执行后,流就被使用“光” 了,无法再被操作。所以这必定是流的最后一个操作。如:forEach()
3、Stream流的生成方式(三种)
- Collection体系的集合可以使用默认方法stream()方法生成流
- Map体系的集合不能直接生成流,只能间接生成流
- 数组可以通过Stream接口的静态方法of(T…values)生成流
public class StreamDemo {
public static void main(String[] args){
// Collection体系的集合,可以使用默认方法stream()生成流
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<String>();
Stream<String> setStream = set.stream();
// Map体系的集合间接生成流
Map<String, Intrger> map = new HshMap<String, Integer>();
Stream<String> keyStream = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
// 数组可以通过Stream接口的静态方法of(T... value)生成流
String[] strArray = {"Hello", "world", "java"};
Stream<String> strArrayStream = Stream.of(strArray);
Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
Stream<Integer> intStream = Stream.of(10, 20, 30);
}
}
4、Stream流中间操作的常用方法
Stream filter(Predicate predicate):用于对流中的数据进行过滤
Predicate接口中的方法boolean test(T t):对给定的参数进行判断,返回一个布尔值
filter()方法的使用:
Stream limit(long maxSize): 返回此流中的元素组成的流,截取前指定参数个数的数据
Stream skip(long n):跳过指定参数个数的数据,返回由该流的剩余元素组成的流
使用:
static Stream concat(Stream a, Stream b):合并a和b两个流为一个流
这是个静态方法,只能通过这个接口来调用这个方法(静态跟对象没有关系,静态只跟类有关系)
Stream distinct(): 返回由该流的不同元素(根据Object.equals(Object)来判断是不是相同的元素)组成的流
Stream sorted(): 返回由此流的元素组成的流,根据自然顺序排序
Stream sorted(Comparator comparator): 返回由该流的元素组成的流,根据提供的Comparator进行排序
import java.util.ArrayList;
public class StreamDemo01 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("linqingxia");
list.add("zhangmanyu");
list.add("wangzuxian");
list.add("liuyan");
list.add("zhangmin");
list.add("zhangwuji");
//需求1:按照字母顺序把数据在控制台输出【sorted()方法是字母的自然排序】
list.stream().sorted().forEach(System.out::println);
//需求2:按照字符串长度把数据在控制台输出,当长度相同时,按照字母排序
list.stream().sorted((s1, s2) -> s1.length() - s2.length()).forEach(System.out::println)
//上面的代码满足不了在字母长度相同时,按字母排序
// 改进:
list.stream().sorted((s1, s2) -> {
int num = s1.length() - s2.length();
int num2 = num == 0 ? s1.compareTo(s2) : num;
return num2;
}).forEach(System.out::println);
}
}
Stream map(Function mapper): 返回由给定函数应用于此流的元素结果组成的流
Function接口中的方法——R apply(T t)
IntStream mapToint(ToIntFunction mapper): 返回一个IntStream其中包含将给定函数应用于此流的元素的结果
IntStream:表示原始 int 流(也是一个接口),其中有一个int sum()方法,用来返回此流中元素的总和(Stream流中没有这个sum()方法)。
ToIntFunction接口中的方法——int applyAsInt(T value)
可以通过mapToInt方法,返回一个InStream接口的对象,再来使用IntStream接口中的方法。
import java.util.ArrayList;
/*
<R> Stream<R> map(Function mapper):返回由给定函数应用于此流的元素的结果组成的流
Function接口中的方法 R apply(T t)
IntStream mapToInt(ToIntFunction mapper):返回一个IntStream其中包含将给定函数应用于此流的元素的结果
IntStream:表示原始 int 流
ToIntFunction接口中的方法 int applyAsInt(T value)
*/
public class StreamDemo05 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
//需求:将集合中的字符串数据转换为整数之后在控制台输出
// list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);
// list.stream().map(Integer::parseInt).forEach(System.out::println);
// list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
// IntStream接口中的方法——int sum() 返回此流中元素的总和
int result = list.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result); // 150
}
}
5、Stream流终结操作的常用方法
-
void forEach(Consumer action): 对此流的每个元素执行操作
Consumer接口中的方法——void accept(T t):对给定的参数执行此操作
- long count() : 返回此流中的元素数
6、Stream流的收集操作——把流中的数据收集到集合中
Stream流中的收集方法:
- R collect(Collection collector)
- 但是,这个收集方法的参数是一个Collector接口,直接使用这个接口是使用不了的
在工具类Collectors中,提供了具体的收集方式:
- public static Collector toList():把元素收集到List集合中
- public static Collector toSet():把元素收集到Set集合中
- public static Collector toMap(Function keyMapper, Function valueMapper):把元素收集到Map集合中