【问题标题】:How to convert a 2D array of integers to a 2D array of booleans using streams in Java?如何使用 Java 中的流将 2D 整数数组转换为 2D 布尔数组?
【发布时间】:2019-01-09 19:04:40
【问题描述】:

我有一个二维整数数组(0 或 1),像这样......

int [][] gridInt = {
        {0, 0, 0, 1, 0, 0},
        {0, 0, 1, 1, 0, 0},
        {1, 0, 1, 0, 0, 1},
        {0, 0, 0, 0, 1, 0},
        {0, 1, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0}
    };

我想使用 Java 流和 .map() 将其转换为布尔值的二维数组。结果数组为:

boolean[][] gridBool = {
        {false, false, false, true, false, false},
        {false, false, true, true, false, false},
        {true, false, true, false, false, true},
        {false, false, false, false, true, false},
        {false, true, false, false, false, false},
        {false, false, false, false, false, false}
    };

我最近的尝试是:

boolean[][] gridBool = Arrays.stream(gridInt)
    .map(row -> Arrays.stream(row)
        .mapToObj(i -> i == 1)
        .toArray(Boolean[]::new)
    )
    .toArray(Boolean[][]::new);

但是我的代码没有编译,错误信息是:

error: incompatible types: inferred type does not conform to upper bound(s)
        .toArray(Boolean[][]::new);
                ^
inferred: Boolean[]
upper bound(s): boolean[],Object

你能告诉我我做错了什么以及如何解决它吗?谢谢。

【问题讨论】:

  • boolean 不是Boolean
  • 这很简单 - 只需将一个小写 b 更改为大写 BBoolean [][] gridBool...

标签: java dictionary multidimensional-array type-conversion java-stream


【解决方案1】:

您可以将生成的Array 更改为Boolean

Boolean[][] grid1bool = Arrays.stream(gridInt)
                .map(row -> Arrays.stream(row)
                    .mapToObj(i -> i == 1)  //Stream<Boolean>
                    .toArray(Boolean[]::new)
                )
                .toArray(Boolean[][]::new);

mapToObj 需要Object,而不是原始类型boolean,所以我们不能使用toArray(boolean[][]::new)

【讨论】:

    【解决方案2】:

    如果您因此需要Boolean[][],那么只需将接收器类型从boolean 更改为Boolean

    Boolean[][] gridBool = Arrays.stream(gridInt)
                    .map(row -> Arrays.stream(row)
                            .mapToObj(i -> i == 1)
                            .toArray(Boolean[]::new)
                    )
                    .toArray(Boolean[][]::new);
    

    但是,结果您似乎想要boolean[][];不幸的是,由于没有BooleanStream,因此通过流执行此操作是不明智的,因为可读性或简洁性不是最好的,而是命令式方法会更好:

    boolean[][] result = new boolean[gridInt.length][];
    for (int i = 0; i < gridInt.length; i++) {
         boolean[] temp = new boolean[gridInt[i].length];
         for (int j = 0; j < gridInt[i].length; j++) 
              temp[j] = gridInt[i][j] == 1;         
         result[i] = temp;
    }
    

    【讨论】:

    • 谢谢。我确实想到了迭代方法,但我认为我可以以某种方式使用地图方法来使其更容易/更短。所以我猜流不能很好地处理除 int、long 和 double 以外的原始类型?或者至少还给他们?
    • @EJC 是的,有很多关于为什么没有CharStreamBooleanStream 的问题。当您想将某种类型的特定序列转换为charboolean 的序列时,它不是最易读/最简洁的,并且不会比使用命令式循环更好,因为没有CharStream 也没有@987654333 @,但是正如您所提到的,其他原始类型都有专门的流,因此它们会很方便。
    • @EJC 如果您想为此使用流,则需要事先声明boolean[][] result = new boolean[gridInt.length][];,然后使用IntStream.range + forEach 完成工作,这基本上就是上述命令式方法确实可以,但以更惯用的方式。
    【解决方案3】:

    您可以将逻辑简化为:

    boolean[][] gridBool = new boolean[gridInt.length][gridInt[0].length]; // NxN grid
    for (int i = 0; i < gridInt.length; i++) {
        for (int j = 0; j < gridInt[0].length; j++) {
            gridBool[i][j] = gridInt[i][j] != 0;
        }
    }
    

    注意:这避免了为每次迭代创建临时数组,因此可以进一步节省空间,并预先使用精确的边界初始化数组。

    【讨论】:

      猜你喜欢
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多