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