将数据放入TreeMap,导致重复条目

时间:2015-03-09 22:43:16

标签: java arraylist hashmap immutability treemap

我在Stackoverflow上的第一篇文章,请原谅我,如果我发错了......

所以我有一个ArrayList<Person>包含大量个人数据(通过json从服务获取,解析并映射到POJO Person)。 我想从这些数据中获取一些统计数据(绘制减肥/增益等图表)。

首先插入所有Person标识符(从HashSet中的ArrayList中过滤掉重复项,为每个人留下唯一标识符。

然后我想要这个结构:

HashMap<String, TreeMap<Date, Double> mapWithWeightPerPerson = new HashMap<>();

所以我要做的是在HashMap中使用TreeMap为每个日期添加一个Persons权重数据。 (天气这是一个很好的设计决定可能需要讨论)。

因此,对于每个标识符,我遍历带有所有Person的ArrayList并将人员记录添加到a 带有键的TreeMap:Date(稍后可能会使用String),以及值:Double为权重。 然后我将TreeMap添加到外部HashMap,并为所有标识符执行此操作。

for (String identifier : setWithUniqueIdentifiers) {
    TreeMap<Date, Double> personWeightData = new TreeMap<>();
    for (Person person : listWithAlotOfPersons) {
        if (person.getSymbol().equalsIgnoreCase(identifier)) {
            System.out.println("Date = " + person.getDate());
            System.out.println("Weight = " + person.getWeight());

            personWeightData.put(person.getDate(), person.getWeight()));
            for (Double weight : personWeightData.values()) {
                System.out.println("Values inserted so far: " + weight);
            }
        }
    }
    System.out.println("in key: " + identifier);
    mapWithWeightPerPerson.put(identifier, personWeightData);
}

当迭代mapWithWeightPerPerson并打印所有人的日期重量数据时,我反复得到理智的数据,即使我做了 personWeightData = new TreeMap&lt;&gt;();以上。这就是我打印mapWithWeightPerPerson时的样子。

Date = 2015-03-05
Weight = 44.16
Values inserted so far: 44.16
Date = 2015-03-04
Weight = 43.99
Values inserted so far: 43.99
Values inserted so far: 44.16
Date = 2015-03-03
Weight = 42.62
Values inserted so far: 42.62
Values inserted so far: 43.99
Values inserted so far: 44.16
Date = 2015-03-02
Weight = 44.11
Values inserted so far: 44.11
Values inserted so far: 42.62
Values inserted so far: 43.99
Values inserted so far: 44.16
Date = 2015-02-27
Weight = 44.28
Values inserted so far: 44.28
Values inserted so far: 44.11
Values inserted so far: 42.62
Values inserted so far: 43.99
Values inserted so far: 44.16
in key: FatBob
Date = 2015-03-05
Weight = 12.77
Values inserted so far: 12.77
Date = 2015-03-04
Weight = 12.82
Values inserted so far: 12.82
Values inserted so far: 12.77
Date = 2015-03-03
Weight = 12.76
Values inserted so far: 12.76
Values inserted so far: 12.82
Values inserted so far: 12.77
Date = 2015-03-02
Weight = 12.91
Values inserted so far: 12.91
Values inserted so far: 12.76
Values inserted so far: 12.82
Values inserted so far: 12.77
Date = 2015-02-27
Weight = 12.93
Values inserted so far: 12.93
Values inserted so far: 12.91
Values inserted so far: 12.76
Values inserted so far: 12.82
Values inserted so far: 12.77
in key: SkinnyPete
Date = 2015-03-05
Weight = 360.30
Values inserted so far: 360.3
Date = 2015-03-04
Weight = 360.50
Values inserted so far: 360.5
Values inserted so far: 360.3
Date = 2015-03-03
Weight = 360.40
Values inserted so far: 360.4
Values inserted so far: 360.5
Values inserted so far: 360.3
Date = 2015-03-02
Weight = 365.40
Values inserted so far: 365.4
Values inserted so far: 360.4
Values inserted so far: 360.5
Values inserted so far: 360.3
Date = 2015-02-27
Weight = 363.80
Values inserted so far: 363.8
Values inserted so far: 365.4
Values inserted so far: 360.4
Values inserted so far: 360.5
Values inserted so far: 360.3
in key: BaldJohn

但是当循环和打印mapWithWeightPerPerson时,我希望它是:

Person: FatBob
{2015-02-27=144.28, 2015-03-02=144.11, 2015-03-03=142.62, 2015-03-04=143.99, 2015-03-05=144.16}
Person: SkinnyPete
{2015-02-27=112.93, 2015-03-02=112.91, 2015-03-03=112.76, 2015-03-04=112.82, 2015-03-05=112.77}
Person: BaldJohn
{2015-02-27=363.8, 2015-03-02=365.4, 2015-03-03=360.4, 2015-03-04=360.5, 2015-03-05=360.3}

期待您的回答。

2 个答案:

答案 0 :(得分:0)

你对mapWithWeightPerPerson中的所有条目都有相同的结果,所以问题可能是,

  1. 所有条目中的TreeMap实例都是相同的。
  2. 您将所有人员数据添加到每个TreeMap
  3. 要验证它是否由第一个原因引起,您可以迭代mapWithWeightPerPerson并注销值的原始哈希值,如果它们不同,则不是原因。

    for (Map.Entry<String, TreeMap<Date, Double> entry : mapWithWeightPerPerson>) {
        System.out.println(System.identityHashCode(entry.getValue()));
    }
    

    要验证是否由第二个原因引起,您可以在以下行中添加调试日志,

    if (person.getName().equalsIgnoreCase(identifier)) {
        System.out.println(String.format("identifier %s, person name %s", identifier, person.getname()));
        personWeightData.put(person.getDate(), person.getWeight());
    }
    

    如果每个标识符都有多个日志,那么if子句中的条件是错误的。

答案 1 :(得分:0)

我在打印mapWithWeightPerPerson(HashMap)时遇到错误:

for (Object o : mapWithWeightPerPerson.keySet()) {
    System.out.println("Person: " + o);
    Collection collection = mapWithWeightPerPerson.values();
    Iterator iterator = collection.iterator();
    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }
}

更改为:

Iterator it = mapWithWeightPerPerson.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry pair = (Map.Entry) it.next();
    System.out.println(pair.getKey() + " = " + pair.getValue());
    it.remove(); // avoids a ConcurrentModificationException
}

适用于输出:

FatBob = {2015-02-27=44.28, 2015-03-02=44.11, 2015-03-03=42.62, 2015-03-04=43.99, 2015-03-05=44.16}
SkinnyPete = {2015-02-27=12.93, 2015-03-02=12.91, 2015-03-03=12.76, 2015-03-04=12.82, 2015-03-05=12.77}
BaldJohn = {2015-02-27=363.8, 2015-03-02=365.4, 2015-03-03=360.4, 2015-03-04=360.5, 2015-03-05=360.3}