группировка по списку объектов с использованием лямбда в Java - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть эта таблица

Set    question     answer
1        A             X
1        B             X
1        C             X 
1        D             X
2        A             Y
2        B             Y
2        C             Y
2        D             Y

, и мне нужно преобразовать в объект ниже

class Assessment{
    integer setId
    Map<String,String> questiontoanswer
}

с группировкой по Set и картой <question,answer>, так что вывод таблицы вышедолжно быть

List<Assessment> [1 <A:X,B:X,C:X,D:X>, 2 <A:Y,B:Y,C:Y,D:Y>]

Я не могу получить это с лямбда.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

вот еще одно решение с использованием коллекторов

public  class Assessment{
    public Integer set;
    public Map<String,String> questiontoanswer = new HashMap<>();

    public void accept(Row r) {
        this.set = r.set;
        this.questiontoanswer.put(r.question, r.answer);
    }

    public Assessment combine(Assessment other) {
        return this;
    }

    @Override
    public String toString() {
        return "Assessment [set=" + set + ", questiontoanswer=" + questiontoanswer + "]";
    }

}

и действительного кода

    List<Row> rows = Arrays.asList(

        new Row(1,"A","X"),
        new Row(1,"B","X"),
        new Row(1,"C","X"),
        new Row(1,"D","X"),

        new Row(2,"A","Y"),
        new Row(2,"B","Y"),
        new Row(2,"C","Y"),
        new Row(2,"D","Y")
            );

    Collector<Row, Assessment, Assessment> collector = Collector.of(Assessment::new, Assessment::accept, Assessment::combine);

    Map<Integer, Assessment> result = rows.stream().collect(Collectors.groupingBy(Row::getSet, collector));
    System.out.println(result.values());
0 голосов
/ 11 декабря 2018

Это должно работать. Шаги:

  • Группировать входы по setId, что создаст карту с setIds в качестве ключей и список связанных входов в качестве значений
  • Для каждого сгруппированного спискавходных данных, затем превратится в карту вопросов-ответов. Результатом будет карта карт
  • . Преобразование результата в список оценок с помощью простой операции с картой

Код содержит 2примеры как утверждения модульного теста.Доказано, что работает

@Test
public void test(){
    List<InputObject> inputs = new LinkedList<>();
    inputs.add(new InputObject(1,"A","X"));
    inputs.add(new InputObject(1,"B","X"));
    inputs.add(new InputObject(1,"C","X"));
    inputs.add(new InputObject(1,"D","X"));

    inputs.add(new InputObject(2,"A","Y"));
    inputs.add(new InputObject(2,"B","Y"));
    inputs.add(new InputObject(2,"C","Y"));
    inputs.add(new InputObject(2,"D","Y"));

    Map<Integer, Map<String, String>> resultingMap = inputs.stream().collect(Collectors.groupingBy(InputObject::getSet, Collectors.toMap(InputObject::getQuestion, InputObject::getAnswer)));
    List<Assessment> result = resultingMap.entrySet().stream().map(entry -> new Assessment(entry.getKey(), entry.getValue())).collect(Collectors.toList());

    Map<String,String> expectedSet1Data = new LinkedHashMap<>();
    expectedSet1Data.put("A","X");
    expectedSet1Data.put("B","X");
    expectedSet1Data.put("C","X");
    expectedSet1Data.put("D","X");

    Map<String,String> expectedSet2Data = new LinkedHashMap<>();
    expectedSet2Data.put("A","Y");
    expectedSet2Data.put("B","Y");
    expectedSet2Data.put("C","Y");
    expectedSet2Data.put("D","Y");

    assertEquals(new Assessment(1,expectedSet1Data),result.get(0));
    assertEquals(new Assessment(2,expectedSet2Data),result.get(1));
}

@AllArgsConstructor
@Getter
private class InputObject{
    private int set;
    private String question;
    private String answer;
}

@Getter
@AllArgsConstructor
@Data
class Assessment{
    Integer setId;
    Map<String,String> questiontoanswer;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...