鉴于
class Foo {
private Long id;
private String name;
private String category;
private List<String> categories;
// getters & setters
}
我有一个对象列表。
final Foo f1 = new Foo(1L, "a", "c1");
final Foo f2 = new Foo(1L, "a", "c2");
final Foo f3 = new Foo(2L, "a", "c1");
final List<Foo> li = List.of(f1, f2, f3);
看起来像
{[Foo [id=1, name=a, category=c1, categories=null], Foo [id=1, name=a, category=c2, categories=null]], [Foo [id=2, name=a, category=c1, categories=null]]}
我想将此转换为
[Foo [id=1, name=a, category=null, categories=[c1, c2]], Foo [id=2, name=a, category=null, categories=[c1]]]
i、 e.将个人类别整理成类别列表。
这是实现我想要的当前代码。
public static void main(final String[] args) {
final Foo f1 = new Foo(1L, "a", "c1");
final Foo f2 = new Foo(1L, "a", "c2");
final Foo f3 = new Foo(2L, "a", "c1");
final List<Foo> li = List.of(f1, f2, f3);
li.forEach(e -> System.out.println(e));
final Map<Long, List<Foo>> collect = li.stream().collect(Collectors.groupingBy(Foo::getId));
System.out.println(collect);
final List<Foo> grouped = new ArrayList<>();
collect.forEach((k, v) -> {
System.out
.println("key=" + k + "val=" + v.stream().map(e1 -> e1.getCategory()).collect(Collectors.toList()));
final Foo foo = collect.get(k).get(0);
foo.setCategories(v.stream().map(e1 -> e1.getCategory()).collect(Collectors.toList()));
foo.setCategory(null);
grouped.add(foo);
});
System.out.println(grouped);
}
有什么方法可以使用流来做到这一点吗
这个问题在本质上类似于Group by和sum对象,比如SQLJavalambdas?但对我没有帮助,因为这里完成了聚合,而这里不是聚合。
可以通过实现合并功能来实现,该功能将在类别列表中累积类别,然后使用流的减少操作:
class Foo {
static Foo merge(Foo accum, Foo other) {
if (null == accum.categories) {
accum.categories = new ArrayList<>();
if (null != accum.category) {
accum.categories.add(accum.category);
accum.category = null;
}
}
accum.categories.add(other.category);
return accum;
}
}
实施:
static List<Foo> joinedCategoriesReduce(List<Foo> input) {
return input
.stream()
.collect(Collectors.groupingBy(Foo::getId)) // Map<Integer, List<Foo>>
.values().stream() // Stream<List<Foo>>
.map(v -> v.stream() // Stream<Foo>
.reduce(new Foo(v.get(0).getId(), v.get(0).getName(), (String)null), Foo::merge)
)
.collect(Collectors.toList());
}
测验
final Foo f1 = new Foo(1L, "a", "c1");
final Foo f2 = new Foo(1L, "a", "c2");
final Foo f3 = new Foo(2L, "a", "c1");
final List<Foo> li = List.of(f1, f2, f3);
joinedCategoriesReduce(li).forEach(System.out::println);
输出
Foo(id=1, name=a, category=null, categories=[c1, c2])
Foo(id=2, name=a, category=null, categories=[c1])
另一种选择是提供一个接受类别列表的Foo构造函数:
// class Foo
public Foo(Long id, String name, List<String> cats) {
this.id = id;
this.name = name;
this.categories = cats;
}
然后,可以使用类别列表轻松地将映射条目重新映射到Foo实例:
static List<Foo> joinedCategoriesMap(List<Foo> input) {
return input
.stream()
.collect(Collectors.groupingBy(Foo::getId))
.values().stream()
.map(v -> new Foo(
v.get(0).getId(),
v.get(0).getName(),
v.stream().map(Foo::getCategory).collect(Collectors.toList()))
)
.collect(Collectors.toList());
}
在线演示
问题:我有一个接口类型列表,在存储到数据库之前需要将其转换为数据库DTO列表。我不熟悉Java8流和映射函数,所以任何帮助都会很好。 研究:我试图在映射中使用instanceOf,但总是出现编译错误。 下面是不同的类及其层次结构。 为了映射Dog和Cat类,我创建了单独的函数。 使用streams,我尝试根据对象类型使用不同的映射函数。 我总是在Collectors.to列表()编译问题。我如何解
我试图将一系列模式(其类型为string)转换为谓词,出于某些原因,我的大脑一直以接近以下代码的方式结束: 显然无法编译。编写转换流的最佳方式是什么? 这是我收到的错误消息:
我有2个对象ExpertJpa到ExpertDto的现有映射,需要另一个参数来过滤ExpertJpa。这个映射工作正常,现在我尝试将ExpertJpa列表转换为ExpertDto列表,我添加了第二个参数。 在构建时,我收到错误消息,即List是一个接口,不能是实例…… 错误:(53,18) java:返回类型java.util.List是一个抽象类或接口。提供非抽象/非接口结果类型或工厂方法。
我正在尝试将列表的元组转换为列表,但是我没有成功,所以我有了这个函数 获取输入,例如: ( [1,2,3,4], [7,8,9] ) 并应返回: [1,7,2,8,3,9,4] 我有 结果是: [1,7,2,8,3,9***异常:hw2.hs:29: 1-54:函数函数中的非穷尽模式 我知道我得到这个错误,因为列表是不一样的大小,你们怎么认为我可以解决这个问题
问题内容: 我有SourceObjects列表,我需要将其转换为ResultObjects列表。 我可以使用ResultObject的方法将一个对象获取到另一个对象: 我当然可以这样: 但对于能够展示如何使用 rxJava 进行相同操作的人,我将非常感激。 问题答案: 如果发出,则可以使用以下运算符: (将您的列表转换为可观察项) (将您的商品转换为其他商品) 运算符(将完成的Observable