将List <product>转换为Map <integer,list <product =“”>&gt; </integer,> </product>

时间:2013-12-19 13:25:54

标签: java list collections map

你可以向我假设最好或更优雅的方式,转换 List<Product>按产品编号分组的Map<Integer, List<Product>>个产品的所有产品。

例如我的产品POJO。

public class Product{
.. 
private Integer productCode;
private String productName;
...
//getters, setters
}

这是我的尝试,但我认为它不那么优雅:

public Map<Integer, List<Product>> getProductsByIndex (List<Product> products){
        Map<Integer, List<Product>> resultMap = new HashMap<>();
        Set<Integer> productCodes = getProductCodes(products);

        for(Integer productCode: productCodes){
            List<Product> productsByCode = new ArrayList<>();
            for(Product product : products){
                if(productCode == product.getCode()){
                    productsByCode.add(product);    
                }
            }
            resultMap.put(productCode, productsByCode);
        }
        return resultMap;
    }

    public Set<Integer> getProductCodes (List<Product> products){
        Set<Integer> productCodes = new HashSet<>();
        for(Product product: products){
            productCodes.add(product.getCode());
        }
        return productCodes;
    }

6 个答案:

答案 0 :(得分:6)

Java 8解决方案:

Map<Integer, List<Product>> productsByCode  = products.stream()
                    .collect(Collectors.groupingBy(Product::getProductCode));

答案 1 :(得分:4)

for (Product p: products) {
    List<Product> l = productsByCode.get(p.getCode());
    if (l == null) {
       l = new ArrayList<>();
       productsByCode.put(p.getCode(), l);
    }
    l.add(p);
}

这就是你所需要的:)

答案 2 :(得分:1)

您的解决方案不是线性的,而且对于大量数据而言太慢。只需使用简单的方法:

public Map<Integer, List<Product>> getProductsByIndex (List<Product> products){
    Map<Integer, List<Product>> resultMap = new HashMap<>();

    for(Product product: products){
        List<Product> productsByCode = resultMap.get(product.getCode());
        if (productsByCode == null) {
           productByCode = new ArrayList();
           resultMap.put(product.getCode(), productByCode);
        }
        productsByCode.add(product);    
    }
    return resultMap;
}

答案 3 :(得分:1)

如果您使用的是Eclipse Collections,则可以将产品转换为ListIterable并使用groupBy()方法。

ListMultimap<Integer, Product> productsByCode =
    products.groupBy(Product::getProductCode);

Multimap<Integer, Product>在概念上与Map<Integer, List<Product>>类似,但它针对此用例进行了优化。您仍然可以致电get()以获取具有特定代码的产品。

ListIterable<Product> productsWithCode = productsByCode.get(someProductCode);

但是使用Multimap,您不必担心null。当产品代码不存在时,get()将返回空集合,而不是null。 Multimap也有containsKeyAndValue()等方便的方法。

boolean b = productsByCode.containsKeyAndValue(someProductCode, product);

如果您无法将产品从List转换为ListIterable,则可以使用ListAdapter获取相同的API。

ListMultimap<Integer, Product> productsByCode =
    ListAdapter.adapt(products).groupBy(Product::getProductCode);

对于Java 8之前的Java版本,方法引用变为匿名Function

ListMultimap<Integer, Product> productsByCode =
    products.groupBy(new Function<Product, Integer>()
    {
        @Override
        public Integer valueOf(Product product)
        {
            return product.getProductCode();
        }
    });

注意:我是Eclipse集合的提交者。

答案 4 :(得分:0)

我会这样做:

Map<Integer, List<Product>> resultMap = new HashMap<>();
for (Product product : products) {
    List<Product> productList = resultMap.get(product.getCode());
    if (productList == null) {
        productList = new ArrayList<>();
        resultMap.put(product.getCode(), productList);
    }
    productList.add(product);
}

答案 5 :(得分:0)

public Map<Integer, List<Product>> getProductsByIndex (List<Product> products){
    Map<Integer, List<Product>> resultMap = new HashMap<>();

    for(Product product : products) {
        if(!resultMap.containsKey(product.getProductCode()) {
            resultMap.put(product.getProductCode(), new ArrayList<Product>();
        }

        resultMap.get(product.getProductCode()).add(product);
    }

    return resultMap;

}