首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义对象的流过滤器多维数组给定范围

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

Stack Overflow用户
提问于 2018-10-18 02:12:39
回答 3查看 1.3K关注 0票数 2

最近几天,我给了Java 8和lambda表达式一次尝试。事情更清晰,更清晰,更有趣的实现,然而,我一直困惑,我如何能够迭代一个给定的范围内的多维数组,以找到第一次出现的非空元素。例如,这是我的数组:

代码语言:javascript
复制
MyObject[][] array = new MyObject[][]; //this array is never full objects are placed at random places

正如注释所暗示的那样,我正在试图找到第一个出现的或非空对象,比方说

代码语言:javascript
复制
array[0-5][irrelevant] 
       or
array[irrelevent][3-9]

到目前为止,我最接近的是:

代码语言:javascript
复制
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元素,而是一个自定义对象。任何帮助都非常感谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-18 05:45:38

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

代码语言:javascript
复制
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);

在这里,我们使用list将2D数组转换为flatMap,然后使用subList指定要搜索的索引的开始和结束。

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

票数 1
EN

Stack Overflow用户

发布于 2018-10-18 14:25:46

尽管尼古拉斯·K的回答对水平切片有好处,但对垂直切片却不起作用。这是一个完全符合OP要求的答案。为了明确起见,我编写了传统的(使用for循环)的方法,以确认OP的意图。然后,我用流来完成它。它既适用于水平切片也适用于垂直切片。

代码语言:javascript
复制
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");
}
票数 1
EN

Stack Overflow用户

发布于 2018-10-18 03:17:06

代码语言:javascript
复制
MyObject obj = Arrays.stream(array)
        .flatMap(Arrays::stream)
        .filter(Objects::nonNull)
        .findFirst()
        .orElse(null);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52865967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档