具有多个值的Java hashmap

具有多个值的Java hashmap,java,hashmap,Java,Hashmap,我知道它被问了一百次,答案总是一样的,不能在hashmap中使用多个重复值。 但是让我们开始讨论这个问题。我有一个导入文件,该导入文件包含关于CustomerID、ProductID和销售单位(基本收据格式)行的信息。 我想做的是获取导入,将其放入地图中,并能够引用它 Map<integer,DoubleSales> hashmap = new HashMap <integer,DoubleSales> try { Scanner dataFile = new Scan

我知道它被问了一百次,答案总是一样的,不能在hashmap中使用多个重复值。 但是让我们开始讨论这个问题。我有一个导入文件,该导入文件包含关于CustomerID、ProductID和销售单位(基本收据格式)行的信息。 我想做的是获取导入,将其放入地图中,并能够引用它

Map<integer,DoubleSales> hashmap = new HashMap <integer,DoubleSales>
 try {
Scanner dataFile = new Scanner 9new File ("./salesData.csv"));
dataFile.nextLine();
while(dataFile.hasNextLine()){
String[] lineValues = line.split (",");
Integer CustomerID = Integer.parseInt(lineValues[0]);
Integer ProductID = Integer.parseInt(lineValues[1]);
integer Units = Integer.parseInt(lineValues[2]);
DoubleSales sales = new DoubleSales(CustomerID,ProductID,Units);
ProductData.put(CustomerID,sales);
}

class DoubleSales{
int CustomerID;
int ProductID;
int Units;

DoubleSales(int custID, int prodID, int Units){
CustomerID = custID;
ProductID = prodID;
Units = units;
}
}
使用上面的代码,当我打印customerID值1时,我只得到最后一个条目,即
10010,3.
如何打印CustomerID 1的所有值和售出的单位

for example:
1,10002,3
  10004,5
  10008,2
  10010,3
  10010,3 
(will add the two 10010 values later.)

我不希望使用数组列表。

您复制了
CustomerID
(所有id都是
1
),并将其用作Hashmap中的键。这就是为什么当您插入具有相同id的新记录时,它会保持OVVERD。看起来您的产品id是唯一的。试试看,或者拥有唯一的客户id。

您复制了
客户id
(所有id都是
1
),并将其用作Hashmap中的键。这就是为什么当您插入具有相同id的新记录时,它会保持OVVERD。看起来您的产品id是唯一的。试试看,或者拥有唯一的客户id。

试试Apache公共集合中的多值映射


有关更多参考资料,请尝试Apache Common Collections中的多值映射


更多参考

我认为在这种情况下,最好使用矩阵实现该结构。使用数组(或列表)可以很容易地做到这一点,其中行可以包含由产品id和销售单位组成的bean,由客户id索引。我认为在这种情况下,最好使用矩阵实现该结构。使用数组(或列表)很容易做到这一点,其中行可以包含由产品id和销售单位组成的bean,由客户id索引。在您的情况下,简单的
映射将不会对您有利,您写入指定客户值的所有内容都将被覆盖,如果要保留所有条目,同时使其易于引用,请尝试:

首先,创建一个结构化映射
Map productData=newhashmap();
第二,添加这样的产品
列表条目;
if(productData.get(CustomerID)==null){
entries=newarraylist();
条目。添加(销售);
productData.put(CustomerID,条目);
}否则{
列表条目=productData.get(CustomerID);
条目。添加(销售);
}
第三,查看您刚刚添加的产品列表
List products=productData.get(CustomerID);
if(产品!=null){
用于(双重销售产品:产品){
//在此处访问您的产品。
}
}
在您的情况下,简单的
映射不会对您有利,您写入指定客户价值的所有内容都将被覆盖。如果您希望保留所有条目,同时使其易于引用,请尝试:

首先,创建一个结构化映射
Map productData=newhashmap();
第二,添加这样的产品
列表条目;
if(productData.get(CustomerID)==null){
entries=newarraylist();
条目。添加(销售);
productData.put(CustomerID,条目);
}否则{
列表条目=productData.get(CustomerID);
条目。添加(销售);
}
第三,查看您刚刚添加的产品列表
List products=productData.get(CustomerID);
if(产品!=null){
用于(双重销售产品:产品){
//在此处访问您的产品。
}
}

我的第一个想法是Jerry Chin的解决方案,但我想向您展示第二种方法,只是为了证明同一问题有多种解决方案

您可以将值存储在
树集中。这不会限制输入,您可以输入任意次数,例如
110010,3

然后,在
DoubleSales
上定义一个订单(
Comparator
),以按CustomerID对订单进行分组

打印列表时,可以检查当前记录的customerID是否与以前的记录不同。如果不同,则它是新客户的第一条记录。如果不是,则属于同一客户

以及守则:

SortedSet<DoubleSales> set = new TreeSet<DoubleSales>(new Comparator<DoubleSales>() {
    @Override
    public int compare(DoubleSales o1, DoubleSales o2) {
        return Long.compare(o1.customerId, o2.customerId);
    }
});

// ... import data
set.add(new DoubleSales( /*...*/ ));

// iterate through data
DoubleSales prevDS = null;
for (DoubleSales ds : set) {
    if (prevDS == null || ds.customerId != prevDS.customerId) {
        // first record of a customer
        // print CustomerID, ProductID, UnitsSold
    } else {
        // second or next record of a customer
        // print ProductID, UnitsSold only
    }
    prevDS = ds;
}
SortedSet set=新树集(新比较器(){
@凌驾
公共整数比较(DoubleSales o1,DoubleSales o2){
返回Long.compare(o1.customerId,o2.customerId);
}
});
// ... 导入数据
添加(新的DoubleSales(/*…*/);
//遍历数据
DoubleSales prevDS=null;
适用于(双倍销售ds:套){
if(prevDS==null | | ds.customerId!=prevDS.customerId){
//客户的第一个记录
//打印CustomerID、ProductID、UnitsSold
}否则{
//客户的第二条或下一条记录
//打印ProductID,仅限UnitsSold
}
prevDS=ds;
}

我的第一个想法是Jerry Chin的解决方案,但我想向您展示第二种方法,只是为了证明同一问题有多种解决方案

您可以将值存储在
树集中。这不会限制输入,您可以输入任意次数,例如
110010,3

然后,在
DoubleSales
上定义一个订单(
Comparator
),以按CustomerID对订单进行分组

打印列表时,可以检查当前记录的customerID是否与以前的记录不同。如果不同,则它是新客户的第一条记录。如果不是,则属于同一客户

以及守则:

SortedSet<DoubleSales> set = new TreeSet<DoubleSales>(new Comparator<DoubleSales>() {
    @Override
    public int compare(DoubleSales o1, DoubleSales o2) {
        return Long.compare(o1.customerId, o2.customerId);
    }
});

// ... import data
set.add(new DoubleSales( /*...*/ ));

// iterate through data
DoubleSales prevDS = null;
for (DoubleSales ds : set) {
    if (prevDS == null || ds.customerId != prevDS.customerId) {
        // first record of a customer
        // print CustomerID, ProductID, UnitsSold
    } else {
        // second or next record of a customer
        // print ProductID, UnitsSold only
    }
    prevDS = ds;
}
SortedSet set=新树集(新比较器(){
@凌驾
公共整数比较(DoubleSales o1,DoubleSales o2){
返回Long.compare(o1.customerId,o2.customerId);
}
});
// ... 导入数据
添加(新的DoubleSales(/*…*/);
//遍历数据
DoubleSales prevDS=null;
适用于(双倍销售ds:套){
if(prevDS==null | | ds.customerId!=prevDS.customerId){
//客户的第一个记录
List<DoubleSales> entries;
if(productData.get(CustomerID) == null) {
    entries = new ArrayList<DoubleSales>();
    entries.add(sales);
    productData.put(CustomerID, entries);
} else {
    List<DoubleSales> entries = productData.get(CustomerID);
    entries.add(sales);
}
List<DoubleSales> products = productData.get(CustomerID);
if (products != null) {
    for(DoubleSales product : products) {
        // access your product here.
    }
}
SortedSet<DoubleSales> set = new TreeSet<DoubleSales>(new Comparator<DoubleSales>() {
    @Override
    public int compare(DoubleSales o1, DoubleSales o2) {
        return Long.compare(o1.customerId, o2.customerId);
    }
});

// ... import data
set.add(new DoubleSales( /*...*/ ));

// iterate through data
DoubleSales prevDS = null;
for (DoubleSales ds : set) {
    if (prevDS == null || ds.customerId != prevDS.customerId) {
        // first record of a customer
        // print CustomerID, ProductID, UnitsSold
    } else {
        // second or next record of a customer
        // print ProductID, UnitsSold only
    }
    prevDS = ds;
}