[英]What would be a cleaner way to transfer data from a form object to an entity for an update method?
[英]What would be a cleaner way to cluster ArrayList() based on one column data?
假设我有以下列表
full_list
ID NAME
1 Apple
1 Banana
2 Carrot
1 Mango
2 Spinach
3 BMW
3 Opal
有了这个单一列表,我想创建一个基于列ID
的分组列表,如下所示
fruits_list veggies_list cars_list
ID NAME ID NAME ID NAME
1 Apple 2 Carrot 3 BMW
1 Banana 2 Spinach 3 Opal
1 Mango
我试图用Arraylist<ArrayList<CustomObject>>
。 但它增加了代码的复杂性。 我做错了吗? 有没有更清洁的方法来做到这一点?
PS:数据传入不固定。 我不能用条件明确定义列表(即 if(id==1)、if(id==2) 等)。 这应根据输入数据动态完成。
正如您所说,如果您使用列表执行此操作,则会更加复杂。 这个逻辑可以通过使用 Map 和 List 来简化。 使用 Map 实现此目的的示例代码和列表如下
Map<Integer, List<String>> myMap = new LinkedHashMap<Integer, List<String>>();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/stackoverflow?useSSL=false",
"root", "password");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from `58144029`");
while (rs.next()) {
List<String> myList = myMap.get(rs.getInt("id")) == null ? new LinkedList<String>()
: myMap.get(rs.getInt("id"));
myList.add(rs.getString("name"));
myMap.put(rs.getInt("id"), myList);
}
con.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(myMap);
// Getting the List as per id
System.out.println(myMap.get(1));
在上面的代码中,我在数据库中创建了与您相同的表。 并且数据现在被动态添加到 map 中。 无论您在数据库中拥有什么 id 都将成为 map 的键,并且针对该 id 的值将成为值列表。 密钥可以是任何 integer,您可以将其进一步 map 到特定列表。
查询创建表和插入数据如下
CREATE TABLE `58144029` (
`id` int(11) NOT NULL,
`name` varchar(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `58144029` (`id`, `name`) VALUES
(1, 'Apple'),
(1, 'Banana'),
(2, 'Carrot'),
(1, 'Mango'),
(2, 'Spinach'),
(3, 'BMW'),
(3, 'Opal');
您需要使用Map
,它将 ID 作为其键,并将值作为 object 的List
。 假设您有以下 class:
class Item {
private int id;
private String name;
public Item(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() { return this.id; }
}
您的结果应该是Map<Integer, List<Item>>
类型。 实现此目的的一种方法是使用Collectors.groupingBy
。 例如:
list.stream().collect(Collectors.groupingBy(Item::getId));
这将创建一个 map,它按Item
class 的id
属性分组。
另一个快速解决方案
var arList = [{1:'Apple'}, {1:'Banana'}, {2:'Carrot'}, {1:'Mango'}, {2:'Spinach'}, {3:'BMW'}, {3:'Opal'}]
var sorted =[];
arList.map(function (value, i) {
Object.keys(value).forEach(function(key, index) {
if(typeof sorted[key]==='undefined'){
sorted[key] = [value[key]];
}else{
sorted[key].push(value[key]);
}
});
})
sorted = sorted.filter(entry => /\S/.test(entry));
console.log(sorted);
谢谢大家的回答。 正如@Mauron 建议的那样,我使用了Collectors.groupingby
,它实际上节省了 20 行排序代码。 经过一番研究,我发现如何在这里列出 map 中的所有键
所以这是我正在寻找的解决方案
//Create a grouped map using Collectors.groupingBy
Map m = itemslist.stream().collect(Collectors.groupingBy(ShipmentItemsModel::getLrid));
//Make an ArrayList of keys
ArrayList<Integer> keys = new ArrayList<>(m.keySet());
//Use enhanced for loop (foreach) to go through each key in order to create list of items each key has.
//(In Layman terms: It will create small lists based on keys)
for (int singlekey: keys) {
ArrayList<ShipmentItemsModel> values = new ArrayList<ShipmentItemsModel>();
values = (ArrayList<ShipmentItemsModel>) m.get(singlekey);
for (ShipmentItemsModel sortedmodel: values) {
System.out.println("Key/ID :"+singlekey+" and values :"+sortedmodel.getProductname());
}
}
所以最终的 output 会是这样的
Key/ID :1 and value :Apple
Key/ID :1 and value :Banana
Key/ID :1 and value :Mango
Key/ID :2 and value :Carrot
Key/ID :2 and value :Spinach
Key/ID :3 and value :BMW
Key/ID :3 and value :Opal
我很感激所有的答案。 再次感谢大家。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.