简体   繁体   English

java.util.treemap给出奇怪的结果

[英]java.util.treemap gives strange results

I have the following method : 我有以下方法:

     public final NavigableSet<AnimalCard> getCowTradeCardsSorted() {
    TreeMap<AnimalCard,AnimalCard> ssa = new TreeMap<AnimalCard,AnimalCard>();
    Iterator<E> i = this.cowTradeCards.iterator();
    System.out.println("Input is:"+this.cowTradeCards.toString());
    while (i.hasNext()) {
        E a = i.next();
        System.out.println("Adding 2 ssa:"+a.toString());

        ssa.put((AnimalCard) a ,(AnimalCard) a); //this.getCountOfOneCard(a));
        System.out.println("ssa is now"+ssa.toString());

    }
    System.out.println("returnvalue is"+ ssa.descendingKeySet().toString());
    return ssa.descendingKeySet().descendingSet();
}

where i would expect the following output as returnvalue: [1000,500,160,10] 我希望将以下输出作为返回值:[1000,500,160,10]

but i get [1000] 但我得到了[1000]

here is the output fom console: 这是输出fom控制台:

   Input is:[1000, 10, 160, 500]
   Adding 2 ssa:1000
   ssa is now{1000=1000}
   Adding 2 ssa:10
   ssa is now{1000=10}
   Adding 2 ssa:160
   ssa is now{1000=160}
   Adding 2 ssa:500
   ssa is now{1000=500}
   returnvalue is[1000]

what is wrong? 怎么了? it looks like treemap is binding all value to the first key? 好像树图将所有值绑定到第一个键?

ps: this.cowtradecards is a arraylist but that doesn´t matter really ps:this.cowtradecards是一个数组列表,但这并不重要

    public class AnimalCard extends Card { ..........

      // super has this :public int getValue() {
  //        return this.value;
  //       }


    @Override
public int compareTo(Object o) {
    // Pufferelement vom Typ AnimalCard
    AnimalCard buffer;

    // Kontrolle, ob übergebenes Objekt vom Typ "AnimalCard" ist
    if (o instanceof MoneyCard) {   <--------------- here is the error !!!!! should be AnimalCard !
        // wenn ja, dann Typcasting vornehmen
        buffer = (AnimalCard) o;

        if (super.getValue() < buffer.getValue()) {
            return -1;
        }
        if (super.getValue() > buffer.getValue()) {
            return 1;
        }
        return 0;
    } else {
        // not an "AnimalCard"

    }
    return 0;
}

after i fixed the compareto:
    Input is:[1000, 10, 160, 500]
    Adding 2 ssa:1000
    ssa is now{1000=1000}
    Adding 2 ssa:10
    ssa is now{10=10, 1000=1000}
    Adding 2 ssa:160
    ssa is now{10=10, 160=160, 1000=1000}
    Adding 2 ssa:500
    ssa is now{10=10, 160=160, 500=500, 1000=1000}
    returnvalue is[1000, 500, 160, 10]

The problem likely has to do with compareTo in AnimalCard . 该问题可能与AnimalCard compareTo AnimalCard Check that compareTo is doing what you expect it to do, and that two AnimalCard instances with different numbers are not considered equal based on this method (ie it does not return 0 in such cases). 根据此方法,检查compareTo是否正在执行您期望的操作,并检查两个具有不同编号的AnimalCard实例是否相等(即,在这种情况下,它不会返回0 )。 If they are, then that would explain your result, since TreeMap would simply update the pre-existing entry instead of adding a new one. 如果是的话,那将解释您的结果,因为TreeMap只会更新现有的条目,而无需添加新的条目。

Also, if you're debugging, you might want to print the return value of put() (it could give you some insight as to what's going on). 另外,如果要调试,则可能需要打印put()的返回值(它可以使您对正在发生的事情有一些了解)。

Your toString method is saying "ssa is now{1000=1000}" and "ssa is now{1000=160}" - so probably, they all seem to have, for whatever reason, that 1000 in all of them. 您的toString方法说“ ssa现在是{1000 = 1000}”和“ ssa现在是{1000 = 160}”-可能由于某种原因,它们似乎全部都具有1000。 I would look at your compareTo method on AnimalCard for further clues. 我将在AnimalCard上查看您的compareTo方法以获取更多线索。

Based on your method name, you want to sort your ArrayList(and remove duplicates). 根据您的方法名称,您要对ArrayList排序(并删除重复项)。 If AnimalCard implements Comarable, this should be as simple as 如果AnimalCard实现了Comarable,那么这应该很简单

return new TreeSet<AnimalCard>(cowTradeCards);

As everyone else has been saying, you've got an incorrect/incomplete implementation of compareTo() , and it's causing the problems you're seeing. 就像其他所有人都说的那样,您有一个compareTo()的错误/不完整的实现,这正在引起您所看到的问题。

public int compareTo(Object o) {
    // Pufferelement vom Typ AnimalCard
    AnimalCard buffer;

    // Kontrolle, ob übergebenes Objekt vom Typ "AnimalCard" ist
    if (o instanceof MoneyCard) {   <--------------- here is the error !!!!! should be AnimalCard !
        // Lots of really interesting logic that's never going to get run because o instanceof AnimalCard, not Moneycard.
    } else {
        // We're always going to come here, but we're not going to do anything, so we'll fall through...
    }
    // And now we'll return a value saying that the two objects are equal.  ALWAYS.
    return 0;
}

Your comparator says that all AnimalCards are equal to one another. 您的比较者说,所有动物卡都彼此相等。 Your TreeMap adds the first one (1000) as you would expect. 如您所愿,TreeMap将添加第一个(1000)。 When it comes to the second one, it recognizes that it's equal to the first one, so it keeps the key as is but puts the new AnimalCard into the value. 当涉及到第二张卡片时,它认识到它等于第一张卡片,因此它保持原样的键,但是将新的AnimalCard放入值中。 (Why, I'm not sure, but it doesn't really matter.) When we insert the third one, the same thing happens: the first object is kept as the key, and the third replaces the second as the value. (为什么,我不确定,但这并不重要。)当我们插入第三个对象时,会发生相同的事情:第一个对象保留为键,第三个对象替换第二个为值。 So after inserting them all, you're left with a map with a single entry, with a key equal to the first and a value equal to the second. 因此,在全部插入之后,您将获得一个具有单个条目的映射,其键等于第一个键,而值等于第二个键。

To beat a dead horse: Fix your compareTo() . 击败一匹死马:修复您的compareTo() You'll fix your problem. 您将解决您的问题。

Incidentally, the sample code you've posted doesn't need a TreeMap; 顺便说一句,您发布的示例代码不需要TreeMap。 if you're using the value as the key, what you really wanted was probably a Treeset . 如果您使用值作为键,那么您真正想要的可能是Treeset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM