Как использовать потоковые операции java8 для выбора только одного элемента из каждого ключа на карте после группировки по двум полям?

#java-8 #stream #grouping

Вопрос:

У меня есть список людей, имеющих несколько полей.

Мне нужно сгруппироваться по двум из этих полей. (возраст и имя)

Таким образом, результатом, который я получу, будет карта карты, подобная:

 Maplt;Integer, Maplt;String, Listlt;Persongt;gt; result;  

теперь мне нужно удалить второй ключ в результате, а также сократить список до одного человека. (это означает, что мне нужно сгруппировать всех людей по возрасту, а затем составить список людей с разными именами для одного и того же возраста.)Правила выбора лиц с одинаковыми именами определены в такой функции, как Сокращение числа лиц(Список лиц){} В настоящее время мой код выглядит следующим образом:

 Maplt;Integer, Listlt;Persongt;gt; select(Listlt;Persongt; persons){   Maplt;Integer, Maplt;string, Listlt;Persongt;gt; result =   persons  .stream()  .collect(groupingBy(p -gt; p.getAge(),  groupingBy(p -gt; p.getName(), toUnmodifiableList()) // HERE  // CAN WE REPLACE "toUnmodifiableList()" with something  //related to "selectPerson" method to simplify the flow?  )  );   return result  .entrySet()  .stream()  .map(this::ignoreName)  .collect(toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)) }   Map.Entrylt;Integer, Listlt;Persongt;gt; ignoreName(Map.Entrylt;int, Maplt;String, Listlt;Persongt;gt;gt; persons){  Listlt;Persongt; ps =   persons  .getValue()  .values()  .stream()  .map(this::selectPerson)  .collect(toUnmodifiableList());  return AbstractMap.SimpleImmutableEntrylt;gt;(persons.getKey(), ps); }  Person selectPerson(Listlt;Persongt; persons){  ///... }  

Теперь мой вопрос в том, есть ли способ упростить это? делая что-то непосредственно внутри потока groupingBy?

 Example: Person1: personID 1, age 24, name john Person2: personID 2, age 24, name anna Person3: personID 3, age 25, name mike Person4: PersonID 4, age 25, name mike  Person5: PersonID 5, age 25, name bob  Maplt;Integer, Maplt;String, Listlt;Persongt;gt;gt;: 24 -gt; john -gt; personID 1  -gt; anna -gt; personID 2 25 -gt; mike -gt; personID 3  -gt; personID 4  -gt; bob -gt; personID 5 Expected Result: Maplt;Integer, Listlt;Persongt;gt;: 24 -gt; personID1  -gt; personID2 25 -gt; personID 3 or 4, depending on selectPerson logic  -gt; personID 5    

Комментарии:

1. Этот код не будет компилироваться. Мы не можем использовать примитивы в качестве параметра типа.

2. В вашем select методе, как вы можете ожидать, что вернетесь Maplt;Integer, Persongt; , когда два человека могут быть одного возраста? Так и должно было быть Maplt;Integer, Listlt;Persongt;gt; . И в своем selectPerson методе вы возвращаете a Person без передачи критериев, на чем основывать выбор.

3. @WJS, спасибо за ответ. Ты прав. это должен быть список. причина в том, что я просто не могу разместить здесь свой рабочий код, поэтому я создал этот класс person.