拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 java中Stream和Collection相互转换

java中Stream和Collection相互转换

白鹭 - 2021-11-24 765 0 0

1.概述

Java 8 Stream API提供了Java Collections之外的有效替代方案,以呈现或处理结果集。但是,决定何时使用哪个是一个普遍的难题。

在本文中,我们将探索StreamCollection并讨论适合其各自用途的各种方案。

2. CollectionStream

Java Collection ListSetMap类的数据结构,提供了有效的机制来存储和处理数据。

但是,Stream API可用于对数据执行各种操作,而无需中间存储。因此, Stream工作方式类似于直接从底层存储(如集合和I / O资源)访问数据。

此外,这些集合主要与提供对数据的访问以及修改数据的方式有关。另一方面,流与有效地传输数据有关。

尽管Java允许轻松地从Collection转换为Stream ,反之亦然,但要知道哪种是呈现/处理结果集的最佳机制是很方便的。

例如,我们可以使用streamparallelStream方法Collection转换为Stream

public Stream<String> userNames() {

 ArrayList<String> userNameSource = new ArrayList<>();

 userNameSource.add("john");

 userNameSource.add("smith");

 userNameSource.add("tom");

 return userNames.stream();

 }

同样,我们可以使用Stream API collect Stream转换为Collection

public List<String> userNameList() {

 return userNames().collect(Collectors.toList());

 }

在这里,我们使用Collectors.toList()方法Stream转换为List同样,我们可以将Stream转换为SetMap

public static Set<String> userNameSet() {

 return userNames().collect(Collectors.toSet());

 }



 public static Map<String, String> userNameMap() {

 return userNames().collect(Collectors.toMap(u1 -> u1.toString(), u1 -> u1.toString()));

 }

3.何时返回Stream

3.1 相关的成本高

Stream API可以随时随地懒惰地执行和过滤结果,这是降低实现成本的最有效方法。

例如,Java NIO readAllLines Files所有行,JVM必须为此文件的所有行将其内容保存在内存中。因此,此方法在返回行列表时涉及较高的实现成本。

但是, Files类还提供了lines方法,该方法返回一个Stream ,我们可以使用它来渲染所有行,甚至可以使用limit方法更好地限制结果集的大小-两者都可以延迟执行:

Files.lines(path).limit(10).collect(toList());

另外,在forEach类的终端操作之前Stream不会执行中间操作:

userNames().filter(i -> i.length() >= 4).forEach(System.out::println);

因此, Stream避免了与过早实现相关的成本。

3.2 大结果或无限结果

Stream的设计目的是为了获得更好的性能,无论结果是大还是无限。 Stream用于此类用例始终是一个好主意。

同样,在结果无限的情况下,我们通常不处理整个结果集。因此,Stream API的内置功能(例如filterlimit证明在处理所需结果集时非常方便,使Stream成为首选。

3.3 灵活性

Stream允许在以任何形式或顺序处理结果时非常灵活。

当我们不想对使用者强制执行一致的结果集时, Stream此外,当我们想为消费者提供急需的灵活性时Stream

例如,我们可以使用Stream API上可用的各种操作来过滤/排序/限制结果:

public static Stream<String> filterUserNames() {

 return userNames().filter(i -> i.length() >= 4);

 }



 public static Stream<String> sortUserNames() {

 return userNames().sorted();

 }



 public static Stream<String> limitUserNames() {

 return userNames().limit(3);

 }

3.4 功能行为

Stream功能正常。当以不同方式处理时,不允许对源进行任何修改。因此,呈现不可变结果集是首选。

例如,让我们filterlimit Stream收到的一组结果:

userNames().filter(i -> i.length() >= 4).limit(3).forEach(System.out::println);

在此,每次对Stream filterlimit类的操作都会返回一个新的Stream并且不会修改userNames方法提供Stream

4.何时返回一个Collection

4.1 物化成本低

在渲染或处理涉及物化成本较低的结果时,我们可以选择流中的集合。

换句话说,Java从一开始就通过计算所有元素来急切地Collection因此, Collection在实现时会对堆内存造成很大压力。

因此,我们应该考虑使用Collection来呈现一个结果集,该结果集不会对实现它的堆内存造成太大的压力。

4.2 固定格式

我们可以使用Collection来为用户强制执行一致的结果集。例如, CollectionTreeSetTreeMap返回自然排序的结果。

换句话说,使用Collection ,我们可以确保每个使用者以相同的顺序接收和处理相同的结果集。

4.3 可重复使用的结果

Collection的形式返回时,可以轻松地遍历多次。但是, Stream就认为它已消耗掉,并在重用时IllegalStateException

public static void tryStreamTraversal() {

 Stream<String> userNameStream = userNames();

 userNameStream.forEach(System.out::println);



 try {

 userNameStream.forEach(System.out::println);

 } catch(IllegalStateException e) {

 System.out.println("stream has already been operated upon or closed");

 }

 }

因此,当很明显消费者将遍历结果多次时Collection

4.4 修改

Stream Collection允许修改元素,例如在结果源中添加或删除元素。因此,我们可以考虑使用集合来返回结果集,以允许使用者进行修改。

例如,我们可以使用add / remove方法ArrayList

userNameList().add("bob");

 userNameList().add("pepper");

 userNameList().remove(2);

类似地,诸如putremove类的方法允许在地图上进行修改:

Map<String, String> userNameMap = userNameMap();

 userNameMap.put("bob", "bob");

 userNameMap.remove("alfred");

4.5 内存中结果

另外,当以集合形式出现的物化结果已经存在于内存中时, Collection是一个显而易见的选择。

5.结论

在本文中,我们比较了StreamCollection并研究了适合他们的各种方案。

我们可以得出结论, Stream是呈现大型或无限结果集的理想选择,它具有诸如延迟初始化,急需的灵活性和功能行为之类的优点。

但是,当我们要求结果的形式一致时,或者当涉及到较低的成本实现时,我们应该选择Stream Collection

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *