Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重组HashMap的最快方法_Java - Fatal编程技术网

Java 重组HashMap的最快方法

Java 重组HashMap的最快方法,java,Java,我有一个HashMap,它将公司映射到他们销售的产品的ArrayList,如下所示: thiscompany --> [productA, productB...] thatcompany --> [productC, productA...] 因此,为特定公司生成产品列表非常容易。请注意,多家公司可能销售同一产品。问题是,我还需要找到所有销售特定产品的公司。而且很快。这种查找可能发生一次或多次。我想知道提供此功能的最有效方法 目前,我通过迭代每个ArrayList并将每个产品映射

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

thiscompany --> [productA, productB...]
thatcompany --> [productC, productA...]
因此,为特定公司生成产品列表非常容易。请注意,多家公司可能销售同一产品。问题是,我还需要找到所有销售特定产品的公司。而且很快。这种查找可能发生一次或多次。我想知道提供此功能的最有效方法


目前,我通过迭代每个ArrayList并将每个产品映射到其供应商来生成一个新的数据结构。但这很昂贵,因为每次添加之前,我都必须检查我创建的HashMap是否包含该产品作为密钥,另外还需要获取每个ArrayList,添加新供应商,删除旧ArrayList,然后为每个条目映射新ArrayList。我只是看不到一个更快的方法来做到这一点,也许有人可以给我一些见解

将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;
}

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

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);
    ....
映射公司副产品
地图产品公司
公共作废添加(公司、产品){
设置公司=公司副产品。获取(产品);
如果(公司==null){
companys=新HashSet();
companyesbyproduct.put(产品,公司);
}
公司。添加(公司);
//对我来说也是如此
Set products=productsByCompany.get(产品);
....
或者,要从您可以使用的服务器接收的映射创建新的公司副产品映射(您可能需要根据原始映射的确切类型进行调整):

for(公司:originalMap.keySet()){
用于(产品:originalMap.get(公司)){
设置公司=公司副产品。获取(产品);
如果(公司==null){
companys=新HashSet();
companyesbyproduct.put(产品,公司);
}
公司。添加(公司);
}
}

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

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

示例:

    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]}
替代解决方案:

    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]}
在这里,我创建了一个二维布尔数组,表示该公司及其产品,以便于查找

import java.util.ArrayList;
导入java.util.array;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Set;
导入com.google.common.collect.Multimap;
导入com.google.common.collect.set;
导入com.google.common.collect.TreeMultimap;
公共类产品公司映射{
private Multimap companyProducts=TreeMultimap.create();
私有布尔值[][]ProductCompanyTable;
私有映射productIndexMap=newHashMap();;
私有映射companyIndexMap=新HashMap();
私有字符串[]productArray;
私有字符串[]companyArray;;
{
公司产品。put(“Britania”、“Biscuts”);
公司产品。put(“不列颠尼亚”、“肥皂”);
公司产品。put(“不列颠尼亚”,“布”);
companyProducts.put(“微软”、“软件”);
公司产品放置(“Birla”、“Cloth”);
公司产品。put(“Birla”、“软件”);
}
公共产品公司映射(){
设置companyNames=companyProducts.keySet();
Set productNames=Sets.newTreeSet(companyProducts.values());
companyArray=companyNames.toArray(新字符串[companyNames.size()]);
createIndexMap(companyIndexMap,companyArray);
productArray=productNames.toArray(新字符串[productNames.size()]);
createIndexMap(productIndexMap,productArray);
ProductCompanyTable=新布尔值[companyArray.length][productArray.length];

对于(int i=0;iWhy)“删除旧的arraylist并映射新的arraylist?”您获取现有的一个。如果它为空,则添加一个并添加公司。否则,您将检查公司,如果公司不存在,则添加该公司。现在要测试它,看看它是如何工作的。感谢您的输入。关于数据库备选方案,我实际上已经看过了,但产品和公司名称可能会经常更改和/或被删除或删除添加。目前,我正在将原始HashMap存储在对象数据库中,并在用户点击“更新”时将其替换。因此,为了保存每次更新时的数据库同步工作,我将“从xtable中删除”,并在执行该查询之前重新创建它。但是,我不确定该操作将花费多长时间,您能否提供一些对吗?一旦你有了它,你就可以很容易地得到那些将产品视为公司副产品的公司。获取(产品)不幸的是,我从服务器获得了原始的HashMap,并且我无法向传输中添加更多数据,我必须完全在客户端创建替代结构。你能创建公司副产品映射一次吗(在客户端,不是每次都搜索原始映射?如果可以,那么您仍然可以使用相同的代码,您只需将其更改为使用服务器上的原始映射来填充新的映射。是的,这就是我正在尝试做的。问题是我只从productsbyCompany映射开始,并且必须创建CompanyByP我正在寻找从旧地图填充新地图的最有效方法。是的,这就是我目前正在做的。问题是我必须将第一个数据结构转换为第二个数据结构,我正在寻找最有效的方法。
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"));
    }
}