1
votes

Convertir un tableau de nombres en carte à l'aide de Java Streams

J'ai le tableau suivant en Java:

The method collect(Supplier<R>, ObjIntConsumer<R>, BiConsumer<R,R>) in the type IntStream is not applicable for the arguments (Collector<Object,?,Map<Object,Object>>)

Je veux le convertir en une instance java.util.Map qui a le index du tableau en tant que clés et la valeur à l'index en tant que valeurs pour la carte. Comme ça,

Type mismatch: cannot convert from Collector<Object,capture#1-of ?,Map<Object,Object>> to Supplier<R>

J'ai essayé ce qui suit:

IntStream.range(0, arr.length)
                 .collect(Collectors.toMap(k -> k, k -> arr[k]));

Mais cela entraîne des erreurs de compilation comme: p >

0 = 4
1 = 5
2 = 6

et

int arr[] = {4,5,6};

Qu'est-ce que je fais de mal ici?

Je vais juste plus tous les indices, puis les mapper sur des clés et des valeurs où je me trompe?


3 commentaires

Est-ce que cela répond à votre question? Tableau int Java 8 à mapper


IntStream n'a qu'une seule méthode de collecte : docs.oracle. com / fr / java / javase / 11 / docs / api / java.base / java / ut‌ il /… . Essayez de le mapper à un Stream comme ceci: IntStream.range (0, arr.length) .mapToObj (Integer :: valueOf) .collect (Collectors.to‌ Map ( k -> k, k -> Integer.valueOf (arr [k.intValue ()]))); .


Essayez d'utiliser un Stream of Integer en utilisant plutôt IntStream # boxed.


4 Réponses :


3
votes

Essai :

0 = 4
1 = 5
2 = 6

int arr[] = {4,5,6};
Map<Integer, Integer> resultMap = IntStream.range(0, arr.length).boxed()
                    .collect(Collectors.toMap(Function.identity(), k -> arr[k]));
resultMap.entrySet().forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));


6 commentaires

Integer # valueOf n'est pas nécessaire.


@Jason merci, j'ai mis à jour la réponse


Pas de soucis, également au lieu d'utiliser k -> k, vous pouvez simplement utiliser Function # identity pour utiliser la valeur d'entrée du Stream et la clé de la carte.


@NitinBisht Qu'est-ce que Function.identity () ?


@ ng.newbie Function.identity () renvoie une fonction qui renvoie toujours son argument d'entrée.


@ ng.newbie vous pouvez également l'utiliser comme Collectors.toMap (k -> k, k -> arr [k]) . Bien que pour mieux comprendre, vous pouvez vous référer à stackoverflow.com/a/28041480/8258942



1
votes

Vous devez mettre en boîte l'IntStream et utiliser la valeur groupingBy pour obtenir le nombre souhaité.

Essayez ceci:

Map<Integer, Long> map = Arrays
        .stream(arr)
        .boxed()
        .collect(Collectors.groupingBy(e -> e, Collectors.counting()));


0 commentaires

2
votes

Vous utilisez IntStream qui est déballé. Vous devez utiliser .boxed () .

Si votre tableau est ordonné, vous pouvez faire:

Map<Integer, Integer> map = IntStream.range(0, arr.length).boxed()
        .collect(Collectors.toMap(Function.identity(), i -> arr[i]));

S'il n'est pas commandé, vous pouvez faire:

int arr[] = {4,5,6};

Map<Integer, Integer> map = Arrays.stream(arr).boxed()
    .collect(Collectors.toMap(i -> Arrays.binarySearch(arr, i), Function.identity()));

map.entrySet().forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));


2 commentaires

Qu'est-ce que Function.identity () ??


C'est similaire à i -> i (mais pas le même). De javadoc: "Renvoie une fonction qui renvoie toujours son argument d'entrée.". Si vous souhaitez obtenir plus d'informations, essayez cette réponse: stackoverflow.com/questions/28032827/...



1
votes

Il existe plusieurs solutions.

1. Pour chaque boucle

Map<Integer, Integer> map = Stream.iterate(0, i -> i+1)
    .limit(arr.length)
    .collect(Collectors.toMap(Function.identity(), i -> arr[i]));

À mon avis, c'est la plus claire en termes de lisibilité.


2. IntStream avec une plage de la longueur du tableau

Map<Integer, Integer> map = IntStream.range(0, arr.length)
    .boxed()
    .collect(Collectors.toMap(Function.identity(), i -> arr[i]));

Cela semble être votre tentative initiale. Vous devez soit boxer avec boxed () à Stream afin d'utiliser collect avec un seul Collector code >.


3. Stream :: iterate et Stream::limit final

Map<Integer, Integer> map = new HashMap<>();
for (int i=0; i<arr.length; i++) {
    map.put(i, arr[i]);
}

C'est une simple génération sans fin d'une séquence par un limitée par la longueur du tableau.


0 commentaires