英文:
How to correct the below code to get output as expected?
问题
public class Main {
public static void main(String[] args) {
Data object= new Data();
object.setQuantity(5);
object.setDate("05/06/2020");
object.setMaterial("96111");
Data object1= new Data();
object1.setQuantity(2);
object1.setDate("05/06/2020");
object1.setMaterial("96111");
Data object2= new Data();
object2.setQuantity(3);
object2.setDate("05/06/2020");
object2.setMaterial("96111");
Data object3= new Data();
object3.setQuantity(3);
object3.setDate("05/06/2020");
object3.setMaterial("96112");
Data object4= new Data();
object4.setQuantity(9);
object4.setDate("05/07/2020");
object4.setMaterial("96113");
ArrayList<Data> list= new ArrayList<Data>();
list.add(object);
list.add(object1);
list.add(object2);
list.add(object3);
list.add(object4);
HashMap<String, Data> map = new HashMap<>();
for(Data obj : list) {
if (map.containsKey(obj.getDate())) {
map.put(obj.getDate(), new Data(map.get(obj.getDate()).getQuantity() + obj.getQuantity(), obj.getDate(), obj.getMaterial()));
} else {
map.put(obj.getDate(), obj);
}
}
System.out.println(map);
}
}
根据日期和物料,应该添加数量。输出应该如下所示:
05/07/2020=(material:96113 date:05/07/2020 quantity:9), 05/06/2020=(material:96112 date:05/06/2020 quantity:3), 05/06/2020=(material:96111 date: 05/06/2020 quantity:10}
但我得到的输出是:
05/07/2020=(material:96113 date:05/07/2020 quantity:9), 05/06/2020=(material:96112 date:05/06/2020 quantity:13)}
英文:
public class Main {
public static void main(String[] args) {
Data object= new Data();
object.setQuantity(5);
object.setDate("05/06/2020");
object.setMaterial("96111");
Data object1= new Data();
object1.setQuantity(2);
object1.setDate("05/06/2020");
object1.setMaterial("96111");
Data object2= new Data();
object2.setQuantity(3);
object2.setDate("05/06/2020");
object2.setMaterial("96111");
Data object3= new Data();
object3.setQuantity(3);
object3.setDate("05/06/2020");
object3.setMaterial("96112");
Data object4= new Data();
object4.setQuantity(9);
object4.setDate("05/07/2020");
object4.setMaterial("96113");
ArrayList<Data> list= new ArrayList<Data>();
list.add(object);
list.add(object1);
list.add(object2);
list.add(object3);
list.add(object4);
HashMap<String, Data> map = new HashMap<>();
for(Data obj : list) {
if (map.containsKey(obj.getDate())) {
map.put(obj.getDate(),new Data(map.get(obj.getDate()).getQuantity() + (obj.getQuantity()), obj.getDate(), obj.getMaterial()));
} else {
map.put(obj.getDate(),obj);
}
}
System.out.println(map);
}
}
Based on date and material , quantity should be added.
Output should come as shown in below:
05/07/2020=(material:96113 date:05/07/2020 quantity:9), 05/06/2020=(material:96112 date:05/06/2020 quantity:3), 05/06/2020=(material:96111 date: 05/06/2020 quantity:10}
But I am getting output as:
05/07/2020=(material:96113 date:05/07/2020 quantity:9), 05/06/2020=(material:96112 date:05/06/2020 quantity:13)}
答案1
得分: 1
根据您提供的内容,您可以拥有一个按date
和material
分组的Map
,其中每个date
对应一个包含多个material
的子Map
,由于只剩下一个值,即数量(其他值已由Map
中的键提供),您可以使用以下格式:
// Date Material Quantity
// | | |
// V V V
Map<String, Map<String, Integer>> map = new HashMap<>();
然后,您的for循环可以转换为以下形式:
```java
for (Data data : list) {
map.computeIfAbsent(data.getDate(), i -> new HashMap<>())
.merge(data.getMaterial(), data.getQuantity(), Integer::sum);
}
然后打印结果可能类似于:
{05/07/2020={96113=9}, 05/06/2020={96111=10, 96112=3}}
生成的map
随后可以轻松转换回List<Data>
:
List<Data> result = new ArrayList<>();
for (Map.Entry<String, Map<String, Integer>> entries : map.entrySet()) {
for (Map.Entry<String, Integer> entry : entries.getValue().entrySet()) {
result.add(new Data(entry.getValue(), entries.getKey(), entry.getKey()));
}
}
在打印时,结果类似于:
[(material=96113, date=05/07/2020, quantity=9), (material=96111, date=05/06/2020, quantity=10), (material=96112, date=05/06/2020, quantity=3)]
英文:
From what you've provided you can have a Map
of Map
s, grouped by date
and then by material
, and as you've only 1 value left, the quanity (the other values are already provided by the key in the Map
) you can use this format:
// Date Material Quantity
// | | |
// V V V
Map<String, Map<String, Integer>> map = new HashMap<>();
Then your for-loop can be converted to this:
for (Data data : list) {
map.computeIfAbsent(data.getDate(), i -> new HashMap<>())
.merge(data.getMaterial(), data.getQuantity(), Integer::sum);
}
Which then prints something like this:
{05/07/2020={96113=9}, 05/06/2020={96111=10, 96112=3}}
The resulting map can then easily be converted back into a List<Data>
:
List<Data> result = new ArrayList<>();
for (Map.Entry<String, Map<String, Integer>> entries : map.entrySet()) {
for (Map.Entry<String, Integer> entry : entries.getValue().entrySet()) {
result.add(new Data(entry.getValue(), entries.getKey(), entry.getKey()));
}
}
When printed, results into something like this:
[(material=96113, date=05/07/2020, quantity=9), (material=96111, date=05/06/2020, quantity=10), (material=96112, date=05/06/2020, quantity=3)]
答案2
得分: 0
你可以使用流式 API 来解决这个问题。使用 Collectors.toMap
,按照日期和材料进行映射。合并数量并进行收集。然后将映射的值集合转换成列表。
List<Data> res = new ArrayList<>(list.stream()
.collect(Collectors.toMap(
e -> new SimpleEntry<String, String>(e.getDate(), e.getMaterial()), e -> e,
(a, b) -> new Data(a.getQuantity() + b.getQuantity(), a.getDate(), a.getMaterial())))
.values());
你可以在这里在线测试代码。
英文:
You can use stream API to solve this. Using Collectors.toMap
map by Date and Materials. Merge the quantity and collect. Then get the map values set in list.
List<Data> res = new ArrayList<>(list.stream()
.collect(Collectors.toMap(
e -> new SimpleEntry<String, String>(e.getDate(), e.getMaterial()), e -> e,
(a, b) -> new Data(a.getQuantity() + b.getQuantity(), a.getDate(), a.getMaterial())))
.values());
You can test code online here
答案3
得分: -2
根据我所理解的,我认为这就是你所询问的内容:
for(Data obj : list) {
if (map.containsKey(obj.getDate())) { // 如果存在该键
if(map.get(obj.getDate()).getMaterial() == obj.getMaterial()){ // 并且如果材料也相同
map.put(obj.getDate(),new Data(map.get(obj.getDate()).getQuantity() + (obj.getQuantity()), obj.getDate(), obj.getMaterial())); // 更新该项
}
else{
map.put(obj.getDate(),obj); // 如果材料不相同
}
}
else {
map.put(obj.getDate(),obj); // 如果键不存在,添加新项
}
}
它首先查找日期,如果日期存在,然后再查找材料,如果材料也相同,则更新对象...在其他情况下,添加新项目。
注意:这基本上是正确的答案,但不是绝对正确,因为这段代码无法区分相同日期和不同材料之间的差异。
唯一完美的解决方案是使用嵌套的键/值对。
希望能对你有所帮助
英文:
Based on what I have understood, I think this is what you are asking for :
for(Data obj : list) {
if (map.containsKey(obj.getDate())) { // If that key exists
if(map.get(obj.getDate()).getMaterial() == obj.getMaterial()){ // and if the material is also same
map.put(obj.getDate(),new Data(map.get(obj.getDate()).getQuantity() + (obj.getQuantity()), obj.getDate(), obj.getMaterial())); // update the item
}
else{
map.put(obj.getDate(),obj); // if material is not same
}
}
else {
map.put(obj.getDate(),obj); // if key don't exists, add a new item
}
}
It first looks for the date, if date is exists, then it look for the material, and if the material is also the same, the the object is updated....In other cases, a new item is added.
NOTE : This is slightly the right answer but not absolutely right, as this code won't be able to differentiate between the same date and different materials.
The only perfect solution would be to use nested key/value pairs.
Hope it helps
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论