Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java流映射列表<;Src>;到一个对象Tgt?_Java_Java Stream - Fatal编程技术网

如何使用Java流映射列表<;Src>;到一个对象Tgt?

如何使用Java流映射列表<;Src>;到一个对象Tgt?,java,java-stream,Java,Java Stream,首先,这个问题来自我的实际工作。我需要解决它,我做一些折衷的工作来实现它的不完美。此外,我对基本数据结构进行了抽象和简化,以避免敏感数据 我的源和目标对象是Src和Tgt,如下所示: 公共类Src{ int-id; 布尔标志; 整数计数; //构造函数Getter和Setter方法。。。。。。 } 公共级Tgt{ int-id; 整数真计数; int假计数; //构造函数Getter和Setter方法。。。。。。 } 现在我有一个名为srcList的Src对象列表。我想将列表合并为一个名为Tg

首先,这个问题来自我的实际工作。我需要解决它,我做一些折衷的工作来实现它的不完美。此外,我对基本数据结构进行了抽象和简化,以避免敏感数据

我的源和目标对象是
Src
Tgt
,如下所示:

公共类Src{
int-id;
布尔标志;
整数计数;
//构造函数Getter和Setter方法。。。。。。
}
公共级Tgt{
int-id;
整数真计数;
int假计数;
//构造函数Getter和Setter方法。。。。。。
}
现在我有一个名为
srcList
的Src对象列表。我想将列表合并为一个名为
Tgt
的对象,该操作类似于计算
Src
对象中有多少
flag

在java8流中,我尝试使用
flatmap
map
操作符将列表转换为一个对象,如下代码所示:


公共类TestSrc2Tgt{
公共列表列表SRC2LISTTGTG(列表srcList){
Tgt Tgt=新的Tgt();
for(Src-Src:srcList){
tgt.setId(src.getId());
if(src.isFlag()){
tgt.setTrue_count(tgt.getTrue_count+src.getCount());
}
否则{
tgt.setFalse_count(tgt.getFalse_count+src.getCount());
}
}
/*这是我的问题,我不想使用列表
我想要的是将列表转换为Tgt,Tgt是一种组合列表
*/
List tgtList=new ArrayList();
tgtList.add(tgt);
返回tgtList;
}
公共静态void main(字符串[]args){
TestSrc2Tgt TestSrc2Tgt=新的TestSrc2Tgt();
List srcList=new ArrayList();
添加(新的Src(1,true,15));
添加(新的Src(1,false,20));
添加(新的Src(1,false,110));
添加(新的Src(2,true,40));
添加(新的Src(2,false,250));
添加(新的Src(2,true,420));
//1.对id进行聚类并按id生成列表
Map srcMap=srcList.stream()
.collect(Collectors.groupingBy(Src::getId,Collectors.toList());
//2.通过ListSrc2ListGT方法计算有多少Src标志为真或假
//我讨厌的是这里
列表tgtMaplist=
srcMap.entrySet().stream().map(e->{return testSrc2Tgt.listscrc2listtgt(e.getValue());})
.map(item->item.get(0)).collect(Collectors.toList());
tgtMaplist.stream().forEach(t->{
System.out.println(t.getId());
System.out.println(t.getFalse_count());
System.out.println(t.getTrue_count());
});
}
}
代码确实可以工作,但我讨厌
listscrc2listtgt()
方法和
获取
listtgmplist中的
映射(item->item.get(0))
。我的想法是从
List
Tgt
的单向转换,而不是从
List
List
(只有一个元素),然后从
List
获取
Tgt
这是一种浪费和不完美的实现方式

处于理想状态

公共Tgt列表SRC2LISTTGTG(列表srcList){
Tgt Tgt=新的Tgt();
for(Src-Src:srcList){
tgt.setId(src.getId());
if(src.isFlag()){
tgt.setTrue_count(src.getCount());
}
否则{
tgt.setFalse_count(src.getCount());
}
}
返回tgt;
}
在主要方法中:

List tgtMaplist=srcMap.entrySet().stream()
.map(e->{return testSrc2Tgt.listscrc2listtgt(e.getValue());})
.collect(Collectors.toList());

它更舒适。因为没有通过使用
.get(0)
方法从tgtlist获取中间进程,这看起来不那么冗余。但是,理想的代码无法通过编译器。

如果返回
tgt
而不是
tgtList
内部
listscrc2listtgt
,则理想的解决方案应该可以工作:

公共Tgt列表SRC2LISTTGTG(列表srcList){
Tgt Tgt=新的Tgt();
for(Src-Src:srcList){
tgt.setId(src.getId());
if(src.isFlag()){
tgt.setTrue_count(src.getCount());
}否则{
tgt.setFalse_count(src.getCount());
}
}
返回tgt;
}
要在
main
方法中提高流的可读性和可用性:

  • 如果不需要密钥,请不要使用
    entrySet()
    。改用
    values()
  • 然后可以使用方法引用缩短lambda
List tgtMaplist=srcMap.values().stream()
.map(testSrc2Tgt::ListSrc2ListTgt)
.collect(Collectors.toList());

对于此代码,您需要一个
类-可以从库中创建,也可以自己创建。您可以使用
收集器来代替自定义收集器。Partitioning by
,但这样更有效

List<Tgt> tgtList = srcList.stream()
        .collect(Collectors.groupingBy(Src::getId, Collector.of(
                () -> new Pair<>(0L, 0L),
                (pair, src) -> {
                    if (src.isFlag())
                        pair.setKey(pair.getKey() + src.getCount());
                    else
                        pair.setValue(pair.getValue() + src.getCount());
                },
                (pairA, pairB) -> new Pair<>(pairA.getKey() + pairB.getKey(), pairA.getValue() + pairB.getValue())
        )))
        .entrySet()
        .stream()
        .map(entry -> new Tgt(entry.getKey(), (int) (long) entry.getValue().getKey(), (int) (long) entry.getValue().getValue()))
        .collect(Collectors.toList());
List tgtList=srcList.stream()
.collect(Collector.groupingBy)(Src::getId,Collector.of(
()->新的一对(0升,0升),
(配对,src)->{
if(src.isFlag())
setKey(pair.getKey()+src.getCount());
其他的
setValue(pair.getValue()+src.getCount());
},
(pairA,pairB)->新对(pairA.getKey()+pairB.getKey(),pairA.getValue()+pairB.getValue())
)))
.entrySet()
.stream()
.map(entry->new Tgt(entry.getKey(),(int)(long)entry.getValue().getKey(),(int)(long)entry.getValue().getValue())
.collect(Collectors.toList());

您可以先将
Src
映射到
Tgt
。然后使用
toMap
map by
Map<Integer, Tgt> tgtMap = srcList.stream()
                .map(s -> new Tgt(s.getId(),                     
                                 (s.isFlag() ? s.getCount() : 0),
                                 (s.isFlag() ? 0 : s.getCount())))
                .collect(Collectors.toMap(Tgt::getId, e -> e,    
                                    (a, b) -> new Tgt(a.getId(), 
                                                      a.getTrue_count() + b.getTrue_count(), 
                                                      a.getFalse_count() + b.getFalse_count())));

List<Tgt> tgtList = new ArrayList(tgtMap.values()); // Create list from map values
s -> new Tgt(s.getId(), (s.isFlag() ? s.getCount() : 0),(s.isFlag() ? 0 :s.getCount()))
Collectors.toMap(Tgt::getId,
                 e -> e,
                 (a, b) -> new Tgt(a.getId(), 
                                   a.getTrue_count() + b.getTrue_count(), 
                                   a.getFalse_count() + b.getFalse_count()))
Map<Integer, Tgt> tgtMap = srcList.stream()
                .map(s -> /*transform into Tgt*/)
                .collect(Collectors.toMap(Tgt::getId, e -> e, /*Merge function*/));
int id = srcList.get(srcList.size() - 1).getId();
int true_count = srcList.stream().filter(Src::getFlag).count();
int false_count = srcList.size() - true_count;
List<Src> srcList = new ArrayList<Src>();
srcList.add(new Src(1, true, 15));
srcList.add(new Src(1, false, 20));
srcList.add(new Src(1, false, 110));
srcList.add(new Src(2, true, 40));
srcList.add(new Src(2, false, 250));
srcList.add(new Src(2, true, 420));

List<Tgt> tgtList = srcList.stream()
    .collect(Collectors.groupingBy(Src::getId, Collectors.toList()))
    .entrySet().stream()
    .map(e -> 
        new Tgt(e.getKey(), 
                e.getValue().stream().mapToInt(s -> s.getFlag() ? s.getCount() : 0).sum(),
                e.getValue().stream().mapToInt(s -> !s.getFlag() ? s.getCount() : 0).sum())
    ).collect(Collectors.toList());

System.out.println(tgtList);
[Tgt [id=1, true_count=15, false_count=130], Tgt [id=2, true_count=460, false_count=250]]
Map<Integer, Tgt> tgtMap = new HashMap<Integer, Tgt>();
for (Src src: srcList) {
    Tgt tgt = new Tgt(src.getId(), src.getFlag() ? src.getCount() : 0, !src.getFlag() ? src.getCount() : 0);
    tgtMap.compute(src.getId(), (k, v) -> 
        v == null ? tgt
            : new Tgt(src.getId(), 
                tgt.getTrue_count() + v.getTrue_count(), 
                tgt.getFalse_count() + v.getFalse_count()));
}