Jai*_*Jai 1 java java-8 java-stream
比方说我有一个List<List<Animal>> animals.此嵌套列表表示每个地方包含动物列表的地点列表.
我需要找出至少出现在两个不同地方的动物类型列表.我知道我可以做正常的循环并做到这一点.有什么办法可以通过Stream API完成吗?
例:
List<List<Animal>> animals = new ArrayList<>();
animals.add(Arrays.asList(new Dog(), new Cat()));
animals.add(Arrays.asList(new Dog(), new Bird()));
animals.add(Arrays.asList(new Bird()));
Run Code Online (Sandbox Code Playgroud)
预期(相当于):
List<Class<? extends Animal>> animalTypes = Arrays.asList(Dog.class, Bird.class);
Run Code Online (Sandbox Code Playgroud)
至于尝试,我只设法将内部列表转换为一组类:
animals.stream().map(place -> place.stream().map(animal -> animal.getClass()).collect(Collectors.toSet()));
Run Code Online (Sandbox Code Playgroud)
没有Stream API的代码:
final List<List<Animal>> animals = new ArrayList<>();
animals.add(Arrays.asList(new Dog(), new Cat()));
animals.add(Arrays.asList(new Dog(), new Bird()));
animals.add(Arrays.asList(new Bird()));
final Map<Class<? extends Animal>, Integer> count = new HashMap<>();
for (final List<Animal> place : animals) {
final Set<Class<? extends Animal>> uniqueTypes = new HashSet<>();
for (final Animal animal : place) {
uniqueTypes.add(animal.getClass());
}
for (final Class<? extends Animal> type : uniqueTypes) {
if (!count.containsKey(type))
{
count.put(type, 1);
}
else
{
count.put(type, count.get(type).intValue() + 1);
}
}
}
final List<Class<? extends Animal>> typesAppearingAtLeastAtTwoPlaces = new ArrayList<>();
for (final Class<? extends Animal> type : count.keySet()) {
if (count.get(type).intValue() >= 2) {
typesAppearingAtLeastAtTwoPlaces.add(type);
}
}
System.out.println(typesAppearingAtLeastAtTwoPlaces);
Run Code Online (Sandbox Code Playgroud)
输出:
[class Test$Dog, class Test$Bird]
Run Code Online (Sandbox Code Playgroud)
首先,计算所有动物,然后选择出现不止一次的动物:
import static java.util.stream.Collectors.*;
.....
Map<Class<? extends Animal>, Long> animalCounts = animals.stream()
.flatMap(
lst -> lst.stream()
.map(a -> a.getClass())
.distinct() // in case several of the same animal are in the same place
)
.collect(groupingBy(x -> x, counting()));
List<Class<? extends Animal>> animalTypes = animalCounts.entrySet().stream()
.filter(e -> e.getValue() > 1)
.map(Map.Entry::getKey)
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
440 次 |
| 最近记录: |