[英]convert one class object into another using stream
我知道这个问题可能会产生误导,如果可能的话,有人可以纠正它,我不知道如何在这种情况下提出问题。
我正在尝试将 X 类转换为 Y 类(这里 Y 类包含 X 类的字段,但以不同的方式,例如:- Integer a, b;
在类 X 中,在类 Y 中转换为Map<a, b>
而其他变量保持不变。),
在 java 8 中使用流。我试图将最终对象作为 json 返回到 UI部分。 该项目是在spring boot 中完成的。 X 类和 Y 类都包含相同的对象,但 Y 类是为了使 X 类不同我对流不熟悉。
X级
public class X {
private final String thumbnailUrl;
private final Integer duration;
private final String contentId;
private final Date reportDate;
private final Integer count;
public X(Report report, int count) {
this.thumbnailUrl = report.getContent().getThumbnailUrl();
this.duration = report.getContent().getDuration();
this.contentId = report.getContent().getContentId();
this.reportDate = report.getReportDate();
this.count = count;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public Integer getDuration() {
return duration;
}
public String getContentId() {
return contentId;
}
public Date getReportDate() {
return reportDate;
}
public Integer getCount() {
return count;
}
}
Y级
public class Y {
private final String thumbnailUrl;
private final Integer duration;
private final String contentId;
private final Map<Date, Integer> contentList;
public Y(X x, Map<Date, Integer> contentList) {
this.thumbnailUrl = x.getThumbnailUrl();
this.duration = x.getDuration();
this.contentId = x.getContentId();
this.contentList = contentList;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public Integer getDuration() {
return duration;
}
public String getContentId() {
return contentId;
}
public Map<Date, Integer> getContentList() {
return contentList;
}
}
这是我目前从 X 班得到的
[
{
"thumbnailUrl": "a",
"duration": 12,
"contentId": "CNT10",
"reportDate": "2020-01-20",
"count": 3
},
{
"thumbnailUrl": "a",
"duration": 12,
"contentId": "CNT10",
"reportDate": "2020-01-21",
"count": 5
},
{
"thumbnailUrl": "a",
"duration": 12,
"contentId": "CNT10",
"reportDate": "2020-01-22",
"count": 3
},
{
"thumbnailUrl": "a",
"duration": 12,
"contentId": "CNT10",
"reportDate": "2020-01-23",
"count": 4
}
]
使用此代码并返回最终列表后,我在邮递员中获得了上述json。
List<X> x;
List<Y> y;
x = StreamSupport.stream(reportRepository
.reportWithRoll(a, b, c).spliterator(), false)
.map(report -> new X(report, report.getStartCount()))
.collect(Collectors.toList());
我希望将其转换为 Y 类的内容,如下所示。 如何使用 Java 中的流实现这一点?
[
{
"list": [
{
"2020-01-20": 3,
"2020-01-21": 5,
"2020-01-22": 3,
"2020-01-23": 4
}
],
"thumbnailUrl": "a",
"duration": 12,
"contentId": "CNT10"
}
]
我试过这个来获得上面的json格式,但最终得到了重复的数据,对于单个contentId和多个contentId的错误
y = x.stream().map(
rep -> {
Map<Date, Integer> contentList = x.stream().collect(
Collectors.toMap(X::getReportDate, X::getCount)
);
Y yy = new Y(rep, contentList);
return yy;
}
).distinct().collect(Collectors.toList());
我将公共日期和计数:键值对组合成每个唯一“contentId”的单个“列表”(每个唯一的“contentId”都有自己的“thumbnailUrl”和“duration”特定于它,所以当我指的是只有“contentId”是唯一的,它将包括“thumbnailUrl”和“duration”,只有日期和计数对于这些中的每一个来说都是倍数)。
考虑到contentId
会为输入中的任何X
带来相同的thumbnailUrl
和duration
值,您可以分两步完成:
Map<String, X> contentIdLookUp = x.stream()
.collect(Collectors.toMap(X::getContentId, Function.identity()));
List<Y> y = x.stream()
.collect(Collectors.groupingBy(X::getContentId,
Collectors.toMap(X::getReportDate, X::getCount))))
.entrySet().stream()
.map(e -> new Y(contentIdLookUp.get(e.getKey()), e.getValue()))
.collect(Collectors.toList());
由于一个堆栈溢出答案,我找到了使用流本身的解决方案。
y = x.stream()
.map(X::getContentId)
.distinct()
.map(
contentId -> {
return reportModifier(reportViews, contentId);
}
).collect(Collectors.toList());
private Y reportModifier(List<x> x, String contentId) {
Map<Date, Integer> contentList = x.stream()
.filter(a -> a.getContentId().equals(contentId))
.collect(
Collectors.toMap(X::getReportDate, X::getCount)
);
X rv = x.stream()
.filter(a -> a.getContentId().equals(contentId))
.findFirst()
.get();
Y yy = new Y(rv, contentList);
return yy;
}
我得到了以下json
[
{
"thumbnailUrl": "a",
"duration": 12,
"contentId": "CNT10",
"contentList": {
"2020-01-21T18:30:00.000+0000": 3,
"2020-01-20T18:30:00.000+0000": 3,
"2020-01-22T18:30:00.000+0000": 3,
"2020-01-19T18:30:00.000+0000": 3
}
},
{
"thumbnailUrl": "b",
"duration": 12,
"contentId": "CNT12",
"contentList": {
"2020-01-19T18:30:00.000+0000": 3
}
},
{
"thumbnailUrl": "c",
"duration": 12,
"contentId": "CNT11",
"contentList": {
"2020-01-21T18:30:00.000+0000": 3,
"2020-01-20T18:30:00.000+0000": 3,
"2020-01-19T18:30:00.000+0000": 3
}
}
]
如果我理解这个问题,您只是将所有X
对象收集到Y
对象中?
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html
public class YCollector<X, Y, Y> {
public Supplier<Y> supplier() {
return () -> new Y();
}
public BiConsumer<X, Y> accumulator {
return (x, y) -> {
y.list.add(x.thumbnailUrl);
y.duration += x.duration;
...
return y;
}
}
public BinaryOperator<Y> combiner {
return (y1, y2) -> {
return y1.merge(y2);
}
}
public Function<Y, Y> finisher() {
return (y) -> y;
}
}
您基本上只是: - 创建一个新的 Y - 将所有 X 值滚动到 Y - 返回最终的 Y
编辑
我只是注意到您希望最终结果是List<Y>
而不是Y
。 你可以使用同样的东西,你只需要相应地更新方法来处理它。 大概用
class YCollector<X, Map<String,Y>, List<Y>> {
// Update methods to combine into Map<ContentId, Y> and then finalize with map values.
}
为什么复杂? 使用 Map Struts... 您可以在编译时将一个对象转换为另一个对象。 这是一个非常好的库,它在 Spring 中经过测试和使用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.