Java 收集器:将 Object 的列表分组到具有计算值的其他 objects 的列表中
Java Collectors: Grouping a list of Object into a list of other objects with calculated values
我最近接触了 Java 8 及其 Stream API,最近接触了它的 Collectors API,我发现它有潜力做很多很多转换为流,但我有一种情况,我不确定 java 8 是否可能,甚至根本不可能。我有两个 类:
public class ClassA{
public int group
public int id
public String title
public String description
public String keyword
public String specialValue
}
public class ClassB{
public String newTitle
public String joinedDescriptions
}
我想知道是否可以从 ClassA objects 的列表生成一个 ClassB objects 的分组列表,其中的值是从 ClassA 的字段计算得出的。具体来说:
- 通过组和 id 的组合对 ClassA 进行分组
- 分组的 ClassB 实例将在关键字 = 1 时具有 newTitle = 标题,或在关键字 = 2 时具有 newTitle = specialValue
- 最后 joinedDescriptions,是分组的 ClassA 实例中所有描述的串联。
我知道可以使用 Collectors 的 groupingBy 使用 classA 类的 lambda 对 ClassA 实例进行分组 -> String.valueOf(classA.group) + String.valueOf(classA.id), 或类似的,但我不知道要为每个分组实例实现其他计算值。
我希望它解释得足够好。
以下是要执行的步骤;类似于@Joakim Danielson 在评论中提到的内容:
按照您在 post 中提到的那样对源列表进行分组,然后在 ClassB
中添加一个构造函数,该构造函数采用 ClassA
的列表,然后执行您的逻辑在设置标题和加入描述方面提到:
所以这将是您的流管道:
List<ClassB> result = source.stream()
.collect(groupingBy(s -> s.getGroup() + "" + s.getId())) // Map<String, List<ClassA>>
.values() // Collection<List<ClassA>>
.stream() // Stream<List<ClassA>>
.map(ClassB::new) // Stream<ClassB>
.collect(Collectors.toList()); //List<ClassB>>
您需要在 ClassB 中定义一个构造函数:
public ClassB(List<ClassA> source) {
ClassA item = source.get(0);
if(“1”.equals(item.getKeyword())
this.newtitle = item.getTitle();
else if(“2”.equals(item.getKeyword())
this.newtitle = “specialValue”; // or make a call to a method to compute the value
this.joinedDescriptions = String.join(“, “, source.stream().map(ClassA::getDescription).collect(toList()));
}
我最近接触了 Java 8 及其 Stream API,最近接触了它的 Collectors API,我发现它有潜力做很多很多转换为流,但我有一种情况,我不确定 java 8 是否可能,甚至根本不可能。我有两个 类:
public class ClassA{
public int group
public int id
public String title
public String description
public String keyword
public String specialValue
}
public class ClassB{
public String newTitle
public String joinedDescriptions
}
我想知道是否可以从 ClassA objects 的列表生成一个 ClassB objects 的分组列表,其中的值是从 ClassA 的字段计算得出的。具体来说:
- 通过组和 id 的组合对 ClassA 进行分组
- 分组的 ClassB 实例将在关键字 = 1 时具有 newTitle = 标题,或在关键字 = 2 时具有 newTitle = specialValue
- 最后 joinedDescriptions,是分组的 ClassA 实例中所有描述的串联。
我知道可以使用 Collectors 的 groupingBy 使用 classA 类的 lambda 对 ClassA 实例进行分组 -> String.valueOf(classA.group) + String.valueOf(classA.id), 或类似的,但我不知道要为每个分组实例实现其他计算值。
我希望它解释得足够好。
以下是要执行的步骤;类似于@Joakim Danielson 在评论中提到的内容:
按照您在 post 中提到的那样对源列表进行分组,然后在 ClassB
中添加一个构造函数,该构造函数采用 ClassA
的列表,然后执行您的逻辑在设置标题和加入描述方面提到:
所以这将是您的流管道:
List<ClassB> result = source.stream()
.collect(groupingBy(s -> s.getGroup() + "" + s.getId())) // Map<String, List<ClassA>>
.values() // Collection<List<ClassA>>
.stream() // Stream<List<ClassA>>
.map(ClassB::new) // Stream<ClassB>
.collect(Collectors.toList()); //List<ClassB>>
您需要在 ClassB 中定义一个构造函数:
public ClassB(List<ClassA> source) {
ClassA item = source.get(0);
if(“1”.equals(item.getKeyword())
this.newtitle = item.getTitle();
else if(“2”.equals(item.getKeyword())
this.newtitle = “specialValue”; // or make a call to a method to compute the value
this.joinedDescriptions = String.join(“, “, source.stream().map(ClassA::getDescription).collect(toList()));
}