Был задан вопрос о том, как решить эту проблему "с помощью потоков Java" .Следующий - это с использованием потоков.И for
- петля.
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class VoteCountTest
{
public static void main(String[] args)
{
Map<LocalDateTime, Set<Vote>> votes =
new LinkedHashMap<LocalDateTime, Set<Vote>>();
Set<Vote> yes0 = votesWith(VoteType.NO, VoteType.NO);
Set<Vote> yes1 = votesWith(VoteType.YES, VoteType.NO);
Set<Vote> yes2 = votesWith(VoteType.YES, VoteType.YES);
votes.put(LocalDateTime.of(2000, 1, 1, 1, 1), yes1);
votes.put(LocalDateTime.of(2000, 1, 2, 1, 1), yes0);
votes.put(LocalDateTime.of(2000, 1, 3, 1, 1), yes2);
votes.put(LocalDateTime.of(2000, 1, 4, 1, 1), yes1);
System.out.println(getWinningDateA(votes));
System.out.println(getWinningDateB(votes));
}
public static Optional<LocalDateTime> getWinningDateA(
Map<LocalDateTime, Set<Vote>> votes)
{
LocalDateTime bestDate = null;
long maxCount = -1;
Predicate<Vote> votedYes = v -> v.getVote() == VoteType.YES;
for (Entry<LocalDateTime, Set<Vote>> entry : votes.entrySet())
{
long count = entry.getValue().stream().filter(votedYes).count();
if (count > maxCount)
{
maxCount = count;
bestDate = entry.getKey();
}
}
return Optional.ofNullable(bestDate);
}
// As of https://stackoverflow.com/a/53771478/3182664
public static Optional<LocalDateTime> getWinningDateB(Map<LocalDateTime, Set<Vote>> votes)
{
return votes.entrySet() // Set<Entry<LocaleDateTime, Set<Vote>>
.stream() // Stream<Entry<LocaleDateTime, Set<Vote>>
.flatMap(e -> e.getValue().stream().filter(a -> a.getVote() == VoteType.YES)
.map(x -> e.getKey())) // Stream<LocalDateTime>
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) // Map<LocaleDateTime, Long>
.entrySet() // Set<Entry<LocaleDateTime, Long>>
.stream() // Stream<Entry<LocaleDateTime, Long>>
.max(Comparator.comparingLong(Map.Entry::getValue)) // Optional<Entry<LocaleDateTime, Long>>
.map(Map.Entry::getKey); // Optional<LocalDateTime>
}
//=========================================================================
enum VoteType {YES, NO, MAYBE}
static class Vote {
private String name;
private VoteType vote;
public Vote(String name, VoteType vote) {
super();
this.name = name;
this.vote = vote;
}
public VoteType getVote()
{
return vote;
}
}
private static Set<Vote> votesWith(VoteType... voteTypes)
{
Set<Vote> votes = new LinkedHashSet<Vote>();
for (int i = 0; i < voteTypes.length; i++)
{
votes.add(new Vote("v" + i, voteTypes[i]));
}
return votes;
}
}
Сравните это с «чистым потоком» и подумайте, какой код вы бы хотели читать, понимать и поддерживать в будущем.Тогда выбирайте мудро.
(Я знаю, что, строго говоря, это не может быть желаемым ответом на вопрос. Но некоторые люди, похоже, намеренно используют потоки с чрезмерным использованием и получают своего рода гикигордость от этого. Я также иногда наслаждаюсь этим как вызовом * 1015. * Но воображение, что I может быть тем, кто должен поддерживать эти мерзости функционального программирования в будущем, заставляет меня содрогаться ....)