3

I am trying to extract unique elements from a list of Classes with the format:

[EntityClientPlayerMP['Player989'/228, l='MpServer', x=138.16, y=68.62, z=522.96], EntityCow['Cow'/231, l='MpServer', x=143.63, y=68.00, z=527.50]....]

these lists typically have a size of 60-100.

The method I am trying to use at the moment is

List<Class> uniqueList = new ArrayList<Class>(new HashSet<Class>(fullList));

this returns the exact same list, but sorted a bit differently. Any ideas on why?

jmj
  • 237,923
  • 42
  • 401
  • 438
Rampartisan
  • 427
  • 6
  • 19
  • What do you mean by "sorted a bit differently"? Can you provide an example? – chessbot May 29 '13 at 21:56
  • What does your `Class` class look like? (I assume you don't mean `java.lang.Class`?) – ruakh May 29 '13 at 21:57
  • This sounds a lot like a "_I didn't implement hashCode() and equals()_" issue. – jahroy May 29 '13 at 22:00
  • The sorting isn't an issue for me, I was confused as to why it would return a sorted version but not just the unique elements,as in it did an operation on the List to sort but not remove duplicates. Other comments have shown that I dont know enough about implementing hashcodes, so I'm looking into that at the moment I have explained my use of Class in a comment below. – Rampartisan May 29 '13 at 23:34

3 Answers3

3

They are ordered differently because HashSet has "weird" ordering, based upon the hashCode of the Objects. To preserve ordering, use a LinkedHashSet.

As for the uniqueness, the Set will use equals() and hashCode(), so be sure those are implemented correctly. A lazy technique that sometimes works is to use the toString() method of your objects (and call the hashCode and equals on the Strings).

user949300
  • 15,364
  • 7
  • 35
  • 66
2

You need to provide correct implementation for equals() and hashcode()

jmj
  • 237,923
  • 42
  • 401
  • 438
2

Don't forget to override the equals() and hashCode() methods in each of your entity classes (why?), otherwise the set won't be able to properly determine when two elements are equal. Also, I think you meant this:

List<EntityClientPlayerMP> uniqueList =
    new ArrayList<EntityClientPlayerMP>(
        new LinkedHashSet<EntityClientPlayerMP>(fullList));

Now in the above snippet the type parameter is one in particular (not Class as shown in the question, replace with the actual type as needed), and by using LinkedHashSet we guarantee that the ordering in the original list is preserved.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • The example list does not only include `EntityClientPlayerMP` but also `EntityCow`. Presumably these are subtypes of OP's `Class` type. – Arend May 29 '13 at 22:12
  • @Arend In that case you'd want Object. – user949300 May 29 '13 at 22:16
  • What I meant is, apparently the OP has defined his own type `Class` of which `EntityClientPlayerMP` and `EntityCow` are subtypes. Of course, this is just idle speculation, and hardly relevant to the question (to your answer of which I have nothing to add). – Arend May 29 '13 at 22:22
  • It's quite possible that OP is using `Class` as an example, a placeholder for the real classes, so let's ignore that and focus on the question – Óscar López May 29 '13 at 22:25
  • I am infact refering to Class, as this List is used in a mod for the game minecraft to search for enemies by their Class, an inbuilt method in the code asks for a Class as an argument. I am not sure if this is right or not, being a fairly new coder, but it works in the way I expected. Is using Class not a good idea? I am trying to post the method in this comment but there is not enough space, whats the best way to show it? – Rampartisan May 29 '13 at 23:28
  • Edit the question and add the details. And no, it doesn't seem to be a good idea to have a list of classes. All of the instances share the exact same class! – Óscar López May 30 '13 at 00:43