Java2个对象形集合按某一个属性合并
怪我咯
怪我咯 2017-04-18 10:35:35
[Java讨论组]
怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(7)
高洛峰

如果两个集合的泛型类是同一类,重写equals方法,直接用set合并。不是同一类没法合并。

巴扎黑

不知道你说的是不是这个:

package com.segmentfault.qa.java;

import java.util.*;

public class ListMergeTest {

    public static void main(String[] args) {
        List<ClsA> listA = new ArrayList<>();
        List<ClsB> listB = new ArrayList<>();
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        
        listA.add(new ClsA("001", "Alex"));
        listA.add(new ClsA("002", "Bill"));
        listA.add(new ClsA("003", "Carl"));
        
        listB.add(new ClsB("001", 1000));
        listB.add(new ClsB("002", 2000));
        listB.add(new ClsB("004", 4000));
        
        for(ClsA a: listA){
            Map<String, Object> map = new HashMap<>();
            String empNo = a.getEmpNo();
            for(ClsB b: listB){
                if(b.getEmpNo().equals(empNo)){
                    map.put("money", b.getMoney());
                }
            }
            map.put("name", a.getName());
            resultMap.put(empNo, map);
        }
        
        System.out.println(resultMap);
    }
}

class ClsA{
    private String empNo;
    private String name;
    
    public ClsA(String empNo, String name){
        this.empNo = empNo;
        this.name = name;
    }
    
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

class ClsB{
    private String empNo;
    private int money;
    
    public ClsB(String empNo, int money){
        this.empNo = empNo;
        this.money = money;
    }
    
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }
}
PHP中文网

感觉循环肯定是少不了,但是感觉怎么减少循环才是优化方向吧,减少一个循环数据量越大效率越明显。

package demo_java;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test1 {
    public static void main(String[] args) {
        List<ObjA> listA = new ArrayList<>();
        List<ObjB> listB = new ArrayList<>();
        // 构建10W数据
        for(int i=0; i<100000; ++i) {
            ObjA a = new ObjA("no"+i, "name"+i);
            listA.add(a);
        }
        for(int i=8888; i<106666; ++i) {
            ObjB b = new ObjB("no"+i, "infos"+i);
            listB.add(b);
        }
        int aSize = listA.size();
        int bSize = listB.size();
        // listA Size: 100000
        System.out.println("listA Size: " + aSize);
        // listB Size: 97778
        System.out.println("listB Size: " + bSize);
        Long sTime = System.currentTimeMillis();
        Map<String, ObjC> map = new HashMap<>();
        // 减少一个循环,取最大的循环数
        int maxSize = aSize > bSize ? aSize : bSize;
        for(int i=0; i<maxSize; ++i) {
            ObjA a = null;
            ObjB b = null;
            // 如果小于listA的个数
            if(i < listA.size()) {
                a = listA.get(i);
            }
            // 如果小于listB的个数
            if(i < listB.size()) {
                b = listB.get(i);
            }
            if(a != null) {
                ObjC c = map.get(a.getEmpNo());
                if( c == null ) {
                    c = new ObjC();
                    map.put(a.getEmpNo(), c);
                } 
                c.setA(a);
            }
            if(b != null) {
                ObjC c = map.get(b.getEmpNo());
                if( c == null ) {
                    c = new ObjC();
                    map.put(b.getEmpNo(), c);
                } 
                c.setB(b);
            }
        }
        Long eTime = System.currentTimeMillis();
        System.out.println((eTime - sTime)+"ms");
        // empNo:no888, name:no888, infos:
        System.out.println(map.get("no888"));
        // empNo:no8888, name:no8888, infos:infos8888
        System.out.println(map.get("no8888"));
        // empNo:no106665, name:, infos:infos106665
        System.out.println(map.get("no106665"));
        // 106666
        System.out.println(map.values().size());
    }
}
class ObjC {
    private ObjA a;
    private ObjB b;
    
    public ObjA getA() {
        return a;
    }
    public void setA(ObjA a) {
        this.a = a;
    }
    public ObjB getB() {
        return b;
    }
    public void setB(ObjB b) {
        this.b = b;
    }
    @Override
    public String toString() {
        String empNo = a == null ? b.getEmpNo() : a.getEmpNo();
        String name = a == null ? "" : a.getEmpNo();
        String infos = b == null ? "" : b.getInfos();
        return "empNo:"+empNo+", name:"+name+", infos:"+infos;
    }
}

class ObjA{
    private String empNo;
    private String name;
    
    public ObjA(String empNo, String name){
        this.empNo = empNo;
        this.name = name;
    }
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

class ObjB{
    private String empNo;
    private String infos;
    
    public ObjB(String empNo, String infos){
        this.empNo = empNo;
        this.infos = infos;
    }
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public String getInfos() {
        return infos;
    }
    public void setInfos(String infos) {
        this.infos = infos;
    }
}
阿神

@机智的熊大 ,@martinwangjun 的解答思路应该是符合你的需求的,我根据他的代码修改了另外一套解决方案,使用纯list的方式,具体代码如下:

import java.util.ArrayList;
import java.util.List;

public class ListMergeTest_1 {

    public static void main(String[] args) {
        List<ClassA> listA = new ArrayList<>();
        List<ClassB> listB = new ArrayList<>();
        List<ClassC> listC = new ArrayList<>();
        
        listA.add(new ClassA("001", "Alex"));
        listA.add(new ClassA("002", "Bill"));
        listA.add(new ClassA("003", "Carl"));
        
        listB.add(new ClassB("001", 1000));
        listB.add(new ClassB("002", 2000));
        listB.add(new ClassB("004", 4000));
        
        for(ClassA a: listA){
            String empNo = a.getEmpNo();
            ClassC c = new ClassC();
            c.setEmpNo(a.getEmpNo());
            c.setName(a.getName());
            for(ClassB b: listB){
                if(b.getEmpNo().equals(empNo)){
                   c.setMoney(b.getMoney());
                }
            }
            listC.add(c);
        }
        
        System.out.println(listC);
    }
}

class ClassA{
    private String empNo;
    private String name;
    
    public ClassA(String empNo, String name){
        this.empNo = empNo;
        this.name = name;
    }
    
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

class ClassB{
    private String empNo;
    private int money;
    
    public ClassB(String empNo, int money){
        this.empNo = empNo;
        this.money = money;
    }
    
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }
    
}

class ClassC{
    private String empNo;
    private String name;
    private int money;
    
//    public ClassC(String empNo, String name, int money){
//        this.empNo = empNo;
//        this.name = name;
//        this.money = money;
//    }
    
    public String getEmpNo() {
        return empNo;
    }
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "(" + empNo + ", " + name + ", " + money + ")";
    }
}
天蓬老师

恕我愚钝,没看明白题目。。。。

巴扎黑

假定objA#empNo是String

Map<String, Object> map = new HashMap<String, Object>();
for (objA a: list_a) {
  map.put(a.empNo, a);
}
for (objB b: list_b) {
  map.put(b.empNo, b);
}
return map.values();
PHPz

我提供个思路,你把listB改成Map对象,key用empNo,而且你要做合并模拟left join肯定还需要第三个对象C存A B合并后的数据,这样你遍历listA时用a.empNo去mapB取,取到了就合并,并加到listC里,没取到继续遍历,最后如果你有需要用list的地方可以用Map.values()生成

这是属于用空间换时间的办法,免得你每次遍历listA时还要遍历一遍listB,但是内存占用会非常大,因为多存了个keySet

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号