Tag: java stream

复制stream以避免“stream已经被操作或closures”(Java 8)

我想复制一个Java 8stream,以便我可以处理它两次。 我可以collect一个列表,并从中获得新的stream; // doSomething() returns a stream List<A> thing = doSomething().collect(toList()); thing.stream()… // do stuff thing.stream()… // do other stuff 但我认为应该有一个更高效/优雅的方式。 有没有办法复制stream而不把它变成一个集合? 实际上,我正在处理任意一个stream,所以我们需要先处理左侧的投影,然后再移动到正确的投影中,然后用另一种方式处理。 有点像这样(到目前为止,我不得不使用toList技巧)。 List<Either<Pair<A, Throwable>, A>> results = doSomething().collect(toList()); Stream<Pair<A, Throwable>> failures = results.stream().flatMap(either -> either.left()); failures.forEach(failure -> … ); Stream<A> successes = results.stream().flatMap(either -> either.right()); successes.forEach(success -> … );

这是Files.lines()中的错误,还是我误解了一些关于并行stream的问题?

环境:Ubuntu x86_64(14.10),Oracle JDK 1.8u25 我尝试使用Files.lines()并行stream,但我想.skip()的第一行(这是一个带有标题的CSV文件)。 所以我尝试这样做: try ( final Stream<String> stream = Files.lines(thePath, StandardCharsets.UTF_8) .skip(1L).parallel(); ) { // etc } 但是,然后一列未能parsing为int … 所以我尝试了一些简单的代码。 该文件是问题是死的简单: $ cat info.csv startDate;treeDepth;nrMatchers;nrLines;nrChars;nrCodePoints;nrNodes 1422758875023;34;54;151;4375;4375;27486 $ 代码同样简单: public static void main(final String… args) { final Path path = Paths.get("/home/fge/tmp/dd/info.csv"); Files.lines(path, StandardCharsets.UTF_8).skip(1L).parallel() .forEach(System.out::println); } 我系统地得到以下结果(好吧,我只运行了大约20次): startDate;treeDepth;nrMatchers;nrLines;nrChars;nrCodePoints;nrNodes 我在这里错过了什么? 编辑看起来像这个问题,或误解,比这更深植根于下面的两个例子(FreeNode的## java的一个研究员煮熟): public static void […]

为什么Stream <T>不能实现Iterable <T>?

在Java 8中,我们有Stream <T>类,它好奇地有一个方法 Iterator<T> iterator() 所以你会希望它实现接口Iterable <T> ,它需要这个方法,但事实并非如此。 当我想使用foreach循环遍历Stream时,我必须做类似的事情 public static Iterable<T> getIterable(Stream<T> s) { return new Iterable<T> { @Override public Iterator<T> iterator() { return s.iterator(); } }; } for (T element : getIterable(s)) { … } 我在这里错过了什么?

并行stream,收集器和线程安全

请参阅下面的简单示例,其中列出了每个单词的出现次数: Stream<String> words = Stream.of("a", "b", "a", "c"); Map<String, Integer> wordsCount = words.collect(toMap(s -> s, s -> 1, (i, j) -> i + j)); 最后, wordsCount是{a=2, b=1, c=1} 。 但是我的stream量非常大,我想平行工作,所以我写道: Map<String, Integer> wordsCount = words.parallel() .collect(toMap(s -> s, s -> 1, (i, j) -> i + j)); 不过,我注意到wordsCount是一个简单的HashMap所以我不知道是否需要明确要求一个并发映射来确保线程安全: Map<String, Integer> wordsCount = words.parallel() .collect(toConcurrentMap(s -> […]

Java 8stream的.min()和.max():为什么编译?

注:这个问题来自一个死链接,这是一个以前的SO问题,但在这里… 看到这个代码( 注意:我知道这个代码不会“工作”,应该使用Integer::compare – 我只是从链接的问题中提取它 ): final ArrayList <Integer> list = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList()); System.out.println(list.stream().max(Integer::max).get()); System.out.println(list.stream().min(Integer::min).get()); 根据.min()和.max()的javadoc,两者的参数应该是Comparator 。 然而这里的方法引用是Integer类的静态方法。 那么,为什么这个编译呢?

我应该返回一个集合或stream?

假设我有一个将只读视图返回给成员列表的方法: class Team { private List<Player> players = new ArrayList<>(); // … public List<Player> getPlayers() { return Collections.unmodifiableList(players); } } 进一步假设所有客户端都立即迭代列表一次。 也许把玩家放入JList或其他东西。 客户端不存储对列表的引用以供以后检查! 鉴于这种常见的情况,我应该返回一个stream吗? public Stream<Player> getPlayers() { return players.stream(); } 或者在Java中返回一个非惯用的stream? stream被devise为始终被“终止”在他们创build的相同expression式内?

Java 8中的map和flatMap方法有什么区别?

在Java 8中, Stream.map和Stream.flatMap方法有什么区别?

如何强制max()返回Java Stream中的所有最大值?

我已经testing了Java 8 lambdaexpression式和stream的max()函数,并且似乎在max()被执行的情况下,即使多于一个对象比较为0,它也会返回绑定候选中的任意元素进一步考虑。 是否有一个明显的技巧或function,这样一个最大期望的行为,以便所有的最大值返回? 我没有看到API中的任何内容,但我相信它必须比手动比较更好。 例如: //myComparator is an IntegerComparator Stream.of(1,3,5,3,2,3,5).max(myComparator).forEach(System.out::println); //Would print 5,5 in any order.

Collectors.toMap中的Java 8 NullPointerException

如果其中一个值为“null”,则Java 8 Collectors.toMap将引发NullPointerException 。 我不明白这个行为,地图可以包含空指针作为值没有任何问题。 Collectors.toMap值不能为null是否有充分的理由? 此外,是否有一个很好的Java 8的方式来解决这个问题,或者我应该恢复到普通的旧的循环? 我的问题的一个例子: import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Answer { private int id; private Boolean answer; Answer() { } Answer(int id, Boolean answer) { this.id = id; this.answer = answer; } public int getId() { return id; } public void setId(int id) { this.id = […]

通过谓词查找第一个元素

我刚刚开始使用Java 8 lambdaexpression式,并试图在函数式语言中实现一些我习惯的东西。 例如,大多数函数式语言都具有某种查找函数,它可以对序列进行操作,或者列表返回第一个元素,谓词为true 。 我可以看到在Java 8中实现这一点的唯一方法是: lst.stream() .filter(x -> x > 5) .findFirst() 然而,这对我来说似乎是无效的,因为filter将扫描整个列表,至less在我的理解(这可能是错误的)。 有没有更好的办法?