Files
Hui-s-notebook/使用流.md
2023-09-10 10:50:53 +08:00

4.0 KiB
Raw Permalink Blame History

筛选与切片

  1. 用谓词筛选filter
  2. 筛选各异的元素distinct(去重)
  3. 截短流limit(n)
  4. 跳过元素skip(n)

映射

  1. 对流中每一个元素应用函数map
  2. 流的扁平化 字符->字节 使用flatmap把一个流中的每个值都转换为另一个流再把所有的流都连接起来
    List<String> uniqueCharacters = 
    	words.stream()
    		 .map(w -> w.split(""))
    		 .flatmap(Array::stream)
    		 // 将各个生成流扁平化为单个流
    		 .distinct()
    		 .collect(Collections.toList());
    

查找和匹配

  1. 检查谓词是否至少匹配一个元素 anyMatch,返回boolean终端操作
  2. 检查谓词是否匹配所有元素 allMatch
  3. 检查谓词是否与任何元素不匹配 noneMatch
  4. 查找元素 findAny,返回流中任意元素
  5. 查找第一个元素 findFirst

规约

  1. 元素求和 reduce
int sum = numbers.stream().reduce(0, (a, b) -> a+b);
int product = numbers.stream().reduce(1, (a, b) -> a*b);
int sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> sum = numbers.stream().reduce((a, b) -> a+b);
0为初始值
一个BinaryOperation<T>将两个元素结合起来产生一个新值
**无初始值**时reduce返回一个Optional对象
  1. 最大和最小值 利用 reduce 计算,
Optional<Integer> max=numbers.Stream (). Reduce (Integer::max);
Optional<Integer> min=numbers.Stream (). Reduce (Integer::min);
  1. 计算个数
int count = menu.stream().map(d-> 1).reduce(0, (a, b)-> a+b);
long count = menu.stream().count()

有状态操作

Sort 和 dsitinct 等操作一开始和 map 和 filter 差不多但是排序和删除重复项都需要之前的历史这种状态称为有状态操作reducesummax 保存了一个内部状态但这个是有界的mapfilter 会获取每一个元素,并在输出流中得到一个或 0 个结果,这种是无状态的

数值流

在求和时包装类型在进行数据计算时有一个装箱成本,流中的元素都是 Integer 类型的

原始类型流特化

IntStreamDoubleStreamLongStream

  1. 映射到数值流 mapToInt、mapToDouble、mapToLong 可以返回一个特化流
  2. 转换为对象流 使用 boxed 方法 intStream.boxed()
  3. 默认值 Optional 对于三种特化流,有 OptionalInt、OptionalDouble、OptionalLong 对应,
OptionalInt maxCalories=menu.stream().mapToInt(Dish::getCalories).max();
// 如果没有最大值,显示提供一个最大值
int max = maxCalories.orElse(1);

数值范围

生成特定数值范围的流

IntStream evenNumbers = IntStream.rangClosed(1, 100).filter(n -> n % 2 == 0);
System.out.println(evenNumbers.count());

勾股数

Stream<int[]> pythagoreanTriples = IntStream.rangClosed(1, 100).boxed()
	.faltMap(a -> 
		IntStream.rangClosed(a, 100)
			.filter(b -> Math.sqrt((a*a + b*b) % 1 == 0))
			.mapToObj(b ->
				new int[]{a, b, (int)Math.sqrt(a*a + b*b)})
	);
// 先生成所有三元数,再筛选符合条件的
Stream<Double[]> pythagoreanTriples2 = IntStream.rangClosed(1, 100).boxed()
	.faltMap(a -> 
		IntStream.rangClosed(a, 100)
			.filter(b -> Math.sqrt((a*a + b*b) % 1 == 0))
			.mapToObj(b ->
				new Double[]{a, b, (int)Math.sqrt(a*a + b*b)})
			.filter(t -> t[2] % 1 == 0)
	);

构建流

  1. 由值构建, 使用 Stream.of
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
// 获取一个空流
Stream<String> emptyStream = Stream.empty
  1. 由数组构建, 使用 Array.stream 从数组创建

  2. 由文件, 使用 File.lines 得到一个流

  3. 由函数创建, Stream.iterate 和 Stream.generate, 这两个操作可以创建所谓的无限流

Stream.iterate(0, n-> n+2)
	  .limit(10)
	  .forEach(System.out::println);
Stream.generate(Math::random)
              .limit(5)
              .forEach(System.out::println)