Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
流Java8API中是否有aggregateBy方法?_Java_Java 8_Aggregation - Fatal编程技术网

流Java8API中是否有aggregateBy方法?

流Java8API中是否有aggregateBy方法?,java,java-8,aggregation,Java,Java 8,Aggregation,在Brian Goetz的这张非常有趣但只有一岁的幻灯片中,他展示了一个流API中的aggregateBy()方法,该方法应该将列表(?)的元素聚合到一个映射(给定一个默认初始值和一个操作该值的方法(也适用于重复键)-请参阅演示文稿中的下一张幻灯片) 显然,世界上没有这样的方法。在Java 8中有没有其他类似的方法?假设我们有一个员工列表,其中包含他们的部门和工资,我们需要每个部门支付的总工资 有几种方法可以做到这一点,例如,您可以使用toMap收集器来聚合每个部门的数据: 第一个参数是关键映

在Brian Goetz的这张非常有趣但只有一岁的幻灯片中,他展示了一个流API中的
aggregateBy()
方法,该方法应该将列表(?)的元素聚合到一个映射(给定一个默认初始值和一个操作该值的方法(也适用于重复键)-请参阅演示文稿中的下一张幻灯片)


显然,世界上没有这样的方法。在Java 8中有没有其他类似的方法?

假设我们有一个员工列表,其中包含他们的部门和工资,我们需要每个部门支付的总工资

有几种方法可以做到这一点,例如,您可以使用
toMap
收集器来聚合每个部门的数据:

  • 第一个参数是关键映射器(聚合轴=部门)
  • 第二个是值映射器(要聚合的数据=薪水),以及
  • 第三个是合并函数(聚合数据的方式=对值求和)
例如:

import static java.util.stream.Collectors.*;

public static void main(String[] args) {
  List<Person> persons = Arrays.asList(new Person("John", "Sales", 10000),
                                       new Person("Helena", "Sales", 10000),
                                       new Person("Somebody", "Marketing", 15000));

  Map<String, Double> salaryByDepartment = persons.stream()
          .collect(toMap(Person::department, Person::salary, (s1, s2) -> s1 + s2));
  System.out.println("salary by department = " + salaryByDepartment);
}

聚合操作可以使用类来完成。因此,在视频中,示例相当于:

Map<String, Integer> map = 
    documents.stream().collect(Collectors.groupingBy(Document::getAuthor, Collectors.summingInt(Document::getPageCount)));
Map=
documents.stream().collect(Collectors.groupingBy(Document::getAuthor,Collectors.summingit(Document::getPageCount));
groupingBy
方法将为您提供一个
Map
。现在,您必须使用下游收集器对
列表中与每个键关联的每个文档的所有页数求和

这是通过向
groupingBy
提供一个下游收集器来实现的,它是
summingit
,从而生成一个
映射


他们在文档中给出了基本相同的示例,其中他们计算了各部门员工的工资总额

我认为他们删除了这个操作并创建了
收集器
类,而不是创建了一个有用的类,它包含了许多您通常会使用的缩减。

是我在Java 8中找到的最接近这个聚合的东西。尽管它是第三方API,但签名似乎排列得很好——您提供了一些函数从中获取值,一些值的终端函数(在本例中为零),以及一些将函数和值组合在一起的函数

这感觉很像一个,这将使我们有能力做到这一点

Map<String, Integer> strIntMap =
    intList.stream()
           .collect(Collectors
               .groupingBy(Document::getAuthor,
                Collectors.summingInt(Document::getPageCount)));
Map strIntMap=
intList.stream()
.收藏(收藏家)
.groupingBy(文档::getAuthor,
Collectors.summingit(Document::getPageCount));

然后,我们将列表中每个条目的作者姓名分组,并将作者的总页码加在一张
地图

+1中,这是一个很好的问题;非常非常有启发性。事实上,
收集器
不仅有助于聚合;你也有一些基本的东西,比如
Collectors.toList()
等等;从长远来看,所有这些操作都在同一个“功能包”中可能会变得相当混乱。我想JDK可以使用一个
Aggregates
class…@fge也许Brian Goetz会看到这个线程并解释rational,这会很有趣。是的,aggregateBy()是对现在包含在收集器中的概念的早期尝试。(虽然我认为所引用的示例早在一年多前就出现了。)aggregateBy()的一个问题是,它只进入了“一级深度”。Collectors.groupingBy()通过“下游”收集器解决了这一问题,并且更具可组合性。@BrianGoetz OK,现在我看到了
收集器
界面,所有这些都在
收集器
中是有道理的,但是我的话,理解这个界面背后的概念需要时间!我想对
收集器
接口的解释才是真正的答案question@fge那将是一个更长的解释!但要坚持下去,这是值得的。一旦你掌握了概念,它就会非常强大。
Map<String, Integer> map = 
    documents.stream().collect(Collectors.groupingBy(Document::getAuthor, Collectors.summingInt(Document::getPageCount)));
Map<String, Integer> strIntMap =
    intList.stream()
           .collect(Collectors
               .groupingBy(Document::getAuthor,
                Collectors.summingInt(Document::getPageCount)));