首页 >> 大全

1.用谓词筛选

2023-11-12 大全 27 作者:考证青年

使用流处理 三、总结

前言 一、是什么?

支持顺序和并行聚合操作的一系列元素

集合和流,同时具有一些表面上的相似之处,具有不同的目标。 集合主要关注其元素的有效管理和访问。 相比之下,流不提供直接访问或操纵其元素的手段,而是关心声明性地描述其源和将在该源上进行聚合的计算操作。

流管道,可以被视为流源上的查询 。 除非源是明确设计用于并发修改(例如 ),否则在查询流源时可能会导致不可预测或错误的行为,流只能运行(调用中间或终端流操作)一次。

二、使用

数据准备:

List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT),
new Dish("french fries", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER),
new Dish("season fruit", true, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER),
new Dish("prawns", false, 300, Dish.Type.FISH),
new Dish("salmon", false, 450, Dish.Type.FISH) );

public class Dish {
private final String name;
private final boolean vegetarian;
private final int calories;
private final Type type;
public Dish(String name, boolean vegetarian, int calories, Type type) {this.name = name;this.vegetarian = vegetarian;this.calories = calories;this.type = type;
}
public String getName() {return name;
}
public boolean isVegetarian() {return vegetarian;
}
public int getCalories() {return calories;
}
public Type getType() {return type;
}
@Override
public String toString() {return name;
}
public enum Type { MEAT, FISH, OTHER }
}

1.用谓词筛选

接口支持方法。该操作会接受一个谓词(一个返回的函数)作为参数,并返回一个包括所有符合谓词的元素的流。

List vegetarianMenu = menu.stream().filter(Dish::isVegetarian).collect(toList());

2.筛选各异的元素

流还支持一个叫作的方法,它会返回一个元素各异(根据流所生成元素的和方法实现)的流。例如,以下代码会筛选出列表中所有的偶数,并确保没有重复。

List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

3.截短流

流支持limit(n)方法,该方法会返回一个不超过给定长度的流。所需的长度作为参数传递给limit。如果流是有序的,则最多会返回前n个元素。比如,可以建立一个List,选出热量超过300卡路里的头三道菜

List dishes = menu.stream().filter(d -> d.getCalories() > 300).limit(3).collect(toList());

4.跳过元素

流还支持skip(n)方法,返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回一个空流。请注意, limit(n)和skip(n)是互补的!例如,下面的代码将跳过超过300卡路里的头两道菜,并返回剩下的。

List dishes = menu.stream().filter(d -> d.getCalories() > 300).skip(2).collect(toList());

5.对流中每一个元素应用函数

流支持map方法,它会接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)。例如,下面代码将要找出每道菜的名称有多长。

List dishNameLengths = menu.stream().map(Dish::getName).map(String::length).collect(toList());

6.检查谓词是否至少匹配一个元素

使用方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(::)时生成的单个流都被合并起来,即扁平化为一个流。所以方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流。

List words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
List uniqueCharacters = words.stream().map(w -> w.split("")).flatMap(Arrays::stream)
.distinct().collect(Collectors.toList());

7.对流中每一个元素应用函数

方法可以回答“流中是否有一个元素能匹配给定的谓词”。比如,可以用它来看看菜单里面是否有素食可选择。

if(menu.stream().anyMatch(Dish::isVegetarian)) {System.out.println("The menu is (somewhat) vegetarian friendly!!");
}

8.检查谓词是否匹配所有元素

1、方法的工作原理和类似,但它会看看流中的元素是否都能匹配给定的谓5.3 查找和匹配谓词。比如,可以用它来看看菜品是否有利健康(即所有菜的热量都低于1000卡路里):

boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);

2、和相对的是。它可以确保流中没有任何元素与给定的谓词匹配。比如,可以用重写前面的例子

boolean isHealthy = menu.stream().noneMatch(d -> d.getCalories() >= 1000);

9.查找元素

方法将返回当前流中的任意元素。它可以与其他流操作结合使用。比如,可能想找到一道素食菜肴。可以结合使用和方法来实现这个查询:流水线将在后台进行优化使其只需走一遍,并在利用短路找到结果时立即结束。

Optional dish =menu.stream().filter(Dish::isVegetarian).findAny();
//因为上面代码有可能返回没有值的Optional,所以可以显式地检查Optional对象中是否存在一道菜
menu.stream().filter(Dish::isVegetarian).findAny().ifPresent(d -> System.out.println(d.getName());
ifPresent如 果 包 含 一 个值就打印它,否则什么都不做。

10.查找第一个元素

有些流有一个出现顺序( order)来指定流中项目出现的逻辑顺序(比如由List或排序好的数据列生成的流)。对于这种流,你可能想要找到第一个元素。为此有一个方法,它的工作方式类似于。例如,给定一个数字列表,下面的代码能找出第一个平方能被3整除的数:

List someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional firstSquareDivisibleByThree =someNumbers.stream().map(x -> x * x).filter(x -> x % 3 == 0).findFirst(); // 9

何时使用和

可能会想,为什么会同时有和呢?答案是并行。找到第一个元素在并行上限制更多。如果不关心返回的元素是哪个,请使用,因为它在使用并行流时限制较少。

11.元素求和

接受两个参数:

1、一个初始值;

2、一个来将两个元素结合起来产生一个新值,

int sum = numbers.stream().reduce(0, (a, b) -> a + b);	//求和
int product = numbers.stream().reduce(1, (a, b) -> a * b);	//求积
//当然可以用lambad表达式
int sum = numbers.stream().reduce(0, Integer::sum);
//也可以无初始值
Optional sum = numbers.stream().reduce((a, b) -> (a + b));
Optional max = numbers.stream().reduce(Integer::max);	//求最大值
Optional min = numbers.stream().reduce(Integer::min);	//同理,最小值

_筛选是什么短语_筛选语句

12.数值流

、 和,分别将流中的元素特化为int、 long和,从而避免了暗含的装箱成本。

用刚学的来计算菜单的热量,如下:

int calories = menu.stream().map(Dish::getCalories).reduce(0, Integer::sum);

但段代码的问题是,它有一个暗含的装箱成本。每个都必须拆箱成一个原始类型,再进行求和。要是可以直接像下面这样调用sum方法:

int calories = menu.stream().map(Dish::getCalories).sum();

所以映射到数值流,如下,如果流是空的, sum默认返回0。

int calories = menu.stream().mapToInt(Dish::getCalories).sum();

同样,一旦有了数值流,你可能会想把它转换回非特化流。例如, 上的操作只能产 生 原 始 整 数 : 的 map 操 作 接 受 的 必 须 接 受 int 并 返 回 int ( 一 个)。但是你可能想要生成另一类值,比如Dish。为此,你需要访问接口中定义的那些更广义的操作。要把原始流转换成一般流(每个int都会装箱成一个),可以使用boxed方法:

IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
Stream stream = intStream.boxed();

13.数值范围

假设你想要生成1和100之间的所有数字。 Java 8引入了两个可以用于和的静态方法,帮助生成这种范围:range和。这两个方法都是第一个参数接受起始值,第二个参数接受结束值。但range是不包含结束值的,而则包含结束值。

IntStream evenNumbers = IntStream.rangeClosed(1, 100).filter(n -> n % 2 == 0);

14.创建流

1、由值创建流:使用静态方法.of,通过显式值创建一个流。它可以接受任意数量的参数。例如,以下代码直接使用.of创建了一个字符串流。然后,可以将字符串转换为大写,再一个个打印出来:

Stream stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);、
//可以使用empty得到一个空流
Stream emptyStream = Stream.empty();

2、由数组创建流:可以使用静态方法.从数组创建一个流。它接受一个数组作为参数。例如,可以将一个原始类型int的数组转换成一个

int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum();

3、由文件生成流:Java中用于处理文件等I/O操作的NIO API(非阻塞 I/O)已更新,以便利用 API。java.nio.file.Files中的很多静态方法都会返回一个流。例如,一个很有用的方法是Files.lines,它会返回一个由指定文件中的各行构成的字符串流。

long uniqueWords = 0;
try(Stream lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) {uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))).distinct().count();
}
catch(IOException e) {
}

4、无限流: API提供了两个静态方法来从函数生成流: .和.。这两个操作可以创建所谓的无限流:不像从固定集合创建的流那样有固定大小的流。由和产生的流会用给定的函数按需创建值,因此可以无穷无尽地计算下去!一般来说,应该使用limit(n)来对这种流加以限制,以避免打印无穷多个值。

三、总结

事实上,流让可以简洁地表达复杂的数据处理查询。此外,流可以透明地并行化。

参考书籍:Java8实战。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了