Java 将列表中的项目分组,并将所有其他字段相加,在recyclerview中显示结果
我有一个Firebase数据库,它具有这种结构Java 将列表中的项目分组,并将所有其他字段相加,在recyclerview中显示结果,java,android,android-recyclerview,java-8,java-stream,Java,Android,Android Recyclerview,Java 8,Java Stream,我有一个Firebase数据库,它具有这种结构 { "foo" : { "data" : { "2019-12-01" : [ { "item1" : 8, "item2" : 16, "name" : "user1" }, { "item1" : 9, "item2" : 18, "name" : "user2" } ], "2019-12
{
"foo" : {
"data" : {
"2019-12-01" : [ {
"item1" : 8,
"item2" : 16,
"name" : "user1"
}, {
"item1" : 9,
"item2" : 18,
"name" : "user2"
} ],
"2019-12-02" : [ {
"item1" : 2,
"item2" : 26,
"name" : "user1"
}, {
"item1" : 6,
"item2" : 6,
"name" : "user2"
} ]
}
}
}
我正在以一种非常简单的方式在主要活动中填写一个回收站
:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private Adapter adapter;
final List<Model> tempList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.simpleRecycler);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
Query statsRef = FirebaseDatabase.getInstance()
.getReference("foo")
.child("data")
.orderByKey()
.startAt("2019-12-01")
.endAt("2019-12-02");
// Read from the database
statsRef.addValueEventListener(new ValueEventListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot itemSnapshot : dataSnapshot.getChildren()){
for (int i = 0; i < 2; i++) {
Model model = itemSnapshot.child(String.valueOf(i)).getValue(Model.class);
tempList.add(model);
}
}
adapter = new Adapter(tempList);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
问题是我想按名称对列表进行分组,然后对所有其他相关字段求和,如下所示
+-------+----+----+
| user1 | 10 | 42 |
+-------+----+----+
| user2 | 15 | 24 |
+-------+----+----+
我尝试过,但没有成功:
tempList.stream().collect(Collectors.groupingBy(Model::getName))
.entrySet().stream()
.collect(Collectors.toMap(x -> {
int item1 = x.getValue().stream().mapToInt(Model::getItem1).sum();
int item2 = x.getValue().stream().mapToInt(Model::getItem2).sum();
return new Model(x.getKey(), item1, item2);
}, Map.Entry::getValue));
在将适配器设置为RecycleServiceWewer之前,我已经添加了上面的代码
是否需要帮助?您可以使用定义了
合并功能的收集器.toMap
操作来执行聚合,例如:
List<Model> output = new ArrayList<>(tempList.stream()
.collect(Collectors.toMap(Model::getName, Function.identity(),
Model::mergeSimilarNames))
.values()); // interested in merged output
要将其与现有方法联系起来,您需要在对元素进行分组后进行缩减操作,例如:
Map<String, Optional<Model>> grouping = tempList.stream()
.collect(Collectors.groupingBy(Model::getName,
Collectors.reducing(Model::mergeSimilarNames)));
但请注意
List<Model> output = new ArrayList<>(tempList.stream()
.collect(Collectors.toMap(Model::getName, Function.identity(),
Model::mergeSimilarNames))
.values()); // interested in merged output
static Model mergeSimilarNames(Model one, Model two) {
return new Model(one.getName(), one.getItem1() + two.getItem1(), one.getItem2() + two.getItem2());
}
Map<String, Optional<Model>> grouping = tempList.stream()
.collect(Collectors.groupingBy(Model::getName,
Collectors.reducing(Model::mergeSimilarNames)));
List<Model> output = tempList.stream()
.collect(Collectors.groupingBy(Model::getName,
Collectors.reducing(Model::mergeSimilarNames)))
.values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());