在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我编辑了我的问题,谢谢你的快速回复。这个解决方案很有效。除此之外,列表没有分组,但是列表中添加了模型的总和,因此该列表包含两个项目,使用此解决方案将添加另一个具有所需结果的项目。但问题是,我只需要有总和的项目。我不知道我是否清楚这个解决方案是否奏效。除此之外,列表没有分组,但是列表中添加了模型的总和,因此该列表包含两个项目,使用此解决方案将添加另一个具有所需结果的项目。但问题是,我只需要有