example - stream() map java 8




Lista de Java 8<V> en el Mapa<K, V> (12)

Quiero traducir una lista de objetos en un mapa usando las secuencias y lambdas de Java 8

Así es como lo escribiría en Java 7 y más abajo.

private Map<String, Choice> nameMap(List<Choice> choices) {
        final Map<String, Choice> hashMap = new HashMap<>();
        for (final Choice choice : choices) {
            hashMap.put(choice.getName(), choice);
        }
        return hashMap;
}

Puedo lograrlo fácilmente utilizando Java 8 y Guava, pero me gustaría saber cómo hacerlo sin Guava.

En guayaba:

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, new Function<Choice, String>() {

        @Override
        public String apply(final Choice input) {
            return input.getName();
        }
    });
}

Y guayaba con Java 8 lambdas.

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, Choice::getName);
}

Una opción más de manera sencilla.

Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));

Aquí está la solución por StreamEx

StreamEx.of(choices).toMap(Choice::getName, c -> c);

Basado en la documentación de Collectors es tan simple como:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName,
                                              Function.identity()));

Es posible usar streams para hacer esto. Para eliminar la necesidad de usar Collectors explícita, es posible importar a toMap forma estática (según lo recomendado por Effective Java, tercera edición).

public class BookKeyFinder implements KeyFinder<Long, Book> {
    @Override
    public Long getKey(Book e) {
        return e.getPrice()
    }
}

Estaba tratando de hacer esto y descubrí que, al usar las respuestas anteriores, al usar Functions.identity() para la clave del Mapa, tuve problemas con el uso de un método local como this::localMethodName para funcionar realmente debido a problemas de tipeo .

Functions.identity() realidad hace algo con la escritura en este caso, por lo que el método solo funcionaría devolviendo Object y aceptando un parámetro de Object

Para resolver esto, terminé deshaciéndome de Functions.identity() y usando s->s en s->s lugar.

Por lo tanto, mi código, en mi caso, para enumerar todos los directorios dentro de un directorio, y para cada uno usa el nombre del directorio como la clave para el mapa y luego llama a un método con el nombre del directorio y devuelve una colección de elementos, se ve así:

Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));

Esto se puede hacer de 2 maneras. Que la persona sea la clase que vamos a usar para demostrarlo.

public class Person {

    private String name;
    private int age;

    public String getAge() {
        return age;
    }
}

Permitir que las personas sean la lista de Personas a convertir en el mapa.

1.Utilizando Simple foreach y una expresión Lambda en la lista

Map<Integer,List<Person>> mapPersons = new HashMap<>();
persons.forEach(p->mapPersons.put(p.getAge(),p));

2.Utilizando Collectors on Stream definido en la lista dada.

 Map<Integer,List<Person>> mapPersons = 
           persons.stream().collect(Collectors.groupingBy(Person::getAge));

Por ejemplo, si desea convertir campos de objeto a mapear:

Objeto de ejemplo:

class Item{
        private String code;
        private String name;

        public Item(String code, String name) {
            this.code = code;
            this.name = name;
        }

        //getters and setters
    }

Y la operación convertir lista a mapa:

List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));

Map<String,String> map = list.stream()
     .collect(Collectors.toMap(Item::getCode, Item::getName));

Puede crear un flujo de los índices utilizando un IntStream y luego convertirlos en un mapa:

Map<Integer,Item> map = 
IntStream.range(0,items.size())
         .boxed()
         .collect(Collectors.toMap (i -> i, i -> items.get(i)));

Si no le importa usar bibliotecas de terceros, la biblioteca cyclops-react ciclops de AOL (divulgación, contribuyo) tiene extensiones para todos los tipos de colecciones JDK , incluyendo List y Map .

ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);

Use getName () como la clave y la elección en sí misma como el valor del mapa:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));

Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
                .toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));

Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));

Incluso sirve para este propósito para mí,

Map<String,Choice> map=  list1.stream().collect(()-> new HashMap<String,Choice>(), 
            (r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));




java-stream