Java Lambda:迭代 2 个暗淡数组并保持当前索引

2024-02-23

我是 Java 8 的 Lambda 表达式的新手,我想制定以下内容: 我有一个二维数组,我想在应用程序代码中对其进行多次迭代,并对数组中的项目进行处理。在我执行以下操作之前:

    public static abstract class BlaBlaIterator {

            private final BlaBla[][] blabla;

            public BlaBlaIterator(final BlaBla[][] blabla) {
                this.blabla = blabla;
            }

            public void iterate() {
                final int size = blabla.length;
                for (int x = 0; x < size; x++) {
                    for (int y = 0; y < size; y++) {
                        final BlaBla bla = blabla[x][y];
                        iterateAction(x, y, bla, bla == null);
                    }
                }
            }

            public abstract void iterateAction(int x, int y, BlaBla bla, boolean isNull);
        }

and then

    BlaBla[][] blabla = ...

    new BlaBlaIterator(blabla) {

        @Override
        public void iterateAction(final int x, final int y, final BlaBla bla, final boolean isNull) {
            //...
        }
    }.iterate();

至关重要的事情:我需要访问当前的 x/y 并且需要计算 isNull 之类的东西。

我现在想做的是将其转换为 lambda。我想写这样的东西:

    BlaBla[] blabla = ...
    blabla.stream().forEach((x, y, blabla, isNull) -> ... );

要从二维数组中获取流,我可以这样做

    Arrays.stream(field).flatMap(x -> Arrays.stream(x))

但随后我丢失了 x/y 信息,并且无法传递 isNull 之类的计算内容。我怎样才能做到这一点?


老实说,我会保留传统的嵌套循环,在我看来,这是一种更简洁的方法。流并不能替代所有“旧”Java 代码。尽管如此,我还是发布了一些可能的方法。

第一种方法

这是第一种可能的方法(面向对象)。创建一个类ArrayElement保存指数:

class ArrayElement<V> {
    public final int row;
    public final int col;
    public final V elem;
    ...
}

然后,您需要创建一种方法,该方法从单个数组(我们将调用的数组)创建元素流flatMap), and iterateAction只打印出当前实例

private static <T> Stream<ArrayElement<T>> createStream(int row, T[] arr) {
    OfInt columns = IntStream.range(0, arr.length).iterator();
    return Arrays.stream(arr).map(elem -> new ArrayElement<>(row, columns.nextInt(), elem));
} 

private static <V> void iterateAction(ArrayElement<V> elem) {
    System.out.println(elem);
}

最后主要看起来像这样:

String[][] arr = {{"One", "Two"}, {"Three", "Four"}};
OfInt rows = IntStream.range(0, arr.length).iterator();
Arrays.stream(arr)
      .flatMap(subArr -> createStream(rows.nextInt(), subArr))
      .forEach(Main::iterateAction);

和输出:

ArrayElement [row=0, col=0, elem=One]
ArrayElement [row=0, col=1, elem=Two]
ArrayElement [row=1, col=0, elem=Three]
ArrayElement [row=1, col=1, elem=Four]

此解决方案的缺点是它为数组中的每个对象创建一个新对象。

第二种方法

第二种方法更直接,它的想法相同,但您不会为数组中的每个 elem 创建一个新的 ArrayElement 实例。同样,这可以在一个衬垫中完成,但 lamdba 会变得丑陋,所以我将它们分成方法(如第一种方法):

public class Main {    
    public static void main(String[] args) {
        String[][] arr = { {"One", "Two"}, {null, "Four"}};
        OfInt rows = IntStream.range(0, arr.length).iterator();
        Arrays.stream(arr).forEach(subArr -> iterate(subArr, rows.nextInt()));
    }
    static <T> void iterate(T[] arr, int row) {
        OfInt columns = IntStream.range(0, arr.length).iterator();
        Arrays.stream(arr).forEach(elem -> iterateAction(row, columns.nextInt(), elem, elem == null));
    }
    static <T> void iterateAction(int x, int y, T elem, boolean isNull) {
        System.out.println(x+", "+y+", "+elem+", "+isNull);
    }    
}

它输出:

0, 0, One, false
0, 1, Two, false
1, 0, null, true
1, 1, Four, false

第三种方法

使用两个实例AtomicInteger

String[][] arr = {{"One", "Two"}, {null, "Four"}};
AtomicInteger rows = new AtomicInteger();
Arrays.stream(arr).forEach(subArr -> {
    int row = rows.getAndIncrement();
    AtomicInteger colums = new AtomicInteger();
    Arrays.stream(subArr).forEach(e -> iterateAction(row, colums.getAndIncrement(), e, e == null));
});

产生与上面相同的输出。

我的结论

使用 Streams 是可行的,但我真的更喜欢用例中的嵌套循环,因为您需要 x 和 y 值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java Lambda:迭代 2 个暗淡数组并保持当前索引 的相关文章

随机推荐

  • Xamarin.IOS 上的内存管理如何工作

    我正在尝试了解使用 xamarin ios 并在实际 iOS 设备上运行该应用程序时内存管理的工作原理 我的理解是iOS平台没有垃圾收集器 但是平台使用ARC Automatci Reference Counting 编译后的应用程序真的会
  • Powershell 在 System.Drawing 中使用 .NET .DrawImage

    我正在制作一个工具 可以自动裁剪和定位 无需将图像大小调整为其他图像 我发现this https learn microsoft com en us dotnet api system drawing graphics drawimageu
  • 我正在评估 Google Pub/Sub 与 Kafka。有什么区别? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对kafka的工作不多 但想在GCE中构建数据管道 所以我们想了解 Kafka 与 PUB Sub 基本上我想知道Kafka和Pub
  • 转换为 Func 与新 Func?

    下面两条语句有什么区别吗 他们都工作 if Func
  • 如何在 C# 中为控件添加移动效果?

    我的 C 表单中有一个面板 并且有一个按钮 当我单击按钮时 会显示不可见的面板 相反 我希望面板移入或滑入 例如 当您单击组合框时 下拉列表不会弹出 我希望我的面板像那样显示 我怎样才能做到这一点 窗口动画是 Windows 的内置功能 这
  • 无法传入 lambda 来申请 pandas DataFrame

    我正在尝试将函数应用于 pandas DataFrame 的所有行 实际上只是该 DataFrame 中的一列 我确信这是一个语法错误 但我知道我做错了什么 df col apply lambda x y x y total seconds
  • CLR 项目的智能感知 - 例如没有智能感知系统.Windows.窗体

    我一直在关注一些关于某些内容的两个教程Visual C 基础知识 http www functionx com vccli general introprogramming htm但他们似乎都缺乏有关我如何在 Visual Studio 2
  • Google AppInvites 中断构建

    您的应用程序的一部分build gradle这是 tasks withType com android build gradle tasks PackageApplication pkgTask gt pkgTask jniFolders
  • 如何在v-html中运行脚本

    我从数据库获取嵌入代码 Instagram Twitter 等 如何将它们绑定到 vue 组件 有没有办法在v html中执行脚本标签 简短的回答 你不能 一旦 dom 加载 您的浏览器就会阻止脚本标签的执行 长答案 您可以尝试匹配脚本的
  • 如何保留对 NPM 模块所做的本地更改?

    我已经使用 NPM 拉下了一个节点模块 并将其添加到package json 然而 需要更改模块的一些代码 因为它没有 100 满足我的要求 通常当我使用节点时git我会忽略node modules目录及使用npm install部署到服务
  • CSS - 并排的内联块,宽度为 100%

    我有两个带有文本的块 文本的长度不是恒定的 用户输入 左侧块中包含短文本 但右侧块可能包含非常长的文本 这些块应该并排出现 并且分布在父级恒定宽度的 100 上 不多也不少 简化示例 https jsfiddle net hh6a03cy
  • 在恒定空间和线性时间内向后打印单链表

    我听到一个面试问题 向后打印单链表 在恒定空间和线性时间中 我的解决方案是反转链接列表 然后像这样打印它 还有其他非破坏性的解决方案吗 您已经找到了大部分答案 将链表反转到位 然后将列表遍历回开头以打印它 为了防止它 永久 破坏性 请就地反
  • AtomicBoolean 与同步块

    我试图通过替换一些来减少代码中的线程争用synchronized块与AtomicBoolean 这是一个例子synchronized public void toggleCondition synchronized this mutex i
  • Subversion 和 CVS 中添加自动内容的标签怎么称呼?

    像 log and version 在签入文件时添加数据 我有兴趣查看其他人以及他们可以提供哪些信息 但除非我知道他们叫什么 否则我无法获得太多信息 Subversion 和 CVS 都称它们为Keywords 在这里查看 SVN 手册 h
  • 窗口函数过滤当前行

    这是后续this https stackoverflow com questions 48000013 optimize slow aggregates in lateral join问题 我的查询被改进为使用窗口函数而不是内部的聚合LAT
  • 你如何制作一个makefile

    我想知道如何为 Unix 创建 makefile 这里有一个好的生成文件教程 http oucsace cs ohiou edu bhumphre makefile html 搜索 如何创建 makefile 后 Google 上的第一个结
  • 修复 Chocolatey“访问被拒绝”的问题

    我刚刚第一次使用安装了 Chocolateythis https i stack imgur com fw9WX png管理员 cmd 中的命令 SystemRoot System32 WindowsPowerShell v1 0 powe
  • dlopen 中对 __dlopen 的未知引用

    dlopen位于libdl a但是当我将我的应用程序链接到libdl a gcc 链接器抛出此错误 unknow reference to dlopen called in dlopen 我应该导入另一个吗 a 当我尝试静态编译时dlope
  • C 将输入文本文件解析为单词

    我正在尝试将输入文件 包含具有多行和分隔符的文本文档 即 解析为单词 我的函数 分割函数 是 int splitInput fp int i 0 char line 255 char array 5000 int x while fgets
  • Java Lambda:迭代 2 个暗淡数组并保持当前索引

    我是 Java 8 的 Lambda 表达式的新手 我想制定以下内容 我有一个二维数组 我想在应用程序代码中对其进行多次迭代 并对数组中的项目进行处理 在我执行以下操作之前 public static abstract class BlaB