在Java中对列表中的项目进行分组

在Java中对列表中的项目进行分组,java,list,java-8,grouping,Java,List,Java 8,Grouping,我有一个对象列表list mList=new ArrayList() 销售模式为: public class Sales { private int product1; private int product2; } public class Shifts { private int shift1; private int shift2; } 这种转变模式是: public class Sales { private int product1;

我有一个对象列表
list mList=new ArrayList()

销售模式为:

public class Sales {
    private int product1;
    private int product2;
}
public class Shifts {
    private int shift1;
    private int shift2;
}
这种转变模式是:

public class Sales {
    private int product1;
    private int product2;
}
public class Shifts {
    private int shift1;
    private int shift2;
}
如何在
列表mList
中按名称对项目进行分组,然后对相应的销售额和班次求和?那么,如果列表中有两个项目的名称相同,那么将它们分组,并计算其销售额和班次

我尝试过stream,但没有成功:

List<WorkingActivityModel> result = mList.stream()
                        .collect(groupingBy(WorkingActivityModel::getName, LinkedHashMap::new, toList()))
                        .values().stream()
                        .flatMap(Collection::stream)
                        .collect(toList());
List result=mList.stream()
.collect(groupingBy(WorkingActivityModel::getName,LinkedHashMap::new,toList())
.values().stream()
.flatMap(集合::流)
.collect(toList());
另一个选择是:

List<WorkingActivity> mList = new ArrayList<>();

HashMap<String, List<WorkingActivityModel>> map = new HashMap<>();

for(WorkingActivityModel o : mList){
    if (!map.containsKey(o.getKey())) {
        List<WorkingActivityModel> list = new ArrayList<>();
        list.add(o);

        map.put(o.getKey(), list);
    } else {
        map.get(o.getKey()).add(o);
    }
}
List mList=new ArrayList();
HashMap=newHashMap();
用于(工作活动模式o:mList){
如果(!map.containsKey(o.getKey())){
列表=新的ArrayList();
列表。添加(o);
put(o.getKey(),list);
}否则{
get(o.getKey()).add(o);
}
}
在这种情况下,我不知道如何计算相应的销售额和班次

编辑

以下是预期结果的示例:


您可以使用自定义合并操作来完成此操作,该操作的定义使得执行
toMap
变得稍微容易一些

Collection<WorkingActivityModel> result = mList.stream()
        .collect(Collectors.toMap(WorkingActivityModel::getName, Function.identity(),
                (a, b) -> WorkingActivityModel.mergeModels(a, b))) // WorkingActivityModel::mergeModels
        .values();

当然,
mergeSales
mergeShifts
遵循相同的模式,实现起来非常简单。

您可以使用自定义的合并操作来实现这一点,这样执行
toMap
会稍微容易一些

Collection<WorkingActivityModel> result = mList.stream()
        .collect(Collectors.toMap(WorkingActivityModel::getName, Function.identity(),
                (a, b) -> WorkingActivityModel.mergeModels(a, b))) // WorkingActivityModel::mergeModels
        .values();
当然,
mergeSales
mergeShifts
遵循相同的模式,实现起来很简单。

您可以这样做:

 mList.stream()
            .collect(Collectors.toMap(WorkingActivityModel::getName,Function.identity(),
                  (o, o2) -> {
                       o.getSales().sum(o2.getSales());
                       o.getShifts().sum(o2.getShifts());
                       return o;
                   })
           )
           .values()
以及:

您可以这样做:

 mList.stream()
            .collect(Collectors.toMap(WorkingActivityModel::getName,Function.identity(),
                  (o, o2) -> {
                       o.getSales().sum(o2.getSales());
                       o.getShifts().sum(o2.getShifts());
                       return o;
                   })
           )
           .values()
以及:


您还可以在自定义数据结构中直接作为添加的项_求和

import java.util.HashMap;

public class MyHash extends HashMap<String, WorkingActivityModel>
{

    @Override
    public WorkingActivityModel put(String key, WorkingActivityModel value)
    {
        if(this.containsKey(key))
        {
            WorkingActivityModel w = this.get(key);
            value.getSales().setProduct1(w.getSales().getProduct1() + value.getSales().getProduct1());
            value.getSales().setProduct2(w.getSales().getProduct2() + value.getSales().getProduct2());
        //  ... same 
        //  value.getShifts().setShift1(w.getShifts().getShift1() + value.getShifts().getShift1());
        //  value.getShifts().setShift1(w.getShifts().getShift2() + value.getShifts().getShift2());
            super.put(key, value);
        }
        else
        {
            super.put(key, value);
        }
        return value;
    }
    
    public String toString()
    {
        StringBuffer sb = new StringBuffer();
        this.forEach((k,v) -> sb.append(k+",sale_p1="+v.getSales().getProduct1()+",sale_p2="+v.getSales().getProduct2()+"\n"));
        return sb.toString();
    }
    
    public static void main(String args[])
    {
        Sales s1 = new Sales();
        s1.setProduct1(1);
        Sales s2 = new Sales();
        s2.setProduct1(2);
        s2.setProduct2(3);
        MyHash mh = new MyHash();
        
        WorkingActivityModel wam = new WorkingActivityModel();
        wam.setSales(s1);
        wam.setName("n1");
        mh.put(wam.getName(), wam);
        System.out.println(mh);
        
        WorkingActivityModel wam2 = new WorkingActivityModel();
        wam2.setSales(s2);
        wam2.setName("n1");
        mh.put(wam2.getName(), wam2);
        
        System.out.println(mh);
    }
}
输出

n1,sale_p1=1,sale_p2=0
n1,sale_p1=3,sale_p2=3

您还可以在自定义数据结构中直接作为添加的项_求和

import java.util.HashMap;

public class MyHash extends HashMap<String, WorkingActivityModel>
{

    @Override
    public WorkingActivityModel put(String key, WorkingActivityModel value)
    {
        if(this.containsKey(key))
        {
            WorkingActivityModel w = this.get(key);
            value.getSales().setProduct1(w.getSales().getProduct1() + value.getSales().getProduct1());
            value.getSales().setProduct2(w.getSales().getProduct2() + value.getSales().getProduct2());
        //  ... same 
        //  value.getShifts().setShift1(w.getShifts().getShift1() + value.getShifts().getShift1());
        //  value.getShifts().setShift1(w.getShifts().getShift2() + value.getShifts().getShift2());
            super.put(key, value);
        }
        else
        {
            super.put(key, value);
        }
        return value;
    }
    
    public String toString()
    {
        StringBuffer sb = new StringBuffer();
        this.forEach((k,v) -> sb.append(k+",sale_p1="+v.getSales().getProduct1()+",sale_p2="+v.getSales().getProduct2()+"\n"));
        return sb.toString();
    }
    
    public static void main(String args[])
    {
        Sales s1 = new Sales();
        s1.setProduct1(1);
        Sales s2 = new Sales();
        s2.setProduct1(2);
        s2.setProduct2(3);
        MyHash mh = new MyHash();
        
        WorkingActivityModel wam = new WorkingActivityModel();
        wam.setSales(s1);
        wam.setName("n1");
        mh.put(wam.getName(), wam);
        System.out.println(mh);
        
        WorkingActivityModel wam2 = new WorkingActivityModel();
        wam2.setSales(s2);
        wam2.setName("n1");
        mh.put(wam2.getName(), wam2);
        
        System.out.println(mh);
    }
}
输出

n1,sale_p1=1,sale_p2=0
n1,sale_p1=3,sale_p2=3

如果我对你的问题理解正确,这可能会有所帮助-

List<WorkingActivityModel> mList = generateList(6);

Map<String, WorkingActivityModel> map = mList.stream()
            .collect(groupingBy(WorkingActivityModel::getName))
            .entrySet().stream()
            .collect(Collectors.toMap(entry ->entry.getKey(),
                    entry -> {
                WorkingActivityModel wam = new WorkingActivityModel();
                wam.shifts = new Shifts();
                wam.shifts.shift1 = entry.getValue()
                        .stream()
                        .map(v -> v.shifts.shift1)
                        .reduce(0, Integer::sum);;
                wam.shifts.shift2 = entry.getValue()
                        .stream()
                        .map(v -> v.shifts.shift2)
                        .reduce(0, Integer::sum);
                wam.sales = new Sales();
                wam.sales.product1 = entry.getValue()
                        .stream()
                        .map(v -> v.sales.product1)
                        .reduce(0, Integer::sum);
                wam.sales.product2 = entry.getValue()
                        .stream()
                        .map(v -> v.sales.product2)
                        .reduce(0, Integer::sum);
                return wam;
            }));
List mList=generateList(6);
Map Map=mList.stream()
.collect(分组依据(WorkingActivityModel::getName))
.entrySet().stream()
.collect(Collectors.toMap(entry->entry.getKey(),
条目->{
WorkingActivityModel wam=新的WorkingActivityModel();
wam.shifts=新班次();
wam.shifts.shift1=entry.getValue()
.stream()
.map(v->v.shifts.shift1)
.reduce(0,整数::和);;
wam.shifts.shift2=entry.getValue()
.stream()
.map(v->v.shifts.shift2)
.reduce(0,整数::和);
wam.sales=新销售额();
wam.sales.product1=entry.getValue()
.stream()
.map(v->v.sales.product1)
.reduce(0,整数::和);
wam.sales.product2=entry.getValue()
.stream()
.map(v->v.sales.product2)
.reduce(0,整数::和);
返回wam;
}));
地图将按名称对工作活动进行分组。
关键是名称,值是一个WorkingActivityModel对象,包含班次和产品的总和。

如果我对您的问题理解正确,这可能会有所帮助-

List<WorkingActivityModel> mList = generateList(6);

Map<String, WorkingActivityModel> map = mList.stream()
            .collect(groupingBy(WorkingActivityModel::getName))
            .entrySet().stream()
            .collect(Collectors.toMap(entry ->entry.getKey(),
                    entry -> {
                WorkingActivityModel wam = new WorkingActivityModel();
                wam.shifts = new Shifts();
                wam.shifts.shift1 = entry.getValue()
                        .stream()
                        .map(v -> v.shifts.shift1)
                        .reduce(0, Integer::sum);;
                wam.shifts.shift2 = entry.getValue()
                        .stream()
                        .map(v -> v.shifts.shift2)
                        .reduce(0, Integer::sum);
                wam.sales = new Sales();
                wam.sales.product1 = entry.getValue()
                        .stream()
                        .map(v -> v.sales.product1)
                        .reduce(0, Integer::sum);
                wam.sales.product2 = entry.getValue()
                        .stream()
                        .map(v -> v.sales.product2)
                        .reduce(0, Integer::sum);
                return wam;
            }));
List mList=generateList(6);
Map Map=mList.stream()
.collect(分组依据(WorkingActivityModel::getName))
.entrySet().stream()
.collect(Collectors.toMap(entry->entry.getKey(),
条目->{
WorkingActivityModel wam=新的WorkingActivityModel();
wam.shifts=新班次();
wam.shifts.shift1=entry.getValue()
.stream()
.map(v->v.shifts.shift1)
.reduce(0,整数::和);;
wam.shifts.shift2=entry.getValue()
.stream()
.map(v->v.shifts.shift2)
.reduce(0,整数::和);
wam.sales=新销售额();
wam.sales.product1=entry.getValue()
.stream()
.map(v->v.sales.product1)
.reduce(0,整数::和);
wam.sales.product2=entry.getValue()
.stream()
.map(v->v.sales.product2)
.reduce(0,整数::和);
返回wam;
}));
地图将按名称对工作活动进行分组。
关键是名称,值是带有班次和产品总和的WorkingActivityModel对象。

我有两个问题:1:
List
应该是
List
,对吗?2:你能举个例子吗?你的最终名单会是什么样的。@Ema.jar,我编辑了我的问题,列表是一个数组列表。@tausif我编辑了我的问题,谢谢你的快速回复。我有两个问题:1:
List
应该是
List
,对吗?2:你能举个例子吗?你的最终名单会是什么样的。你能发布吗。@Ema.jar,我编辑了我的问题,列出了它的一个数组列表。@tausif我编辑了我的问题,谢谢你的快速回复。这个解决方案很有效。除此之外,列表没有分组,但是列表中添加了模型的总和,因此该列表包含两个项目,使用此解决方案将添加另一个具有所需结果的项目。但问题是,我只需要有总和的项目。我不知道我是否清楚这个解决方案是否奏效。除此之外,列表没有分组,但是列表中添加了模型的总和,因此该列表包含两个项目,使用此解决方案将添加另一个具有所需结果的项目。但问题是,我只需要有