如何在Java 8流中从Collector中调用方法?

huangapple go评论63阅读模式
英文:

How do you call a method from within a Collector in Java 8 Streaming?

问题

以下是您提供的代码的中文翻译部分:

原始代码:

private Map<Florist, EnumSet<Flower>> localMethod(List<FlowerSellers> branchList) {
    Map<Florist, EnumSet<Flower>> availableFlowers = new EnumMap<>(Florist.class);

    branchList.stream()
              .filter(f -> f instanceof FlorestFranchised)
              .forEach(f -> availableFlowers.put(
                      FlorestHelperClass.florestTypeForKey(f.id()), 
                      ((FlorestFranchised) f).getFlowers()));

    return availableFlowers;
}

重写使用收集器的代码:

return branchList.stream()
                 .filter(p -> p instanceof FlorestFranchised)
                 .map(p -> (FlorestFranchised) p)
                 .collect(Collectors.toMap(
                         FlorestFranchised::getId,  
                         FlorestFranchised::getFlowers));

在您的重写中,似乎您想要调用FlorestHelperClass.florestTypeForKey方法来获取Florest,但它不适用于Collectors.toMap方法。要实现这一点,您可以使用Collectors.toMap的另一重载版本,将一个函数用于键映射:

return branchList.stream()
                 .filter(p -> p instanceof FlorestFranchised)
                 .map(p -> (FlorestFranchised) p)
                 .collect(Collectors.toMap(
                         p -> FlorestHelperClass.florestTypeForKey(p.getId()),  
                         FlorestFranchised::getFlowers));

这个版本中,FlorestHelperClass.florestTypeForKey(p.getId())将用作键的映射函数,以获取正确的Florest对象。

英文:

I have a bit of code that is working functionally as I want it to:

private Map&lt;Florist, EnumSet&lt;Flower&gt;&gt; localMethod(List&lt;FlowerSellers&gt; branchList) {
    Map&lt;Florist, EnumSet&lt;Flower&gt;&gt; availableFlowers = new EnumMap&lt;&gt;(Florist.class);

    branchList.stream()
              .filter(f -&gt; f instanceof FlorestFranchised)
              .forEach(f -&gt; availableFlowers.put(
                      FlorestHelperClass.florestTypeForKey(f.id()), 
                      ((FlorestFranchised) f).getFlowers()));

    return availableFlowers;
}

For sake of argument the helper class method is:

public static Florist FlorestTypeForKey(String id) {
	return FLOREST_MAP.get(id);
}

I would like to do this with a collector instead so I wanted to do this ...

return branchList.stream()
                 .filter(p -&gt; p instanceof FlorestFranchised)
	             .map(p -&gt; (FlorestFranchised) p)
	             .collect(Collectors.toMap(
                         FlorestFranchised::getId,  
                         FlorestFranchised::getFlowers));

But obviously this fails because it is not doing the helper class lookup and so rather than returning a map of <Florest, Flowers> it is returning <String, Flowers>

This fails though :

return branchList.stream()
                 .filter(p -&gt; p instanceof FlorestFranchised)
	             .map(p -&gt; (FlorestFranchised) p)
	             .collect(Collectors.toMap(
                         FlorestHelperClass.florestTypeForKey(FlorestFranchised::getId),
                         FlorestFranchised::getFlowers));

Can anyone tell me how I should call the lookup methods (FlorestHelperClass.florestTypeForKey) in the collector? Is it possible?

答案1

得分: 3

Collectors.toMap需要两个函数来分别从传递给collect方法的值中创建键和值。因此,您可以这样做:

return branchList.stream()
    .filter(p -> p instanceof FlorestFranchised)
    .map(p -> (FlorestFranchised) p)
    .collect(Collectors.toMap(
        p -> FlorestHelperClass.florestTypeForKey(p.getId()),   // 键
        p -> p.getFlowers()                                     // 值
));

最后一个lambda表达式可以替换为FlorestFranchised::getFlowers

英文:

Collectors.toMap requires two functions creating a key and value respectively from the value passed into the collect method. Therefore you can do this:

return branchList.stream()
    .filter(p -&gt; p instanceof FlorestFranchised)
    .map(p -&gt; (FlorestFranchised) p)
    .collect(Collectors.toMap(
        p -&gt; FlorestHelperClass.florestTypeForKey(p.getId()),   // key
        p -&gt; p.getFlowers()                                     // value
));

The last lambda expression can be replaced with FlorestFranchised::getFlowers.

答案2

得分: 2

你可以将首个映射为 AbstractMap.SimpleEntry 对,然后使用 Collectors.toMap

return branchList
    .stream()
    .filter(p -> p instanceof FlorestFranchised)
    .map(p -> (FlorestFranchised) p)
    .map(p -> new AbstractMap.SimpleEntry<>(
                 FlorestHelperClass.florestTypeForKey(p.getId()), p.getFlowers()))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
英文:

You can map first as AbstractMap.SimpleEntry pair then use Collectors.toMap

return branchList
    .stream()
    .filter(p -&gt; p instanceof FlorestFranchised )
    .map(p -&gt; (FlorestFranchised) p )
    .map(p -&gt; new AbstractMap.SimpleEntry&lt;&gt;(
                 FlorestHelperClass.florestTypeForKey(p.getId()), p.getFlowers()))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

huangapple
  • 本文由 发表于 2020年8月3日 22:29:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63231342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定