【问题标题】:How to apply in Function<T, R> argument from List (not List)如何在 List(不是 List)的 Function<T, R> 参数中应用
【发布时间】:2019-07-24 22:51:19
【问题描述】:

我有一个方法,它返回公司作为键和员工列表作为值 &lt;T&gt; Map&lt;String, List&lt;T&gt;&gt; getUserPerCompany(final Function&lt;User, T&gt; converter)。 该方法接受converter 参数,该参数在测试中返回字符串(员工姓名+ 姓氏)。它应该返回:Map&lt;String, List&lt;String&gt;&gt;。我创建了这个实现:

return getUserStream().collect(toMap(Company::getName, c -&gt; converter.apply(c.getUsers())));

错误是: apply (domain.User) in Function cannot be applied to (java.util.List&lt;domain.User&gt;)

我的问题是我不知道如何将员工传递到“申请”列表而不是完整列表。

我的其他尝试:

  • return getUserStream().collect(toMap(Company::getName, c -&gt; converter.apply((User) c.getUsers().listIterator())));
  • return getUserStream().collect(toMap(Company::getName, c -&gt; converter.apply((User) c.getUsers().subList(0, c.getUsers().size()))));
  • return getUserStream().collect(toMap(Company::getName, c -&gt; converter.apply((User) c.getUsers().iterator())));

【问题讨论】:

  • 未阅读问题,但第一个标题“来自列表(不是列表)”不清楚。

标签: java functional-programming java-stream functional-interface


【解决方案1】:

我想这就是你要找的东西

<T> Map<String, List<T>> getUserPerCompany(final Function<User, T> converter) {
    return getUserStream().collect(Collectors.toMap(
            c -> c.getName(),
            c -> c.getUsers()
                  .stream()
                  .map(converter)
                  .collect(Collectors.toList())
    ));
}

用法示例是

final Map<String, List<String>> users = getUserPerCompany(user -> user.getName() + " " + user.getSurname());

基本上你需要map每个User,应用输入Function

【讨论】:

  • 非常感谢!我刚刚将getUserStream () 替换为getCompanyStream ()(公司包含用户),但这些是我不在这里的内部方法。再次感谢您的解决方案,它有效并且很清楚。
【解决方案2】:

您可以使用Collectors.groupingBy() 并编写自定义Collector

<T> Map<String, List<T>> getUserPerCompany(final Function<User, T> converter) {
    return getUserStream().collect(
            Collectors.groupingBy(
                    c -> c.getName(),
                    Collector.of(
                            ArrayList::new,                  //init accumulator
                            (list, c)-> c.getUsers()         //processing each element
                                         .stream()
                                         .map(converter)
                                         .forEach(list::add),
                            (result1, result2) -> {          //confluence 2 accumulators 
                                result1.addAll(result2);     //in parallel execution
                                return result1;
                            }
                    )
            )
    ); 
}

【讨论】:

  • Stream 低于 foriforeach=> 替换它使用 for
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多