URL: https://www.overclockers.at/applications/java_set_ignoriert_equals_216445/page_1 - zur Vollversion wechseln!
Hiho,
ich hab hier eine Klasse SearchItem, welche eine Eigenschaft eines realen Objekts repräsentiert, nach der man suchen kann. Die besteht nur aus einem Namen und einer Methode equals:
Code:package search; public class SearchItem { private String name; public String getName() { return name; } // public void setName(String name) { // this.name = name; // } @Override public String toString() { return "SearchItem [name=" + name + "]"; } public SearchItem(String name) { this.name = name; } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj instanceof SearchItem) { System.out.println("iof SearchItem"); System.out.println(name+" equals "+((SearchItem)obj).getName()+"?"); return ((SearchItem)obj).getName().equalsIgnoreCase(this.getName()); } if (obj instanceof String) { System.out.println("iof String"); System.out.println(name+" equals "+obj+"?"); return name.equalsIgnoreCase((String)obj); } return false; } }
Code:package search; import java.util.*; public class SearchItemSystem { private Set<SearchItem> searchItems; private static SearchItemSystem instance; private SearchItemSystem() { searchItems = new HashSet<SearchItem>(); } /** * Returns the instance of SearchItemSystem * * @return instance */ public static SearchItemSystem getInstance() { if (instance==null) instance=new SearchItemSystem(); return instance; } /** * Deletes an Item from the system * @param name The name of the item * @return true if something was removed */ public boolean deleteItem(String name) { if (name==null) return false; SearchItem old = new SearchItem(name); return searchItems.remove(old); } /** * Edit an SearchItem * * @param name The name of the SearchItem * @param newName The new name * @return The new item. Null if something went wrong or there was no old item */ public SearchItem editItem(String name, String newName) { if (name==null) return null; if (newName==null) return null; if (name.equalsIgnoreCase(newName)) return null; SearchItem oldItem = new SearchItem(name); if (!searchItems.contains(oldItem)) return null; searchItems.remove(oldItem); return createItem(newName); } /** * Returns all items in the system * @return all items */ public Set<SearchItem> getAllItems() { return searchItems; } /** * Creates a new SearchItem, adds it to the system and returns it. * * @param name The name of the SearchItem * @return The created item, null if there is already such an item */ public SearchItem createItem(String name) { System.out.println("Items: "+searchItems); if (name==null) return null; if (searchItems.contains(name)) return null; SearchItem si = new SearchItem(name); System.out.println("new item: "+si); if (searchItems.contains(si)) return null; //TODO some evil voodoo magic happens here if (searchItems.add(si)) return si; return null; } }
Code:package search.test; import search.SearchItem; import search.SearchItemSystem; import junit.framework.*; public class SearchItemSystemTest extends TestCase{ SearchItemSystem sis = null; SearchItem a = new SearchItem("A"); SearchItem b = new SearchItem("B"); SearchItem c = new SearchItem("C"); public void setUp() { sis = SearchItemSystem.getInstance(); } public void testItems() { assertTrue(".equals isn't working", (new SearchItem("D")).equals(new SearchItem("d"))); assertTrue(".equals isn't working", (new SearchItem("D")).equals("d")); assertFalse(".equals isn't working", b.equals("C")); assertTrue(".equals isn't working", b.equals("b")); assertTrue(".equals isn't working", b.equals(b)); assertFalse(".equals isn't working", b.equals(c)); assertEquals("Null-Item was created", null, sis.createItem(null)); assertEquals("Item A was not created", a, sis.createItem("A")); assertEquals("Item A was created twice", a, sis.createItem("a")); assertEquals("Item A was created three times", a, sis.createItem("a")); } public static void main(String[] args) { // TODO Auto-generated method stub junit.textui.TestRunner.run(SearchItemSystemTest.class); } }
Code:iof SearchItem D equals d? iof String D equals d? iof String B equals C? iof String B equals b? iof SearchItem B equals B? iof SearchItem B equals C? Items: [] Items: [] new item: SearchItem [name=A] iof SearchItem A equals A? Items: [SearchItem [name=A]] new item: SearchItem [name=a] iof SearchItem A equals a? Items: [SearchItem [name=a], SearchItem [name=A]] new item: SearchItem [name=a] iof SearchItem A equals a?

ohne jetzt was genauer angeschaut zu haben: für ein HashSet solltest du auch hashCode überschreiben, der aus den properties, die in equals verwendet werden, halt einen hash berechnet...
glaube auch dass deine equals version nie aufgerufen wird..
Zitat von DKCHohne jetzt was genauer angeschaut zu haben: für ein HashSet solltest du auch hashCode überschreiben, der aus den properties, die in equals verwendet werden, halt einen hash berechnet...
Zitat von Nicoglaube auch dass deine equals version nie aufgerufen wird..
Code:@Override public int hashCode() { return this.name.toLowerCase().hashCode(); }

ich weiss nicht mit welcher ide du arbeitest, aber eclipse zum beispiel kann dir equals und hashcode generieren (allerdings nur bis zu einem gewissen grad sinnvoll, in deinem fall aber wahrscheinlich ausreichend)
lg
generell ist das überschreiben von equals alleine selten sinnvoll und wird völlig zurecht von "findbugs" (super plugin btw) als bug identifiziert... sobald das ding in nem hashset oder hashmap drin ist, kommst in teufels küche...
plugin für welche ide?
eclipse
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2026