我觉得还是原始一点,每层写个函数,每个函数里最多一个 for 循环,看起来还简单些。
如果用 stream,需要采用多次(5次) flatMap,每次都会产生一个新的结构……貌似 Java 又没有动态对象一说,所以这个事情就比较麻烦了。
我用 js 给你写个三层的示例(前面一多半都是在生成数据)
Array.prototype.flatMap = function(mapper) {
return this.reduce((all, t) => {
const list = mapper(t);
all.push(...list);
return all;
}, []);
};
const data = [
{
name: "A",
list: [
{
name: "a",
subs: [1, 2, 3]
},
{
name: "b",
subs: [4, 5]
}
]
},
{
name: "B",
list: [
{
name: "c",
subs: [11, 12, 13, 14]
},
{
name: "d",
subs: [15, 16]
},
{
name: "e",
subs: [17, 18]
}
]
}
];
const result = data
.flatMap(t => t.list.map(item => ({
level1: t.name,
item: item
})))
.flatMap(t => t.item.subs.map(item => ({
level1: t.level1,
level2: t.item.name,
value: item
})))
.forEach(t => console.log(t));
结果
{ level1: 'A', level2: 'a', value: 1 }
{ level1: 'A', level2: 'a', value: 2 }
{ level1: 'A', level2: 'a', value: 3 }
{ level1: 'A', level2: 'b', value: 4 }
{ level1: 'A', level2: 'b', value: 5 }
{ level1: 'B', level2: 'c', value: 11 }
{ level1: 'B', level2: 'c', value: 12 }
{ level1: 'B', level2: 'c', value: 13 }
{ level1: 'B', level2: 'c', value: 14 }
{ level1: 'B', level2: 'd', value: 15 }
{ level1: 'B', level2: 'd', value: 16 }
{ level1: 'B', level2: 'e', value: 17 }
{ level1: 'B', level2: 'e', value: 18 }
用 C# 我也能写出来,因为 C# 可以动态生成对象(不需要定义结构)
用 Java 当然也写得出来,可以定义一个包括 6 层数据的对象,在每次 flatMap 的时候 clone() 若干次……主要是构造数据太麻烦
想了下,还是给你个 Java 的示意吧,反正不如直接 for 来得简单
class TheModel {
private PidFeedback pid;
private AdvertiserFeedback biz;
private CampaignFeedback campaign;
private AdgroupFeedback adgroup;
private CreativeFeedback creative;
private FeedbackInfo f;
public TheModel setPid(PidFeedback pid) {
this.pid = pid;
return this;
}
public TheModel setBiz(AdvertiserFeedback biz) {...}
...
public TheModel clone() {
TheModel m = new TheModel();
m.pid = pid;
m.biz = biz;
m.campaign = campaign;
m.adgroup = adgroup;
m.creative = creative;
m.f = f;
}
}
feedbackCombination.getPidFeedbacksList().stream()
.map(pid -> new TheModel().getPid(pid))
.flatMap(m -> m.pid
.getAdvertiserFeedbacksList().stream()
.map(biz -> m.clone().setBiz(biz)))
.flatMap(m -> n.biz
.getCampaignFeedbacksList().stream()
.map(campaign -> m.clone().setCampaign(campaign)))
.....
.forEach(m -> {
Feedback feedback = new Feedback();
feedback.setTimestamp(m.getF().getTimestamp() * Constants.HOUR_MILLISEC);
feedback.addItem(Constants.ACTION, Integer.toString(m.getF().getAction().getNumber()));
feedback.addItem(Constants.PID, m.getPid.getPid());
feedback.addItem(Constants.BIZ, Integer.toString(m.getBiz.getAdvertiserId()));
....
feedbacks.add(feedback);
})