重构HashMap的最快方法

时间:2011-03-17 04:33:04

标签: java

我有一个HashMap,可以将公司映射到他们销售的产品的ArrayList,如下所示:

thiscompany --> [productA, productB...]
thatcompany --> [productC, productA...]

因此,在给定特定公司的情况下生成产品列表非常容易。请注意,多家公司可能会销售相同的产品。问题是,鉴于特定产品,我还需要找到所有销售它的公司。很快。这种查找可能会发生一次或多次。我想知道提供此功能的最有效方法。

目前,我正在通过迭代每个ArrayList并将每个产品映射到其供应商来生成新的数据结构。这很昂贵,因为我必须检查我正在创建的HashMap是否每次添加之前都包含该产品作为键,而且它需要我获取每个ArrayList,添加新的供应商,删除旧的ArrayList然后映射每个条目的新的。我根本无法看到更快的方式,也许有人可以提供一些见解?

4 个答案:

答案 0 :(得分:2)

如何将ArrayList更改为HashSet。

List<String> findCompanies(Map<String,Set<String>> companyToProducts, String product) {
    List<String> companies = new ArrayList<String>();
    for (Map.Entry<String,Set<String>> entry : companyToProducts) {
        Set<String> products = entry.getValue();
        if (products.contains(product)) {
            companies.add(entry.getKey());
        }
    }
    return companies;
}

另一种常见的方法是在数据库中使用一个表,其中包含产品列和公司列,然后执行以下操作:

select distinct company from companyToProduct where product = 'cheese';

答案 1 :(得分:1)

为什么不在为公司制作产品地图的同时创建销售产品的公司地图

Map<Product, Set<Company>> companiesByProduct
Map<Company, Set<Product>> productsByCompany

public void add(Company company, Product product) {
    Set<Company> companies = companiesByProduct.get(product);
    if (companies==null) {
        companies = new HashSet<Company>();
        companiesByProduct.put(product, companies);
    }
    companies.add(company);

    // do the same for 
    Set<Product> products = productsByCompany.get(product);
    ....

或者从您可以使用的服务器收到的地图中创建新的公司产品地图(您可能需要根据原始地图的确切类型进行调整):

for (Company company : originalMap.keySet()) {
  for (Product product : originalMap.get(company)) {
    Set<Company> companies = companiesByProduct.get(product);
    if (companies==null) {
        companies = new HashSet<Company>();
        companiesByProduct.put(product, companies);
    }
    companies.add(company);
   }
}

答案 2 :(得分:1)

尝试MultiMaps.invertFrom

示例:

    Multimap<String, Integer> map = HashMultimap.create();
    map.put("a", 3);
    map.put("a", 4);
    map.put("a", 5);
    map.put("b", 5);
    map.put("b", 3);
    map.put("b", 6);
    Multimap<Integer,String> mapInverse=HashMultimap.create();
    Multimaps.invertFrom(map, mapInverse);
    System.out.println(mapInverse);

<强>输出:

{3=[b, a], 4=[a], 5=[b, a], 6=[b]}

替代解决方案:

在这里,我正在创建一个2D布尔数组,代表公司及其产品,以便于查找。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultimap;

public class ProductCompanyMap {
    private Multimap<String, String> companyProducts = TreeMultimap.create();
    private boolean[][] ProductCompanyTable;
    private Map<String,Integer> productIndexMap = new HashMap<String, Integer>();;
    private Map<String,Integer> companyIndexMap = new HashMap<String, Integer>();
    private String[] productArray;
    private String[] companyArray;;


    {
        companyProducts.put("Britania","Biscuts");
        companyProducts.put("Britania","Soap");
        companyProducts.put("Britania","Cloths");
        companyProducts.put("MicroSoft","Software");
        companyProducts.put("Birla","Cloths");
        companyProducts.put("Birla","Software");
    }
    public ProductCompanyMap(){

        Set<String> companyNames=companyProducts.keySet();
        Set<String> productNames= Sets.newTreeSet(companyProducts.values());
        companyArray = companyNames.toArray(new String[companyNames.size()]);
        createIndexMap(companyIndexMap, companyArray);
        productArray = productNames.toArray(new String[productNames.size()]);
        createIndexMap(productIndexMap,productArray);

        ProductCompanyTable = new boolean[companyArray.length][productArray.length];
        for(int i=0;i<companyArray.length;i++)
            for(int j=0;j<productArray.length;j++){
                if(companyProducts.containsEntry(companyArray[i],productArray[j]))
                    ProductCompanyTable[i][j] = true;
            }

    }

    private void createIndexMap(Map<String,Integer> map,String[] arr){
        for(int i=0;i<arr.length;i++)
            map.put(arr[i], i);
    }

    public List<String> getProductsOfCompany(String companyName){
        List<String> productsOfCompany = new ArrayList<String>();
        Integer companyIndex = null;
        if((companyIndex=companyIndexMap.get(companyName))!=null)
        {
            for(int i=0;i<ProductCompanyTable[companyIndex].length;i++)
                if(ProductCompanyTable[companyIndex][i])
                    productsOfCompany.add(productArray[i]);
        }
        return productsOfCompany;
    }
    public List<String> getCompanysWithProduct(String productName){
        List<String> companysWithProduct = new ArrayList<String>();
        Integer productIndex = null;
        if((productIndex=productIndexMap.get(productName))!=null)
        {
            for(int i=0;i<ProductCompanyTable.length;i++)
                if(ProductCompanyTable[i][productIndex])
                    companysWithProduct.add(companyArray[i]);
        }
        return companysWithProduct;
    }
    public static void main(String[] args) {
        ProductCompanyMap mm=new ProductCompanyMap();
        System.out.println("Products of Birla : " +mm.getProductsOfCompany("Birla"));
        System.out.println("Company's producing cloths : "+mm.getCompanysWithProduct("Cloths"));
    }
}

答案 3 :(得分:0)

维护两个数据结构 - 您现在维护的HashMap和另一个将产品映射到公司的数据结构:

productA --> [thiscompany, thatcompany...]
productC --> [thatcompany, othercompany...]