我遇到一个问题,其中一个键/值对正在正确更新,但具有相同键的其他值未得到更新。我正在使用一个HashMap,它包含一个字符串列表(Item Nbr)作为键,值存储为一个字符串列表(PO Nbr),因此在这方面它基本上是一对多的。下面是我实现这个HashMap的代码,但我只是卡住了。任何帮助将不胜感激。
public void process(List<PoBean> excelData,List<String> errors) throws CustomException
{
Map<String,ArrayList<String>> poNbrItemNbrMap = new HashMap<String, ArrayList<String>>();
ArrayList<String> poNbrList = new ArrayList<String>();
int recordCount = excelData.size();
for(PoBean bean : excelData)
{
if(rowValidator.validate(bean, errors))
{
if (!newErrorInRow(errors))
{
poNbrList.add(bean.getPoId());
poNbrItemNbrMap.put(bean.getItemNbr(),bean.getPoId());
}
}
}
List<DutyFees> dutyFeesTempDAO = myService.getAssocIdByPOAndItemNbr(new ArrayList<String>(poNbrItemNbrMap.keySet()),new ArrayList<String>(poNbrItemNbrMap.values()));
for(DutyFees duty : dutyFeesTempDAO)
{
Double dutyFees = new Double(0);
if(poNbrItemNbrMap.containsKey(duty.getItemNbr()) && poNbrItemNbrMap.containsValue(duty.getPoId()))
{
for(PoBean dutyBean : excelData)
{
if(duty.getPoId().equals(dutyBean.getPoId()) && duty.getItemNbr().equals(dutyBean.getItemNbr()))
{
dutyFees = new Double(dutyBean.getDutyFees());
break;
}
}
Boolean result = myService.updateDutyFeesByAssocID(duty.getAssocId(), dutyFees);
}
}
}
答案 0 :(得分:1)
你说你想要一对多,但你的代码有一对一
HashMap<String,String> poNbrItemNbrMap = new HashMap<String,String>();
一个字符串值的一个字符串键
斜体部分与您问题中的粗体部分形成对比。
我正在使用一个HashMap,它由一个字符串列表(Item Nbr)组成 键和值存储为字符串列表(PO Nbr), 所以它是 在这方面基本上是一对多。
斜体意味着许多人。 大胆意味着一对多。
无论如何,让我给你两个实现。
public class Test {
public static void main(String[] args) {
System.out.println("= One to Many =");
Map<String, List<String>> stringListMap = new HashMap<>();
String key = "list of 4 strings";
List<String> valuesList = Arrays.asList("one","two","three","four");
stringListMap.put(key,valuesList);
stringListMap.forEach((strings, strings2) -> System.out.println(strings.toString() + strings2.toString()));
System.out.println("= Many to Many =");
Map<List<String>, List<String>> listListMap = new HashMap<>();
List<String> keys = Arrays.asList("1","2","3","4");
List<String> values = Arrays.asList("one","two","three","four");
listListMap.put(keys,values);
listListMap.forEach((strings, strings2) -> System.out.println(strings.toString() + strings2.toString()));
}
}
编辑回复您的评论。 不确定你在评论中的意思,但我确实看到了几个问题。首先,当您放入地图时,您正在放置看似项目编号和po id的内容,因此它们似乎都是单个字符串类型而不是ArrayList。所以我甚至不确定你是如何编译它的。除非你的getPoId实际上是getPoIds并返回一个列表。我在谈论这一行
poNbrItemNbrMap.put(bean.getItemNbr(),bean.getPoId());
现在关于
new ArrayList<String>(poNbrItemNbrMap.values())
你不能像那样初始化数组列表。
我不知道getAssocIdByPoAndItemNbr函数的签名是什么,所以无法提出答案。但是,如果您只想发送映射值,那么直接发送它为什么将它作为构造函数参数放入新的ArrayList&lt;&gt;()?
答案 1 :(得分:0)
process
第一部分的目的很明确:将PoBean
个对象列表转换为Map<String, List<String>>
,将对象按itemNbr
分组到列表中。以下是代码:
// One-to-many relationship requires the value to be a List
// Better not say ArrayList here because then you put unnecessary
// Restrictions on the code.
Map<String, List<String>> poNbrItemNbrMap = new HashMap<>();
for(PoBean bean : excelData)
{
if(rowValidator.validate(bean, errors))
{
if (!newErrorInRow(errors))
{
String key = bean.getItemNbr();
List<String> value = poNbrItemNbrMap.get(key);
if (value == null) {
// This is first time we see this item nbr,
// Create a new list to hold the values
value = new ArrayList<>();
poNbrItemNbrMap.put(key, value);
}
// Just add the value to the list
value.add(bean.getPoId());
}
}
}
现在第二部分令人困惑,尤其是这一行:
List<DutyFees> dutyFeesTempDAO = myService.getAssocIdByPOAndItemNbr(new ArrayList<String>(poNbrItemNbrMap.keySet()),new ArrayList<String>(poNbrItemNbrMap.values()));
第一个参数几乎没有意义,它传递的密钥为List
;没关系。第二个参数无法编译,因为您需要new ArrayList<List<String>>(poNbrItemNbrMap.values())
。是的,您需要一个字符串列表列表。但这仅仅是个开始。 通过执行此操作,您基本上删除了键和值之间的关系,getAssocIdByPOAndItemNbr
方法无法再将关键字及其各自的值关联起来。它不能假设键中的第一项映射到值中的第一项。这意味着我们在第一部分做的任何事都没用。