#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
методе вы возвращаете aPerson
без передачи критериев, на чем основывать выбор.3. @WJS, спасибо за ответ. Ты прав. это должен быть список. причина в том, что я просто не могу разместить здесь свой рабочий код, поэтому я создал этот класс person.