Java8流聚合和返回聚合步骤

Java8流聚合和返回聚合步骤,java,java-8,java-stream,Java,Java 8,Java Stream,我不熟悉Java8流api,我正在寻找一种解决方案,以运行我的对象列表并对某些属性进行聚合,以便最终能够获得该属性类型的新列表和所有聚合结果 例如,我的列表中有10个人对象,我想要一个基于第一个人年龄的所有年龄差异的列表 即使在java中,流也可以这样做吗 例如: person1.age = 10 person2.age = 12 person3.age = 20 person4.age = 25 person5.age = 30 在执行流魔术之后,结果应该是int类型的,并且看起来像这样 0

我不熟悉Java8流api,我正在寻找一种解决方案,以运行我的对象列表并对某些属性进行聚合,以便最终能够获得该属性类型的新列表和所有聚合结果

例如,我的列表中有10个人对象,我想要一个基于第一个人年龄的所有年龄差异的列表

即使在java中,流也可以这样做吗

例如:

person1.age = 10
person2.age = 12
person3.age = 20
person4.age = 25
person5.age = 30
在执行流魔术之后,结果应该是int类型的,并且看起来像这样

0
2 //based on first age 12 - 10
10 // based on first age 20 - 10
15 // ...
20

假设列表已经排序(如果没有,则需要按年龄排序)。您可以提取lst.get(0.getAge(),然后执行如下操作:

List<Integer> diff = lst.stream().map((x)->x.getAge()-firstAge).collect(Collectors.toList());
List diff=lst.stream().map((x)->x.getAge()-firstAge.collect(Collectors.toList());

我不允许命名任何
列表
lst
。这是一种不好的做法,但鉴于您没有与我们共享任何代码,我不知道您将人员列表命名为什么。

我认为您有一个Person类,我根据这个假设编写了代码,因为您提供了任何信息

public static void main(String [] args) {
    List<Person> list = new ArrayList<Person>();
    Person person1 = new Person();
    person1.age = 10;
    Person person2 = new Person();
    person2.age = 12;
    Person person3 = new Person();
    person3.age = 20;
    Person person4 = new Person();
    person4.age = 25;
    Person person5 = new Person();
    person5.age = 30;

    list.add(0,person1);
    list.add(person2);
    list.add(person3);
    list.add(person4);
    list.add(person5);

    list.stream().forEach(person -> System.out.println(person.age-list.get(0).age));
}

我假设您有一个名为
Person
的类,上面有一个
getAge()
getter。然后你可以做:

list.stream()
    .skip(1)
    .map(Person::getAge)
    .map(age -> age - list.get(0).getAge())
    .map(Math::abs)
    .forEach(System.out::println);
.skip(1)
-从列表中跳过第一个人,这样结果就不会包含通过比较第一个人的年龄和他们自己得出的0

.map(Math::abs)
-取绝对值,因为“差”总是正的(无论我有10年,你有20年,或者我有20年,你有10年,差都是10)

您可能需要添加
.distinct()
以删除重复


最后,您可能希望使用不同的终端操作—例如,
.collect(toList())
,而不是打印。

即使在java中也可以不编写太多的代码吗?到目前为止,我甚至找不到您尝试过的代码。我的意思是,如果不为stream之类的东西编写自定义colletor,这是可能的。让我们看看,您已经尝试了什么,然后让我们找出可以改进的地方。我的意思是,如果不为stream编写自定义colletor以及来自OP@nullpointer实际上,我认为这不会被视为“自定义收集器”,因为它使用了
Collectors.toList()
生成返回的
列表
{return…;}
lambda语法似乎有点不必要。是否有办法获取以前的和实际的项,并将它们累积到使用流输出的新列表中?这是一个完全不同的问题。答案是肯定的<代码>列表。添加(0,人员1)-此
0
是冗余的。您的流应该有
.skip(1)
,否则它将始终打印0作为第一个结果,因为它将第一人称与自身进行比较。最后,在单个lamba中有这么多操作是一种不好的做法-您应该使用多个
.map(…)
。关于您的编辑,您不应该有添加到某些列表中的有状态使用者函数。这就是
.collect(…)
的作用。
public int getAge(){
    return this.age;
}
list.stream()
    .skip(1)
    .map(Person::getAge)
    .map(age -> age - list.get(0).getAge())
    .map(Math::abs)
    .forEach(System.out::println);