2
votes

Comment convertir un tableau 2D d'entiers en un tableau 2D de booléens à l'aide de flux en Java?

J'ai un tableau 2D d'entiers (0 ou 1) comme so ...

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

et je veux le convertir en un tableau 2D de booléens en utilisant des flux Java et .map ( ). Le tableau résultant étant:

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

Ma dernière tentative était:

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}
    };

Mais mon code ne se compile pas, l'erreur message est:

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}
    };

Pouvez-vous me dire ce que je fais mal et comment y remédier? Merci.


2 commentaires

booléen n'est pas booléen !


C'est facile - il suffit de changer une minuscule b en majuscule B . Booléen [] [] gridBool ...


3 Réponses :


2
votes

Vous pouvez changer le Array résultant en Boolean:

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

mapToObj nécessite un Object , pas le type primitif boolean , nous ne pouvons donc pas utiliser toArray (boolean [] [] :: new) .


0 commentaires

1
votes

si vous avez besoin d'un Boolean [] [] en conséquence, c'est aussi simple que de changer le type de récepteur de boolean à Boolean :

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;
}

Cependant, il semble que vous vouliez un booléen [] [] comme résultat; malheureusement, comme il n'y a pas de BooleanStream , il ne serait pas judicieux d'effectuer cela via un flux car la lisibilité ou la concision n'est pas la meilleure, plutôt une approche impérative serait préférable:

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


3 commentaires

Merci. J'ai pensé à l'approche itérative mais j'ai pensé que je pourrais d'une manière ou d'une autre utiliser l'approche cartographique pour la rendre plus facile / plus courte. Donc, je suppose que les flux ne fonctionnent pas bien avec les types primitifs autres que int, long et double? Ou du moins les rendre?


@EJC ouais, il y a eu un bon nombre de questions sur la raison pour laquelle il n'y a pas de CharStream ou BooleanStream . lorsque vous voulez convertir une séquence particulière d'un certain type en une séquence de char ou boolean ce n'est pas le plus lisible / concis et ne serait pas mieux que d'utiliser un impératif boucle car il n'y a pas de CharStream ni de BooleanStream , cependant, comme vous l'avez mentionné, les autres types primitifs ont des flux spécialisés pour chacun donc ils seraient pratiques.


@EJC si vous vouliez utiliser un flux pour cela, vous devrez déclarer un booléen [] [] result = new boolean [gridInt.length] []; au préalable puis utiliser IntStream .range + forEach pour faire le travail, ce qui est essentiellement ce que fait l'approche impérative ci-dessus, mais d'une manière plus idiomatique.



1
votes

Vous pouvez simplement simplifier la logique comme suit:

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;
    }
}

Remarque : cela évite une création de tableau temporaire pour chaque itération, d'où vous permet d’économiser de l’espace supplémentaire et initialise également le tableau avec des limites précises à l’avance.


0 commentaires