Конвертировать карту к списку объектов - PullRequest
5 голосов
/ 29 апреля 2020

У меня есть следующая коллекция:

Map<String, Map<SomeEnum, Long>> map = ...

Вот примеры данных:

{"Foo": {
    SomeEnum.BAR1: 1,
    SomeEnum.BAR2: 2,
    SomeEnum.BAR3: 3
  },
 "two": {...}

Поскольку я знаю все перечисления, я хочу преобразовать их в список POJO. Определение объекта следующее:

class SomeClass {
  String name;
  long bar1Value;
  long bar2Value;
  long bar3Value;
}

Я пробовал разные решения, например, с отображением внутри отображения:

map.entrySet().stream()
.map(e -> e.getValue().entrySet().stream().map(innerEntry -> {
  long bar1 = 0;
  long bar2 = 0;
  long bar3 = 0;

  if(innerEntry.getKey().equals(SomeEnum.BAR1)) bar1 = innerEntry.getValue();
  if(innerEntry.getKey().equals(SomeEnum.BAR2)) bar2 = innerEntry.getValue();
  if(innerEntry.getKey().equals(SomeEnum.BAR3)) bar3 = innerEntry.getValue();

  return new SomeClass(e.getKey(), bar1, bar2, bar3);
}).collect(toList()).collect(toList());

К сожалению, я получаю List<List<SomeClass>>.

Есть ли другой, более элегантный способ справиться с этим?

Ответы [ 5 ]

5 голосов
/ 29 апреля 2020

Будет ли это работать для вас?

Требуется конструктор для целевого класса, но он просто получает значения и создает экземпляр. Затем он собирает их в список.

        List<SomeClass> list = map.entrySet().stream()
                .map(e -> new SomeClass(e.getKey(),
                        e.getValue().get(SomeEnum.BAR1),
                        e.getValue().get(SomeEnum.BAR2),
                        e.getValue().get(SomeEnum.BAR3)))
                .collect(Collectors.toList());

Класс с конструктором


class SomeClass {
    String name;
    long bar1Value;
    long bar2Value;
    long bar3Value;

    public SomeClass(String name, long bar1Value, long bar2Value,
        long bar3Value) {
        this.name = name;
        this.bar1Value = bar1Value;
        this.bar2Value = bar2Value;
        this.bar3Value = bar3Value;
    }       
}
4 голосов
/ 29 апреля 2020

Вы можете упростить всю задачу с помощью утилиты для создания SomeClass из внутренней карты:

private SomeClass createSomeClass(String name, Map<SomeEnum, Long> innerMap) {
    return SomeClass.builder()
            .name(name)
            .bar1Value(innerMap.getOrDefault(SomeEnum.BAR1, 0L))
            .bar2Value(innerMap.getOrDefault(SomeEnum.BAR2, 0L))
            .bar3Value(innerMap.getOrDefault(SomeEnum.BAR3, 0L))
            .build();
}

, и тогда ваше отображение будет таким же простым, как -

List<SomeClass> someClassList = map.entrySet().stream()
        .map(e -> createSomeClass(e.getKey(), e.getValue()))
        .collect(Collectors.toList());
2 голосов
/ 29 апреля 2020

Измените map на flatMap и удалите 1-е toList()

List<SomeClass> ss = map.entrySet().stream()
                .flatMap(e -> e.getValue().entrySet().stream().map(innerEntry -> {
                    long bar1 = 0;
                    long bar2 = 0;
                    long bar3 = 0;

                    if(innerEntry.getKey().equals(SomeEnum.BAR1)) bar1 = innerEntry.getValue();
                    if(innerEntry.getKey().equals(SomeEnum.BAR2)) bar2 = innerEntry.getValue();
                    if(innerEntry.getKey().equals(SomeEnum.BAR3)) bar3 = innerEntry.getValue();

                    return new SomeClass(e.getKey(), bar1, bar2, bar3);
                })).collect(Collectors.toList());
1 голос
/ 29 апреля 2020

Вы должны сделать это:

Сначала добавьте метод, чтобы задать de speci c long для каждого значения перечисления, что-то вроде этого:

class SomeClass {

    String name;
    long bar1Value;
    long bar2Value;
    long bar3Value;

// БУКВЫ И УСТАНОВКИ

    public void setByEnum(SomeEnum t, Long value) {
        switch (t) {
            case BAR1:
                this.setBar1Value(value);
                break;
            case BAR2:
                this.setBar2Value(value);
                break;
            case BAR3:
                this.setBar3Value(value);
                break;
        }
    }
}

Затем вы должны сделать l oop карту, примерно так:

 List<SomeClass> list = new ArrayList<>();
    map.forEach((name,values)->{
        SomeClass s = new SomeClass();
        s.setName(name);
        values.forEach((t,value)->{
            s.setByEnum(t, value);
        });
        list.add(s);
    });
0 голосов
/ 29 апреля 2020

Как насчет этого:

ArrayList<Integer> keyList = new ArrayList<Integer>(map.keySet());
for(int i=0; i<keyList.size(); i++){
    Map innermap = map.get(keyList.get(i));
    SomeClass obj = new SomeClass(keyList.get(i),innermap.get('bar1'),innermap.get('bar2'),innermap.get('bar3');
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...