繁体   English   中英

基于一列数据对 ArrayList() 进行聚类的更简洁的方法是什么?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM