为了账号安全,请及时绑定邮箱和手机立即绑定

自定义对象上的流过滤器给定范围的多维数组

自定义对象上的流过滤器给定范围的多维数组

红糖糍粑 2021-11-24 15:51:35
最近几天,我尝试了 Java 8 和 lambda 表达式。实现起来更清晰、更清晰、更有趣,但是我一直困惑如何在给定范围内迭代多维数组以找到第一次出现的非空元素。例如,这是我的数组:MyObject[][] array = new MyObject[][]; //this array is never full objects are placed at random places正如评论暗示我试图找到第一次出现或非空对象,让我们说array[0-5][irrelevant]        orarray[irrelevent][3-9]到目前为止我得到的最接近的是:MyObject obj = Arrays.stream(grid.grid)                .flatMap(IntStream.range(0,2)) //here it must work for any dimension given any range                .filter(array -> array != null)                .findFirst()                .orElse(null); 显然,这不会编译,因为它不是一个 Integer 元素,而是一个自定义对象。非常感谢任何帮助。
查看完整描述

3 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

我们可以使用以下语法来做到这一点:

MyObject findFirst = Arrays.stream(array).flatMap(Arrays::stream)
                       .collect(Collectors.toList())
                       .subList(0, 3) // observe this line
                       .stream()
                       .filter(e -> e != null).findFirst().orElse(null);

这里我们将二维数组转换为一个listusing flatMap,然后用 usesubList来指定要搜索的索引的开始和结束。

要指定范围,您需要将值传递给 subList(...)


查看完整回答
反对 回复 2021-11-24
?
jeck猫

TA贡献1909条经验 获得超7个赞

虽然 Nicholas K 的答案适用于水平切片,但它不适用于垂直切片。这是一个完全符合OP想要的答案。为了清楚起见,我已经编写了传统的(使用 for 循环)方式来执行此操作,以确认这就是 OP 打算完成的操作。然后,我使用流完成了它。它适用于水平和垂直切片。


public static void main(String[] args) {


    // Sample data

    Object[][] array = new Object[5][10];

    array[1][5] = "this is it";  // This is the first non-null object

    array[4][7] = "wrong one";   // This is another non-null object but not the first one


    // Define range (start=inclusive, end=exclusive)

    int iStart = 0, iEnd = array.length, jStart = 3, jEnd = 9; // array[irrelevant][3-9]

    //int iStart = 1, iEnd = 3, jStart = 0, jEnd = array[0].length; // array[1-3][irrelevant]


    // Doing it the traditional way

    Object firstNonNull = null;

    outerLoop:

    for (int i = iStart; i < iEnd; i++)

        for (int j = jStart; j < jEnd; j++)

            if (array[i][j] != null) {

                firstNonNull = array[i][j];

                break outerLoop;

            }


    assert firstNonNull != null;

    assert firstNonNull.equals("this is it");


    // Doing it with Java 8 Streams

    firstNonNull = Arrays.asList(array)

            .subList(iStart, iEnd)

            .stream()

            .flatMap(row -> Arrays.asList(row)

                    .subList(jStart, jEnd)

                    .stream()

                    .filter(Objects::nonNull))

            .findFirst()

            .orElse(null);


    assert firstNonNull != null;

    assert firstNonNull.equals("this is it");

}


查看完整回答
反对 回复 2021-11-24
?
GCT1015

TA贡献1827条经验 获得超4个赞

MyObject obj = Arrays.stream(array)
        .flatMap(Arrays::stream)
        .filter(Objects::nonNull)
        .findFirst()
        .orElse(null);


查看完整回答
反对 回复 2021-11-24
  • 3 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信