我正在玩 Java SE 8 中的惰性函数操作,我想为pair / tuple 创建map一个索引,然后基于第二个元素,最后只输出索引。i``(i, value[i])``filter``value[i]
map
i``(i, value[i])``filter``value[i]
我还必须忍受这个:Java 中的 C++ Pair 等价物是什么?在 lambda 和流的大胆新时代?
更新: 我提出了一个相当简化的示例,@dkatzel 在以下答案之一中提供了一个简洁的解决方案。但是,它并 不能 一概而论。因此,让我添加一个更一般的示例:
package com.example.test; import java.util.ArrayList; import java.util.stream.IntStream; public class Main { public static void main(String[] args) { boolean [][] directed_acyclic_graph = new boolean[][]{ {false, true, false, true, false, true}, {false, false, false, true, false, true}, {false, false, false, true, false, true}, {false, false, false, false, false, true}, {false, false, false, false, false, true}, {false, false, false, false, false, false} }; System.out.println( IntStream.range(0, directed_acyclic_graph.length) .parallel() .mapToLong(i -> IntStream.range(0, directed_acyclic_graph[i].length) .filter(j -> directed_acyclic_graph[j][i]) .count() ) .filter(n -> n == 0) .collect(() -> new ArrayList<Long>(), (c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2)) ); } }
这给出了 不正确 的输出,[0, 0, 0]其对应于所有 3 列的 计数false。我需要的是这三列的 索引 。正确的输出应该是[0, 2, 4]. 我怎样才能得到这个结果?
[0, 0, 0]
false
[0, 2, 4]
更新: 这个答案是对原始问题的回应, Java SE 8 是否有对或元组? (隐含地,如果不是,为什么不呢?) OP 已经用一个更完整的例子更新了这个问题,但它似乎可以在不使用任何类型的 Pair 结构的情况下解决。
最简洁的答案是不。您要么必须自己动手,要么引入实现它的几个库之一。
在 Java SE 中创建一个Pair类至少有一次被提议并被拒绝。请参阅OpenJDK 邮件列表之一上的此讨论线程。权衡并不明显。一方面,在其他库和应用程序代码中有许多 Pair 实现。这表明了一种需求,将这样的类添加到 Java SE 将增加重用和共享。另一方面,拥有一个 Pair 类增加了从 Pairs 和集合中创建复杂数据结构而不创建必要的类型和抽象的诱惑。(这是对Kevin Bourillion在该线程中的信息的解释。)
Pair
我建议每个人都阅读整个电子邮件线程。它非常有洞察力,没有火焰。这很有说服力。当它开始时,我想,“是的,Java SE 中应该有一个 Pair 类”,但是当线程结束时,我改变了主意。
但是请注意,JavaFX 具有javafx.util.Pair类。JavaFX 的 API 与 Java SE API 分开发展。
从链接的问题中可以看出,Java 中的 C++对是什么?a)围绕显然如此简单的 API有相当大的设计空间。对象应该是不可变的吗?它们应该是可序列化的吗?它们应该具有可比性吗?这门课应该是最终的还是不是?这两个元素应该排序吗?它应该是接口还是类?为什么停在对?为什么不是三元组、四元组或N 元组?
当然,元素的命名是不可避免的:
一个几乎没有被提及的大问题是 Pairs 与原语的关系。如果您有一个(int x, int y)表示 2D 空间中的点的数据,则将其表示为Pair<Integer, Integer>消耗 三个对象 而不是两个 32 位字。此外,这些对象必须驻留在堆上并且会产生 GC 开销。
(int x, int y)
Pair<Integer, Integer>
似乎很清楚,就像 Streams 一样,对 Pairs 有原始的专业化是必不可少的。我们想看到:
Pair ObjIntPair ObjLongPair ObjDoublePair IntObjPair IntIntPair IntLongPair IntDoublePair LongObjPair LongIntPair LongLongPair LongDoublePair DoubleObjPair DoubleIntPair DoubleLongPair DoubleDoublePair
即使 anIntIntPair仍然需要堆上的一个对象。
IntIntPair
当然,这些让人想起java.util.functionJava SE 8 中包中功能接口的激增。如果您不想要臃肿的 API,您会省略哪些?您也可以争辩说这还不够,还Boolean应该添加专业化。
java.util.function
Boolean
我的感觉是,如果 Java 很久以前就添加了 Pair 类,它会很简单,甚至过于简单化,而且它不会满足我们现在设想的许多用例。考虑一下,如果在 JDK 1.0 时间框架中添加了 Pair,它可能是可变的!(查看 java.util.Date。)人们会对此感到满意吗?我的猜测是,如果在 Java 中有一个 Pair 类,它会有点排序 - 不是真的有用,每个人仍然会滚动自己来满足他们的需求,外部库中会有各种 Pair 和 Tuple 实现,人们仍然会争论/讨论如何修复 Java 的 Pair 类。换句话说,有点像我们今天所处的位置。
同时,一些工作正在进行以解决基本问题,即 JVM(以及最终的 Java 语言)对 值类型 的更好支持。请参阅此《价值观状态》文件。这是初步的推测性工作,它仅涵盖 JVM 角度的问题,但背后已经有相当多的思考。当然,不能保证这会进入 Java 9 或任何地方,但它确实显示了当前对该主题的思考方向。