java软件任务分组管理,分组对象java 8

I have something like the below :

public class MyClass {

private Long stackId

private Long questionId

}

A collection of say 100, where the stackid could be duplicate with different questionIds. Its a one to many relationship between stackId and questionId

Is there a streamy, java 8 way to convert to the below strcuture :

public class MyOtherClass {

private Long stackId

private Collection questionIds

}

Which would be a collection of 25, with each instance having a nested collection of 4 questionIds.

Input :

[{1,100},{1,101},{1,102},{1,103},{2,200},{2,201},{2,202},{1,203}]

Output

[{1, [100,101,102,103]},{2,[200,201,202,203]}]

解决方案

The straight-forward way with the Stream API involves 2 Stream pipelines:

The first one creates a temporary Map> of stackId to questionIds. This is done with the groupingBy(classifier, downstream) collectors where we classify per the stackId and values having the same stackId are mapped to their questionId (with mapping) and collected into a list with toList().

The second one converts each entry of that map into a MyOtherClass instance and collects that into a list.

Assuming you have a constructor MyOtherClass(Long stackId, Collection questionIds), a sample code would be:

Map> map =

list.stream()

.collect(Collectors.groupingBy(

MyClass::getStackId,

Collectors.mapping(MyClass::getQuestionId, Collectors.toList())

));

List result =

map.entrySet()

.stream()

.map(e -> new MyOtherClass(e.getKey(), e.getValue()))

.collect(Collectors.toList());

Using StreamEx library, you could do that in a single Stream pipeline. This library offers a pairing and first collectors. This enables to pair two collectors and perform a finisher operation on the two collected results:

The first one only keeps the first stackId of the grouped elements (they will all be the same, by construction)

The second one mapping each element into their questionId and collecting into a list.

The finisher operation just returns a new instance of MyOtherClass.

Sample code:

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

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

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

import static one.util.streamex.MoreCollectors.first;

import static one.util.streamex.MoreCollectors.pairing;

// ...

Collection result =

StreamEx.of(list)

.groupingBy(

MyClass::getStackId,

pairing(

collectingAndThen(mapping(MyClass::getStackId, first()), Optional::get),

mapping(MyClass::getQuestionId, toList()),

MyOtherClass::new

)

).values();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Java 8中,可以使用Stream的groupBy和summingInt方法来实现自定义分组求和并排序。 首先,我们需要一个数据集合,然后将其转化为Stream对象。假设我们有一个Person类,其中包含姓名和年龄两个属性。 ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // getters and setters } ``` 现在,我们可以创建一个Person对象的列表,并将其转化为Stream对象。 ```java List<Person> persons = new ArrayList<>(); persons.add(new Person("Tom", 20)); persons.add(new Person("Alice", 22)); persons.add(new Person("Bob", 25)); persons.add(new Person("Tom", 30)); persons.add(new Person("Alice", 35)); persons.add(new Person("Bob", 28)); ``` 接下来,我们可以使用groupBy方法根据姓名将Person对象分组。然后,我们可以使用summingInt方法对分组进行求和,计算每个组的年龄总和。 ```java Map<String, Integer> sumByGroup = persons.stream() .collect(Collectors.groupingBy(Person::getName, Collectors.summingInt(Person::getAge))); ``` 现在,sumByGroup是一个Map对象,键是姓名,值是年龄总和。例如,对于上述例子,sumByGroup的值为{"Tom": 50, "Alice": 57, "Bob": 53}。 最后,我们可以按照年龄总和对分组进行排序。我们可以使用entrySet方法将Map对象的键值对转化为一个Set对象,并使用stream方法对其进行排序。排序完成后,我们可以使用collect方法将其转化为一个LinkedHashMap对象,以保持排序顺序。 ```java Map<String, Integer> sortedSumByGroup = sumByGroup.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k, v) -> k, LinkedHashMap::new)); ``` 现在,sortedSumByGroup是一个已按照年龄总和排序的Map对象。例如,对于上述例子,sortedSumByGroup的值为{"Tom": 50, "Bob": 53, "Alice": 57}。 综上所述,以上就是使用Java 8 Stream自定义分组求和并排序的实现方法。 ### 回答2: Java 8引入的Stream API提供了一种简洁而强大的方式,使我们能够对集合进行各种操作,包括分组、求和和排序等。下面是使用Stream API自定义分组求和并排序的一个示例实现。 假设我们有一个包含商品信息的列表,每个商品有名称和价格两个属性。我们希望按照商品名称的首字母进行分组,并计算每个组中商品的总价格,并根据总价格进行排序。 首先,我们需要创建一个包含商品信息的列表: List<Goods> goodsList = new ArrayList<>(); goodsList.add(new Goods("Apple", 10)); goodsList.add(new Goods("Banana", 20)); goodsList.add(new Goods("Orange", 30)); goodsList.add(new Goods("Pear", 40)); 接下来,我们可以使用Stream的groupingBy方法,以商品名称的首字母作为分组条件: Map<Character, List<Goods>> groupedGoods = goodsList.stream() .collect(Collectors.groupingBy(g -> g.getName().charAt(0))); 上述代码将商品列表按照名称的首字母进行了分组,结果保存在groupedGoods变量中,其中键表示首字母,值表示对应分组的商品列表。 接下来,我们可以使用Stream的mapToInt方法和sum方法,分别计算每个分组中商品价格的总和: Map<Character, Integer> sumOfGroup = groupedGoods.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream().mapToInt(Goods::getPrice).sum())); 上述代码将计算每个分组中商品价格的总和,并将结果保存在sumOfGroup变量中。 最后,我们可以使用Stream的sorted方法,根据分组的总价格进行排序: List<Map.Entry<Character, Integer>> sortedSumOfGroup = sumOfGroup.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toList()); 上述代码将根据分组的总价格进行排序,并将结果保存在sortedSumOfGroup变量中。 通过以上步骤,我们完成了对商品列表的自定义分组求和并排序的实现。可以根据实际需要,对代码进行修改和扩展。 ### 回答3: Java8的Stream提供了很多强大的函数式编程特性,包括自定义分组、求和和排序。下面是一个实现自定义分组求和并排序的例子: 假设我们有一个包含学生信息的列表,每个学生有姓名、年龄和成绩三个属性。我们想要按照年龄分组,并计算每个年龄组的平均成绩,然后按照平均成绩从高到低进行排序。 首先,我们需要创建一个包含学生信息的类,并在该类中定义姓名、年龄和成绩三个属性的getter方法。 然后,我们可以使用Java8的Stream来实现分组、求和和排序操作。首先,将学生列表转换成一个Stream对象,然后使用collect方法对Stream进行分组,使用averagingDouble方法对每个年龄组的成绩进行求平均值,最后使用sorted方法进行排序。 代码示例如下: ```java import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student("张三", 20, 80), new Student("李四", 22, 90), new Student("王五", 20, 85), new Student("赵六", 22, 95), new Student("钱七", 23, 75) ); Map<Integer, Double> averageScores = students.stream() .collect(Collectors.groupingBy(Student::getAge, Collectors.averagingDouble(Student::getScore))); List<Map.Entry<Integer, Double>> sortedScores = new ArrayList<>(averageScores.entrySet()); Collections.sort(sortedScores, (e1, e2) -> e2.getValue().compareTo(e1.getValue())); for (Map.Entry<Integer, Double> entry : sortedScores) { System.out.println("年龄:" + entry.getKey() + " 平均成绩:" + entry.getValue()); } } } class Student { private String name; private int age; private int score; public Student(String name, int age, int score) { this.name = name; this.age = age; this.score = score; } public String getName() { return name; } public int getAge() { return age; } public int getScore() { return score; } } ``` 以上代码将输出按照平均成绩从高到低排序的结果,例如: 年龄:22 平均成绩:92.5 年龄:20 平均成绩:82.5 年龄:23 平均成绩:75.0 这是一个简单的自定义分组求和并排序的实现。我们使用了Stream的groupingBy、averagingDouble和sorted方法完成了这个任务

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值