以下代码可以工作并且可读,但是在我看来,我有一些中间操作,感觉它们不必要。我写了这个简化版本,因为实际代码是更大过程的一部分。
我有一个Collection
的Widget
,每一个名字和多种类型(由常量表示WidgetType
枚举)。这些多种类型Stream<WidgetType>
虽然可以获取,但如有必要,我可以将它们作为其他类型返回。(由于各种原因,由于在实际代码的后面如何使用这些小部件,因此强烈希望将它们作为返回Stream<WidgetType>
。)
将这些小部件添加到EnumMap<WidgetType, List<Widget>>
中,然后将其翻译成EnumMap<WidgetType, Widget[]>
。
如果每个都Widget
只有一个WidgetType
,这将是一个微不足道的解决方案,但是,由于任何Widget都可以具有1个或多个类型,因此,我使用该Collectors.groupingBy()
方法的语法(及其重载)遍历了我自己。
同样,这是代码示例,功能齐全,可以为我提供所需的确切结果。
class StackOverFlowExample {
private final Map<WidgetType, Widget[]> widgetMap = new EnumMap<>(WidgetType.class);
public static void main(String[] args) { new StackOverFlowExample(); }
StackOverFlowExample() {
Collection<Widget> widgetList = getWidgetsFromWhereverWidgetsComeFrom();
{
final Map<WidgetType, List<Widget>> intermediateMap = new EnumMap<>(WidgetType.class);
widgetList.forEach(w ->
w.getWidgetTypes().forEach(wt -> {
intermediateMap.putIfAbsent(wt, new ArrayList<>());
intermediateMap.get(wt).add(w);
})
);
intermediateMap.entrySet().forEach(e -> widgetMap.put(e.getKey(), e.getValue().toArray(new Widget[0])));
}
Arrays.stream(WidgetType.values()).forEach(wt -> System.out.println(wt + ": " + Arrays.toString(widgetMap.get(wt))));
}
private Collection<Widget> getWidgetsFromWhereverWidgetsComeFrom() {
return Arrays.asList(
new Widget("1st", WidgetType.TYPE_A, WidgetType.TYPE_B),
new Widget("2nd", WidgetType.TYPE_A, WidgetType.TYPE_C),
new Widget("3rd", WidgetType.TYPE_A, WidgetType.TYPE_D),
new Widget("4th", WidgetType.TYPE_C, WidgetType.TYPE_D)
);
}
}
输出:
TYPE_A: [1st, 2nd, 3rd]
TYPE_B: [1st]
TYPE_C: [2nd, 4th]
TYPE_D: [3rd, 4th]
为了完整起见,这里是Widget
类和WidgetType
枚举:
class Widget {
private final String name;
private final WidgetType[] widgetTypes;
Widget(String n, WidgetType ... wt) { name = n; widgetTypes = wt; }
public String getName() { return name; }
public Stream<WidgetType> getWidgetTypes() { return Arrays.stream(widgetTypes).distinct(); }
@Override public String toString() { return name; }
}
enum WidgetType { TYPE_A, TYPE_B, TYPE_C, TYPE_D }
欢迎有任何更好的方法来执行此逻辑的想法。谢谢!
恕我直言,关键是将一个Widget
实例转换为一个Stream<Pair<WidgetType, Widget>>
实例。一旦有了它,我们就可以创建flatMap
一个小部件流并收集结果流。当然我们没有Pair
Java语言,因此必须使用Java AbstractMap.SimpleEntry
。
widgets.stream()
// Convert a stream of widgets to a stream of (type, widget)
.flatMap(w -> w.getTypes().map(t->new AbstractMap.SimpleEntry<>(t, w)))
// Grouping by the key, and do additional mapping to get the widget
.collect(groupingBy(e->e.getKey(),
mapping(e->e.getValue,
collectingAndThen(toList(), l->l.toArray(new Widget[0])))));
PS这是IntelliJ的建议不能缩短方法参考的lambda的场合。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句