【问题标题】:Iterate over list with indices in vavr使用 vavr 中的索引迭代列表
【发布时间】:2018-08-03 07:16:25
【问题描述】:

我正在使用来自 vavr 库的集合。 我有一个这样定义的元素列表:

List<Integer> integers = List.of(1, 2, 3);

如何遍历列表的元素并同时访问索引?在 Groovy 中有一个方法 eachWithIndex。我在vavr 中寻找类似的东西。我想这样使用它:

integers.eachWithIndex((int element, int index) -> {
     System.out.println("index = " + index + " element = " + element);
})

如何在vavr 中实现这一点?

【问题讨论】:

  • 使用带有迭代器的索引是一种反模式?为什么你首先需要它?
  • 为什么你认为这是一个反模式?
  • 首先去阅读iterator模式,它会给你答案。
  • 即使是功能性更强的 Kotlin 语言也有 forEachIndexed 方法,所以你认为这是设计师的错误?
  • 我想很多人会将此视为一个 Java 问题,因为这完全是关于 vavr

标签: java lambda collections foreach vavr


【解决方案1】:

Vavr 有一个类似于 Scala 的 API。 Vavr 集合(又名可遍历)有一个名为zipWithIndex() 的方法。它返回一个新集合,该集合由元素和索引的元组组成。

此外,使用迭代器可以为我们节省新的集合实例。

final List<Integer> integers = List.of(1, 2, 3);

integers.iterator().zipWithIndex().forEach(t ->
    System.out.println("index = " + t._1 + " element = " + t._2)
);

但是,我发现创建新集合不如 Kotlin 解决方案高效,尤其是当所有信息(元素和索引)都已经到位时。我喜欢在 Vavr 的集合中添加一个新方法 forEachWithIndex 的想法,就像在 Kotlin 中一样。

更新:我们可以将 forEachWithIndex(ObjIntConsumer&lt;? super T&gt;) 添加到 Vavr 的 Traversable。它不仅仅是iterator().zipWithIndex().forEach(Consumer&lt;Tuple2&lt;T, Integer&gt;&gt;) 的快捷方式,因为它不会在迭代期间创建Tuple2 实例。

更新:我只是 added forEachWithIndex 给 Vavr。它将包含在下一个版本中。

免责声明:我是 Vavr 的创造者。

【讨论】:

  • 如果只是一次性迭代,也可以通过integers.iterator().zipWithIndex().forEach(..) 跳过创建新集合。
  • Nándor 是对的,在这种情况下它更有用,因为我们执行副作用并且不转换集合。我会相应地更新帖子。
  • 添加“filterWithIndex”是否有意义?
【解决方案2】:

如果你想访问索引,只需使用普通的 for 循环和List.get(ix)

【讨论】:

  • 谢谢,我只是在争取有更多功能性、声明性的方式来实现相同的目标。
【解决方案3】:

JMPL 是一个简单的 java 库,它可以模拟一些特征模式匹配,使用 Java 8 特性。 这个库还支持简单的迭代集合。

   Figure figure = new Rectangle();    

   foreach(listRectangles, (int w, int h) -> {
      System.out.println("square: " + (w * h));
   });      

【讨论】:

    猜你喜欢
    • 2014-10-04
    • 1970-01-01
    • 2010-09-12
    • 2018-09-21
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    相关资源
    最近更新 更多