Java Comparator given the name of the property to compare - java

My problem is this; I have to order a table of data. Each row of the table is an object (lets call it TableObject) stored in a List. Each column of data is a property of the class (usually a String).
I have to do the typical ordering of data when the user clicks on any column. So I thought about changing the List to a TreeSet and implementing Comparator in my TableObject.
The problem comes when I try to reorder the TreeSet. The compare is fairly easy at first (cheeking for exceptions in parseInt have been omitted):
public int compare(TableObject to1, TableObject to2){
TableObject t1 = to1;
TableObject t2 = to2;
int result = 1;
if(Integer.parseInt(t1.getId()) == Integer.parseInt(t2.getId())){result=0;}
if(Integer.parseInt(t1.getId()) < Integer.parseInt(t2.getId())){result=-1;}
return result;
}
But when I have to reorder by the text of the data or by other dozens of data that the TableObject has I have a problem.
I do not want to create dozens of compare functions, each for one. I prefer not to use a switch (or a chain of ifs) to decide how to compare the object.
Is there any way to do this in some way (like Reflexive), that doesn't imply that I will write like hundreds of lines of nearly the same code?
Thanks for all!

Bean Comparator should work.
Using reflection the BeanComparator that will allow you to sort on any property that has a zero parameter method that returns the value of the property.
So basically you can sort on any property that has a "getter" method.

What you could do is make the comparator take a String representing the name of the parameter to sort by in its constructor.
Then you could use reflection to sort by the given parameter.
The following code is very dirty. But I think it illustrates the gist of what you would need to do.
public class FieldComparator<T> implements Comparator<T> {
String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#Override
public int compare(T o1, T o2) {
Field toCompare = o1.getClass().getField(fieldName);
Object v1 = toCompare.get(o1);
Object v2 = toCompare.get(o2);
if (v1 instanceof Comparable<?> && v2 instanceof Comparable<?>){
Comparable c1 = (Comparable)v1;
Comparable c2 = (Comparable)v2;
return c1.compareTo(c2);
}else{
throw new Exception("Counld not compare by field");
}
}
}

Yes, you could use the reflection API, to get the content of a field based on it's name.
See Field class and especially the Field.get method.
(I wouldn't recommend it though, as reflection is not designed for this type of task.)

Related

Using a comparable on 3 different classes

I'm trying to implement a function that returns the maximum object of a given Comparable (generic) list.
I have 3 classes that I have implemented their compareTo method that returns the 1 if this is bigger than other, -1 if this is smaller than other, and 0 if they're equal.
Now my problem is with understanding with how do I work with a generic input COmparable list.
Here's the signature of my function, and the code I wrote so far (that refuses to work on me):
public static Comparable<?> getMax(List<Comparable<?>> ls) {
LinkedList<Comparable<?>> tmpComp = new LinkedList<Comparable<?>>();
for (Comparable<?> c : ls)
tmpComp.add(c);
Comparable<?> maxObj = tmpComp.get(0);
for (Comparable<?> c : tmpComp)
if (c.compareTo(maxObj) > 0)
m = c;
return m;
}
I'm writing a system that has users in it, and ads. Users and ads both classes that have "profit" field on them that all I do in my compareTo methods is to compare which of the two (this, or other) have more profit and then just returns the right value according to that. The 3rd class is compared via another field, which is an int as well, that indicates the level (int) of the Quest.
Also that if statement, specifically, gives me an error of the type "is not applicable for the arguments".
Any clues?
Thanks in advance!
Reading your comment, I suggest you redesign your model to be:
interface ProfitGenerating {
double getProfit();
}
class User implements ProfitGenerating {
...
}
class Advert implements ProfitGenerating {
...
}
List<ProfitGenerating> profits = ...;
Optional<ProfitGenerating> maxProfit = profits.stream()
.max(Comparator.comparingDouble(ProfitGenerating::getProfit));
The answer by Mạnh Quyết Nguyễn is good. But it does not account for the situation where you have multiple potential types T, which appears to be your situation.
So in that situation, just wrap your various classes with a single class and use his solution.
If you have a User class and an Ad class, then create a wrapper like so:
class ProfitMaker implements Comparable<ProfitMaker> {
User user;
Ad ad;
public int compare(ProfitMaker p) {
//check my profit and compare with profit of p
}
}
Use that class as the "T" when usign the getMax from Mạnh Quyết Nguyễn.
Alternatively, use an interface
interface ProfitMaker extends Comparable<ProfitMaker> {
int getProfit();
}
Make both your User and Ad classes implement that interface, and that use that interface as the "T" along with the getMax method from Mạnh Quyết Nguyễn.
Your three classes must be comparable to each other. For this they will need to implement Comparable<SomeX> where SomeX is their lowest common superclass. In the worst case, SomeX is Object.
If this is the case, you can simply do:
ls.stream().max(Comparator.naturalOrder())
Alternatively, instead of forcing your classes to implement Comparable<...>, you could capture comparison semantics in a Comparator<...> and then do:
ls.stream().max(comparator)
Using a comparator is better for cases where the order is not really "natural" for the type or where there may be different orders. I think this is the case here since you actually compare instances of different types. It is hard to argue that some order is "natural" for these instances as they don't even belong to one type.
If you compare your instances based on some property they share (like int getProfit()), it would make sense creating a common interface like Profitable. Then you could do:
ls.stream().max(Comparator.comparintInt(Profitable::getProfit))
Note that if you compare on privitive types, you should use comparingInt/comparingLong/comparingDouble instead of comparing to avoid unnecessary boxing and unboxing.
If you for some reason can't create and implement a common interface like Profitable, you can still use comparingInt and likes. You'll just have a much uglier lambda:
ls.stream().max(Comparator.comparintInt(l -> {
if (l instanceof Ad) { return ((Ad) l).getProfit(); }
else if (l instanceof Ransom) { return ((Ransom) l).getProfit(); }
// ...
else { throw new IllegalArgumentException(...); }
}))

When using Collections.sort - no instance of Variable T exist so that Collection conforms etc

so I've build these two classes:
1. Genre which implements Comparable
2. GenreManager which takes a Collection of genres and creates an internal copy of it. Later in GenreManager, I will need to add new Genres by getting a name as an input, and I need to assign this Genre the next free id number, which is basically the next smallest positive number after the smallest used id.
I am trying to use Collections.sort() to sort my list but I am getting the following error:
"no instance(s) of type variable(s) T exist so that Collection conforms to List." and I am not sure what this is referring to... I've tried ready a bunch of posts about this on here but couldn't figure out the solution... Here is part of the code:
public class Genre implements Comparable<Genre>{
private int id;
private String name;
public Genre(int id, String name){
this.id = Validate.requireNonNegative(id);
this.name = Validate.requireNonNullNotEmpty(name);
}
#Override
public int compareTo(Genre o) {
int res = Integer.valueOf(id).compareTo(o.id);
if (res != 0){
return res;
}
else{
return this.name.compareToIgnoreCase(o.name);
}
}
}
public class GenreManager{
private Collection<Genre> genres;
private Collection<Genre> sortedTree;
public GenreManager(){
this.genres = new ArrayList<Genre>();
}
public GenreManager(Collection<Genre> genres){
// check for duplicates
for (Genre x : genres){
for (Genre y : genres){
if (x.equals(y) || x.getName().equals(y.getName()))
throw new IllegalArgumentException("List contains duplicates");
}
}
this.genres = new ArrayList<Genre>(Collections.sort(genres));
}
}
I am trying to do the sorting in the constructor above. Can someone tell me how to go around this?
I tried playing around a little bit, trying to change the private variable from Collection<Genre> to List<Genre> for example and similar things but nothing worked... I also tried casting the input of the .sort method to (List<Genre>) but it didn't work either.
PS: I can't change any of the method header or class headers.
Thanks!
As per request, here's a compilation of my comments to answer the question:
The immediate problem is that Collections.sort(List<T>) takes a List parameter and not just a Collection because collections in general don't have to be sortable (e.g. hash sets aren't). Additionally the method returns void and sorts the passed list in place, i.e. the way you call it won't compile.
Taking all this into consideration your code might be changed to something like this:
public class GenreManager{
private List<Genre> genres;
...
public GenreManager(Collection<Genre> genres){
...
//create a list out of the passed collection
this.genres = new ArrayList<Genre>( genres );
//sort the list
Collections.sort(this.genres);
}
}
The other problem with the code you posted is that for any non-empty collection it will throw the IllegalArgumentException because elements are compared to themselves. Adding a check for x != y to the condition would solve that but the code is still somewhat slow because it has a time complexity of O(n2).
This can be solved to use a set instead of a list. However, a HashSet would depend on how equals() and hashCode() define equality, which doesn't seem to match your requirements. That could be solved by using a wrapper object that implements both methods as needed.
A better approach might be to use a TreeSet though. TreeSet uses comparisons to determine order and equality (if the compare result is 0) and thus would allow you to either let your Genre class implement Comparable as you did or provide a separate Comparator (e.g. if you need multiple different definitions of equality).
If you just want to eliminate duplicates, your code could then look like this:
public class GenreManager{
private SortedSet<Genre> genres;
...
public GenreManager(Collection<Genre> genres){
this.genres = new TreeSet<>( genres );
}
}
If you want to know what duplicates are in the collection you could do it like this:
public GenreManager(Collection<Genre> genres){
this.genres = new TreeSet<>(); //the generic type is inferred from this.genres
for( Genre element : genres ) {
//If the element didn't exist in the set add() will return true, false if it existed
boolean nonDuplicate = this.genres.add( element );
//handle the duplicate element here
}
}
As it was mentioned before, your code has several errors which makes it unusable:
Checking equality of elements with themselves.
Collections.sort method takes a List of Comparable as an argument, when Collection is a little higher in a hierarchy, which means you can't use it as a parameter. To resolve it change declaration of variable genres to List.
method Collections.sort returns void, so you can't pass its return value as an argument to ArrayList constructor. Instead, try assigning genres variable first and then sorting it via Collections.sort as
this.genres = new ArrayList/LinkedList(genres)
Collections.sort(this.genres)
Again, you may consider using TreeSet as it holds all elements sorted and without duplicates, so your constructor will just look like
this.genres = new TreeSet(genres)
In addition, it prevents duplicates even during adding, so if you have 10 elements, adding already existing one won't make any changes to your set. But using this data structure you should check variable for null before adding, as it will produce NullPointerException

How to avoid of huge amount of key objects for different HashMaps

In my project in several places I use HashMap. Each of my HashMap should have a key with several fields like this:
public Long campaignId;
public Integer regionId;
public String posaLang;
public String audienceCode;
public String theme;
public GroupKey(Long campaignId,
Integer regionId,
String posaLang,
String audienceCode,
String theme) {
this.campaignId = campaignId;
this.regionId = regionId;
this.posaLang = posaLang;
this.audienceCode = audienceCode;
this.theme = theme;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AdGroupKey that = (AdGroupKey) o;
return new EqualsBuilder()
.append(regionId, that.regionId)
.append(posaLang, that.posaLang)
.append(audienceCode, that.audienceCode)
.append(theme, that.theme)
.isEquals();
}
#Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(regionId)
.append(posaLang)
.append(audienceCode)
.append(theme)
.toHashCode();
}
}
It's so huge amount of code, and for each HashMap I should write a key class as above. Is there a way to avoid of huge amout of this objects ?
I suspect your question would have attracted more views if it was titled "Best approach to composite keys in a HashMap".
There are many choices to choose from, and using a separate class for each key type may well be the best option. It is canonical and safe as it can represent any possible value made up of any combination of possible values from each of the fields. To minimize space overhead, think about whether you really need campaignId to be a Long object, or just a primitive long – in other words, can it be null?
You could combine all the fields into a single string, which could save space as you are then storing all the fields consecutively in memory instead of having separate reference variables. But this can be tricky. What will you use as a delimiter between fields? Are you sure this delimiter will never be part of a field?
You can store each field separately, as in the original option, but without having to write a class for each key type. All you need is a collection class that can store all the fields and provide suitable hashCode and equals methods that use the values of the fields. In fact, the List interface provides this. Its hashCode and equals method specifications are exactly what you need. They combine the hashCode and equals methods of each field in turn.
So, instead of a class, just use a List:
List<Object> myKey = Arrays.asList(campaignId, regionId, posaLang, audienceId);
HashMap<List<?>, ValueClass> myMap = new HashMap<>();
myMap.put(myKey, myValue);
myValue = myMap.get(Arrays.asList(campaignId, regionId, posaLang, audienceId));
Advantage: it's convenient, you don't have to write a class for each key.
Disadvantage: lack of type safety. You can't have homogeneous lists, so all fields have to be of type Object. There is no protection against creating a list with too many or too few objects, or objects of the wrong type.

Not sure how to sort an ArrayList based on parts of Objects in that ArrayList (Java)

I have a Sorts class that sorts (based on insertion sort, which was the assignment's direction) any ArrayList of any type passed through it, and uses insertion sort to sort the items in the list lexicographically:
public class Sorts
{
public static void sort(ArrayList objects)
{
for (int i=1; i<objects.size(); i++)
{
Comparable key = (Comparable)objects.get(i);
int position = i;
while (position>0 && (((Comparable)objects.get(position)).compareTo(objects.get(position-1)) < 0))
{
objects.set(position, objects.get(position-1));
position--;
}
objects.set(position, key);
}
}
}
In one of my other files, I use a method (that is called in main later) that sorts objects of type Owner, and we have to sort them by last name (if they are the same, then first name):
Directions: "Sort the list of owners by last name from A to Z. If more than one owner have the same last name, compare their first names. This method calls the sort method defined in the Sorts class."
What I thought first was to get the last name of each owner in a for loop, add it to a temporary ArrayList of type string, call Sorts.sort(), and then re-add it back into the ArrayList ownerList:
public void sortOwners() {
ArrayList<String> temp = new ArrayList<String>();
for (int i=0; i<ownerList.size(); i++)
temp.add(((Owner)ownerList.get(i)).getLastName());
Sorts.sort(temp);
for (int i=0; i<temp.size(); i++)
ownerList.get(i).setLastName(temp.get(i));
}
I guess this was the wrong way to approach it, as it is not sorting when I compile.
What I now think I should do is create two ArrayLists (one is firstName, one is LastName) and say that, in a for loop, that if (lastName is the same) then compare firstName, but I'm not sure if I would need two ArrayLists for that, as it seems needlessly complicated.
So what do you think?
Edit: I am adding a version of compareTo(Object other):
public int compareTo(Object other)
{
int result = 0;
if (lastName.compareTo(((Owner)other).getLastName()) < 0)
result = -1;
else if (lastName.compareTo(((Owner)other).getLastName()) > 0)
result = 1;
else if (lastName.equals(((Owner)other).getLastName()))
{
if (firstName.compareTo(((Owner)other).getFirstName()) < 0)
result = -1;
else if (firstName.compareTo(((Owner)other).getFirstName()) > 0)
result = 1;
else if (firstName.equals(((Owner)other).getFirstName()))
result = 0;
}
return result;
}
I think the object should implement a compareTo method that follows the normal Comparable contract--search for sorting on multiple fields. You are correct that having two lists is unnecessary.
If you have control over the Owner code to begin with, then change the code so that it implements Comparable. Its compareTo() method performs the lastName / firstName test described in the assignment. Your sortOwners() method will pass a List<Owner> directly to Sorts.sort().
If you don't have control over Owner, then create a subclass of Owner that implements Comparable. Call it OwnerSortable or the like. It accepts a regular Owner object in its constructor and simply delegates all methods other than compareTo() to the wrapped object. Its compareTo() will function as above. Your sortOwners() method will create a new List<OwnerSortable> out of the Owner list. It can then pass this on to Sorts.sort().
Since you have an ArrayList of objects, ordinarily we would use the Collections.sort() method to accomplish this task. Note the method signature:
public static <T extends Comparable<? super T>> void sort(List<T> list)
What's important here is that all the objects being sorted must implement the Comparable interface, which allows objects to be compared to another in numerical fashion. To clarify, a Comparable object has a method called compareTo with the following signature:
int compareTo(T o)
Now we're getting to the good part. When an object is Comparable, it can be compared numerically to another object. Let's look at a sample call.
String a = "bananas";
String b = "zebras";
System.out.println(a.compareTo(b));
The result will be -24. Semantically, since zebras is farther in the back of the dictionary compared to bananas, we say that bananas is comparatively less than zebras (not as far in the dictionary).
So the solution should be clear now. Use compareTo to compare your objects in such a way that they are sorted alphabetically. Since I've shown you how to compare strings, you should hopefully have a general idea of what needs to be written.
Once you have numerical comparisons, you would use the Collections class to sort your list. But since you have your own sorting ability, not having access to it is no great loss. You can still compare numerically, which was the goal all along! So this should make the necessary steps clearer, now that I have laid them out.
Since this is homework, here's some hints:
Assuming that the aim is to implement a sort algorithm yourself, you will find that it is much easier (and more performant) to extract the list elements into an array, sort the array and then rebuild the list (or create a new one).
If that's not the aim, then look at the Collections class.
Implement a custom Comparator, or change the object class to implement Comparable.

Most efficient way to see if an ArrayList contains an object in Java

I have an ArrayList of objects in Java. The objects have four fields, two of which I'd use to consider the object equal to another. I'm looking for the most efficient way, given those two fields, to see if the array contains that object.
The wrench is that these classes are generated based on XSD objects, so I can't modify the classes themselves to overwrite the .equals.
Is there any better way than just looping through and manually comparing the two fields for each object and then breaking when found? That just seems so messy, looking for a better way.
Edit: the ArrayList comes from a SOAP response that is unmarshalled into objects.
It depends on how efficient you need things to be. Simply iterating over the list looking for the element which satisfies a certain condition is O(n), but so is ArrayList.Contains if you could implement the Equals method. If you're not doing this in loops or inner loops this approach is probably just fine.
If you really need very efficient look-up speeds at all cost, you'll need to do two things:
Work around the fact that the class
is generated: Write an adapter class which
can wrap the generated class and
which implement equals() based
on those two fields (assuming they
are public). Don't forget to also
implement hashCode() (*)
Wrap each object with that adapter and
put it in a HashSet.
HashSet.contains() has constant
access time, i.e. O(1) instead of O(n).
Of course, building this HashSet still has a O(n) cost. You are only going to gain anything if the cost of building the HashSet is negligible compared to the total cost of all the contains() checks that you need to do. Trying to build a list without duplicates is such a case.
*
() Implementing hashCode() is best done by XOR'ing (^ operator) the hashCodes of the same fields you are using for the equals implementation (but multiply by 31 to reduce the chance of the XOR yielding 0)
You could use a Comparator with Java's built-in methods for sorting and binary search. Suppose you have a class like this, where a and b are the fields you want to use for sorting:
class Thing { String a, b, c, d; }
You would define your Comparator:
Comparator<Thing> comparator = new Comparator<Thing>() {
public int compare(Thing o1, Thing o2) {
if (o1.a.equals(o2.a)) {
return o1.b.compareTo(o2.b);
}
return o1.a.compareTo(o2.a);
}
};
Then sort your list:
Collections.sort(list, comparator);
And finally do the binary search:
int i = Collections.binarySearch(list, thingToFind, comparator);
Given your constraints, you're stuck with brute force search (or creating an index if the search will be repeated). Can you elaborate any on how the ArrayList is generated--perhaps there is some wiggle room there.
If all you're looking for is prettier code, consider using the Apache Commons Collections classes, in particular CollectionUtils.find(), for ready-made syntactic sugar:
ArrayList haystack = // ...
final Object needleField1 = // ...
final Object needleField2 = // ...
Object found = CollectionUtils.find(haystack, new Predicate() {
public boolean evaluate(Object input) {
return needleField1.equals(input.field1) &&
needleField2.equals(input.field2);
}
});
If the list is sorted, you can use a binary search. If not, then there is no better way.
If you're doing this a lot, it would almost certainly be worth your while to sort the list the first time. Since you can't modify the classes, you would have to use a Comparator to do the sorting and searching.
Even if the equals method were comparing those two fields, then logically, it would be just the same code as you doing it manually. OK, it might be "messy", but it's still the correct answer
If you are a user of my ForEach DSL, it can be done with a Detect query.
Foo foo = ...
Detect<Foo> query = Detect.from(list);
for (Detect<Foo> each: query)
each.yield = each.element.a == foo.a && each.element.b == foo.b;
return query.result();
Is there any better way than just looping through and manually comparing the two fields for each object and then breaking when found? That just seems so messy, looking for a better way.
If your concern is maintainability you could do what Fabian Steeg suggest ( that's what I would do ) although it probably isn't the "most efficient" ( because you have to sort the array first and then perform the binary search ) but certainly the cleanest and better option.
If you're really concerned with efficiency, you can create a custom List implementation that uses the field in your object as the hash and use a HashMap as storage. But probably this would be too much.
Then you have to change the place where you fill the data from ArrayList to YourCustomList.
Like:
List list = new ArrayList();
fillFromSoap( list );
To:
List list = new MyCustomSpecialList();
fillFromSoap( list );
The implementation would be something like the following:
class MyCustomSpecialList extends AbstractList {
private Map<Integer, YourObject> internalMap;
public boolean add( YourObject o ) {
internalMap.put( o.getThatFieldYouKnow(), o );
}
public boolean contains( YourObject o ) {
return internalMap.containsKey( o.getThatFieldYouKnow() );
}
}
Pretty much like a HashSet, the problem here is the HashSet relies on the good implementation of the hashCode method, which probably you don't have. Instead you use as the hash "that field you know" which is the one that makes one object equals to the other.
Of course implementing a List from the scratch lot more tricky than my snippet above, that's why I say the Fabian Steeg suggestion would be better and easier to implement ( although something like this would be more efficient )
Tell us what you did at the end.
Maybe a List isn't what you need.
Maybe a TreeSet would be a better container. You get O(log N) insertion and retrieval, and ordered iteration (but won't allow duplicates).
LinkedHashMap might be even better for your use case, check that out too.
Building a HashMap of these objects based on the field value as a key could be worthwhile from the performance perspective, e.g. populate Maps once and find objects very efficiently
If you need to search many time in the same list, it may pay off to build an index.
Iterate once through, and build a HashMap with the equals value you are looking for as the key and the appropriate node as the value. If you need all instead of anyone of a given equals value, then let the map have a value type of list and build the whole list in the initial iteration.
Please note that you should measure before doing this as the overhead of building the index may overshadow just traversing until the expected node is found.
There are three basic options:
1) If retrieval performance is paramount and it is practical to do so, use a form of hash table built once (and altered as/if the List changes).
2) If the List is conveniently sorted or it is practical to sort it and O(log n) retrieval is sufficient, sort and search.
3) If O(n) retrieval is fast enough or if it is impractical to manipulate/maintain the data structure or an alternate, iterate over the List.
Before writing code more complex than a simple iteration over the List, it is worth thinking through some questions.
Why is something different needed? (Time) performance? Elegance? Maintainability? Reuse? All of these are okay reasons, apart or together, but they influence the solution.
How much control do you have over the data structure in question? Can you influence how it is built? Managed later?
What is the life cycle of the data structure (and underlying objects)? Is it built up all at once and never changed, or highly dynamic? Can your code monitor (or even alter) its life cycle?
Are there other important constraints, such as memory footprint? Does information about duplicates matter? Etc.
I would say the simplest solution would be to wrap the object and delegate the contains call to a collection of the wrapped class. This is similar to the comparator but doesn't force you to sort the resulting collection, you can simply use ArrayList.contains().
public class Widget {
private String name;
private String desc;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
public abstract class EqualsHashcodeEnforcer<T> {
protected T wrapped;
public T getWrappedObject() {
return wrapped;
}
#Override
public boolean equals(Object obj) {
return equalsDelegate(obj);
}
#Override
public int hashCode() {
return hashCodeDelegate();
}
protected abstract boolean equalsDelegate(Object obj);
protected abstract int hashCodeDelegate();
}
public class WrappedWidget extends EqualsHashcodeEnforcer<Widget> {
#Override
protected boolean equalsDelegate(Object obj) {
if (obj == null) {
return false;
}
if (obj == getWrappedObject()) {
return true;
}
if (obj.getClass() != getWrappedObject().getClass()) {
return false;
}
Widget rhs = (Widget) obj;
return new EqualsBuilder().append(getWrappedObject().getName(),
rhs.getName()).append(getWrappedObject().getDesc(),
rhs.getDesc()).isEquals();
}
#Override
protected int hashCodeDelegate() {
return new HashCodeBuilder(121, 991).append(
getWrappedObject().getName()).append(
getWrappedObject().getDesc()).toHashCode();
}
}

Categories