我有两个场景,下面有两个域对象:
List<String> 1 = { id1,id2 ,id3}
List<String> 2 = { "one","two","three"}
1)我有4个列表
List<String> 3 = { "one","two","three"}
List<String> 4 = { 1,2,3}
注意 - 列表1元素对应于列表2元素,如id1 =&#34;一个&#34; ,id2 =&#34;两个&#34;等等
List<A> onjList = {[id=id1,name=one,value=1] , [id=id2,name=two,value=2] ,[id=id3,name=three,value=3]..... }
注 - 列表3元素对应于列表4元素,如&#34;一个&#34; = 1,&#34;两个&#34; = 2等等
这些列表的所有值都对应于A类的属性,所以更多的列表与上面的所有属性一样,因此可能无法制作上述两个列表的地图。
我想要的是根据公共字段合并这些列表,即名称(值为列表2和列表3),如
List<A> onjList - {[id=id1,name=one,value=1] , [id=id2,name=two,value=2] ,[id=id3,name=three,value=3]..... } -----obtained from Step 1
List<PropVal> list 2 = { [id=id1,propVal1=w,propVal2=x,propVal3=y,propVal4=z] , [id=id2,propVal1=a,propVal2=b,propVal3=c,propVal4=d] ....}
2)我有两个列表
List<A> final List = {[id=id1,name=one,value=1,val1=w ,val2=x] , [id=id2,name= two,value = 2,val1 = a ,val2 = b]..... }
我想要一个像
这样的最终清单public class TimerTest extends GdxTest {
@Override
public void create () {
Timer timer = new Timer();
Task task = timer.scheduleTask(new Task() {
@Override
public void run () {
Gdx.app.log("TimerTest", "ping");
}
}, 1, 1);
Gdx.app.log("TimerTest","is task scheduled: "+String.valueOf(task.isScheduled()));
}
}
注意val1 = propVal1和val2 = propVal2。
这两种情况的最佳方法是什么?最好使用java 8流和lambdas?
答案 0 :(得分:2)
您的示例具有误导性。数字没有很好的变量名称,所有四个列表都是相同的顺序,但我认为,你的问题应该暗示前两个列表的顺序可能与其他两个不同,例如。
List<String> aNames=Arrays.asList("one", "two", "three");
List<String> aIDs =Arrays.asList("id1", "id2", "id3");
List<String> bNames =Arrays.asList("two", "one", "three");
List<String> bValues=Arrays.asList("2", "1", "3");
虽然可以在一个步骤中合并所有列表,但重复的线性搜索会产生整体的二次时间复杂度,因此不鼓励这样做。相反,将两个相关列表合并到一个地图中,允许有效查找,然后将另外两个与地图合并:
assert bNames.size()==bValues.size();
Map<String,String> bNameToValue = IntStream.range(0, bNames.size())
.collect(HashMap::new, (m,i) -> m.put(bNames.get(i),bValues.get(i)), Map::putAll);
assert aNames.size()==aIDs.size();
List<A> list = IntStream.range(0, aNames.size())
.mapToObj(i -> new A(aIDs.get(i), aNames.get(i), bNameToValue.get(aNames.get(i))))
.collect(Collectors.toList());
第二项任务的考虑因素是相似的。如果PropVal
元素的列表顺序不同,即需要查找,则建议使用映射,这意味着让上一步生成映射可能更简单。
assert bNames.size()==bValues.size();
Map<String,String> bNameToValue = IntStream.range(0, bNames.size())
.collect(HashMap::new, (m,i)->m.put(bNames.get(i),bValues.get(i)), Map::putAll);
assert aNames.size()==aIDs.size();
Map<String,A> idToA = IntStream.range(0, aNames.size())
.mapToObj(i -> new A(aIDs.get(i), aNames.get(i), bNameToValue.get(aNames.get(i))))
.collect(Collectors.toMap(A::getId, Function.identity()));
List<PropVal> list2 = …
然后,如果A
是可变的:
list2.forEach(pVal -> {
A a = idToA.get(pVal.id);
a.setVal1(pVal.propVal1);
a.setVal2(pVal.propVal2);
a.setVal3(pVal.propVal3);
a.setVal4(pVal.propVal4);
});
List<A> finalList = new ArrayList<>(idToA.values());
或A
是不可变的:
List<A> finalList = list2.stream()
.map(pVal -> {
A a = idToA.get(pVal.id);
return new A(pVal.id, a.getName(), a.getValue(),
pVal.propVal1, pVal.propVal2, pVal.propVal3, pVal.propVal4);
})
.collect(Collectors.toList());
(请注意,这仅包含列表中的A
个实例,其中存在PropVal
。
答案 1 :(得分:0)
请不要滥用java 8功能!您有数据设计缺点。在类中提供有用的方法,迁移到合适的数据结构。在您的模型中,很容易得到不一致的数据。
不要将所有问题委托给lambdas和溪流。