I have a class PriorityList with the signature
Tree<Key extends Comparable<Key>, Value>(which is given, I can't modify). The elements Tree are inserted in some order, given the key (i.e. it considers the key's compareTo method).
Let's say I have Tree<Integer, Integer>. The default compareTo of integer considers ascending order. I would like to be able to somehow have Tree insert the elements in descending order, if I wanted to. I know I could probably write another class MyInteger which implements Comparable and has a compareTo on its own.
But is there another way? What I would really like is to be able to somehow tell the Tree how to order the values.
Second question: If I were able to modify Tree, how would one pass a comparator as argument? (keeping generic types-syntax in mind).
You've named the two ways to do it: pass in a comparator or have key be comparable. If the class doesn't let you pass in your own comparator, then you're stuck monkeying with the keys or creating your own subclass with the Comparable interface
The alternative code would look something like this.
public class Tree<K,V>{
public Tree( Comparator<K> cmp ) {...}
}
You wouldn't need to create a new class for reverse. you can use Collections.reverseOrder() to obtain a Comparator in reverse of a given one.
As for the second question, you will simply add a setter to your tree. Something like: setComparator(Comparator<Key> c) and then use that comparator for all the comparisons needed in your Tree.
Related
I have a question which appeared in a past paper (I'm revising for my exams) and I came across this word natural order which appears to be a keywords since it was written in bold on the paper. I've looked online at Natural Order but I couldn't find anything that related it to arraylist's like my question asks.
Please note, I do not need help solving the actual question, I just wish to understand what natural order means.
Question:
Write a Java static method called atLeast which takes an ArrayList of objects which
have natural order, an object of the element type of the ArrayList, and an integer n. A
call to the method should return true if at least n elements of the ArrayList are greater
than the element type object according to natural order, otherwise it should return false.
This likely means the objects in the List implement Comparable:
This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.
The declaration would look something like this:
static <T extends Comparable<? super T>>
boolean atLeast(List<T> list, T key, int n) {
...
}
Natural order means the default ordering for a particular type of collection. It actually depends upon the type of collection you are using. eg. if its a string collection, it will be sorted in alphabetical order, for numbers it follows numerical order.
Refer here for better understanding about natural ordering.
You can have a look at here for detail.
For objects to have a natural order they must implement the interface java.lang.Comparable. In other words, the objects must be comparable to determine their order. Here is how the Comparable interface looks:
public interface Comparable<T> {
int compareTo(T o);
}
This may seem like a dumb question, but I'd like to inquire about the best way to sort in reverse order a sortable structure (any kind, could be List) of a class MyClass that doesn't implement Comparable
First off, since MyClass doesn't implement Comparable and I want to sort it, I create a Comparator, something like this:
public class MyClassComparator implements Comparator<MyClass> {
#Override
public int compare(MyClass o1, MyClass o2) {
return (o1.getMyField()).compareTo(o2.getMyField());
}
}
This, of course, sorts MyClass objects according to the natural ordering of MyClass.MyField. But I want the reverse order.
I could of course just hardcode the reverse order in the compare(MyClass o1, MyClass o2) method. Something like
if (o1.getMyField()).compareTo(o2.getMyField()) > 0 return -1;
if (o1.getMyField()).compareTo(o2.getMyField()) < 0 return 1;
return 0;
Anoter alternative is leaving the code of MyClassComparator as I initially suggested, and using public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) from java.util.Collections to pass an instance of MyClassComparator and get a reverse comparator.
And a third alternative, that I think is wrong, could be sorting my LinkedList<MyClass> with the natural order Comparator and fetch the elements from last to first. LinkedList is a doubly linked list, so it should handle this perfectly. The problem is that I would always have to get a specific Iterator instead of just using a for each loop (minor) and, of course, that I initially wanted to sort ANY sortable structure, and I can't guarantee that it will be a doubly linked list or anything that handles well iterating through it in reverse order.
Considering that I'm quite certain (can't ever be 100% certain) that I won't be using the natural order of MyClass objects, just the reverse order, what would be the best way to obtain my reverse comparator?
Thank you.
Using a comparator would be the correct approach here in order to avoid the overhead of reversing an array. If the classes you are comparing implement Comparable you can just reverse the order of the comparison. obj2.compareTo(obj1). A way to visualize this is to think of the two objects as integers and compareTo as subtracting them.
I'm implementing my own java treeset. I think the underlying data structure is a BST and each node in the tree contains Object type data field. However, I stuck at how to compare two Object type data using natural ordering comparator. Is there a compareTo function that compares two objects and return the value of their natural ordering? I'm also thinking using hashcode as index key for each node and do comparison based on that. But it seems that distinct object might have same hashcode. Any advice is appreciated.
instead of BST consider RBT (Red black tree). look at here for more reference.
Now your MyTreeSet can take two kind of objects.
1. Object of java given wrapper class like String, Integer, Long etc Or
2. Object of your own written custom classes.
If your data structure needs to support case 1 one then order can be done easily based on compareTo method which is implemented by all java given wrapper class. You only need to call compareTo method to know which object is greater, equal or lesser than others based on it's return value 0, negative and positive value.
For case 2, that means your MyTreeSet needs to take object of custom classes also then you should implement Comparable interface to your custom classes and write your comparison algorithm there. For example if you want MyTreeSet should take Employee class object then implement Comparable method in Employee class and write implementation of compareTo method based on how emp1 will be compared to emp2. You may want to sort them based on their employee ids.
Hope it helps you.
i have two array
String a[]={"11","02","43","24","05","86","37","28","29","10"};
String b[]={"a","c","f","q","w","x","z","x","s","r"};
i want to sort array a[] in ascending order
and the result may like
String a[]={"02","05","10","11","24","28","29","37","43","86"};
String b[]={"c","w","r","a","q","x","s","z","f","x"};
how can i get result like above using java?
any sorting method available in java?
The easiest way would be to link the 2 pieces of data together in some way instead of having them in separate arrays. Many people have suggested a Map which would work great. Depending on exactly what you are trying to do, I would also consider a new class with 2 variables that implement Comparable. Comparable defines the natural ordering of a class when it is in a Collection (in this instance an array) if Collections.sort is not given a different Comparator to use. It would look something like this:
public class Data implements Comparable{
private String stringOne;
private String stringTwo;
#Override
public int compareTo(Object obj) {
stringOne.compareTo((String)obj);
}
Somewhere else call:
Collections.sort(locationOfDataCollection);
You could then create one Collection of Data and access the other String with a getter method. This implementation also would make it simple in future (see Strategy Design) if in some instances the natural order needed to be overridden with a new Comparator (e.g. sort by stringTwo).
Since you have 2 related sets of data, I would either link these via a Pair<String,String> type object and then into a List<Pair>, or put them into a Map<String,String>.
Perhaps the first solution is more intuitive e.g.
public class Pair implements Comparable<Pair> {
public String first;
public String second;
// equals/hashcode etc.
}
Once they're in a standard Java collection, numerous solutions exist for sorting these. e.g. in the above Pair I've implemented the Comparable<T> interface which the Collections sorting mechanisms will make use of.
There is no methods for directly doing this in Java. You have two options.
1) Define a Map<String, String>, put all the pairs in it (like ("11", "a")). Sort first array (or the keys of the map) and retrieve the elements of the map in that order.
2) Create an object that holds each par, create a List with it, and sort comparing only by the number (implement Comparable or create a Comparator).
One issue you'll need to be aware of is that Strings don't sort according to the same rules as integers. You are likely to be surprised by what you get if you leave the array by which you sort as String.
I have to implement a generic AVL tree as homework. It's defined as follows:
public class AVL<Key,Elem>;
The problem is that I assume that at some point, I'll have to compare keys to decide in which side of a node I allocate an element. For the purpose of this homework, Integers will be used as Keys.
Since no other restriction or information about that is given, I first thought of just asuming that Key will always be an Integer. However, that makes the generic "Key" superfluous, and I don't think that's what the teachers expect. So, I think that the best solution involves forcing that whatever that is passed as Key implements a Comparator, or something like that (I've really never worked with Comparator, just guessing), and then using that comparator to compare the Keys instead of using the ==,<,> and != operators. However, I have no idea on how to do it. Any hints?
Thanks in advance.
Try public class AVL<Key extends Comparable<Key>,Elem>; and use the compareTo() method which is required by the Comparable<T> interface and which is implemented by Integer.
The SortedMap and SortedSet implementations in the standard Java API either use a Comparator<Key> and call its compare(k1, k2) method, or assume the keys implement Comparable<Key>, and call k1.compareTo(k2). Most offer both, depending on which constructor is used. (EnumMap/EnumSet don't, as they support only the build-in ordering of the enum values by declaration order.)
The Comparable approach mandates that the keys are always sorted in the same way, and would be used for keys which have a canonical ordering (like integers), where you want to use this ordering.
The Comparator approach is more flexible, since you can use the same key objects for different maps where they are differently ordered, and you can use it for keys over which you have no control, or who don't have a canonical ordering (like List, trees/graphs, etc. You can also use it to sort strings keys by other criteria than the pure unicode value (e.g. Locale-based), using a Collator (this is a class implementing Comparator).
Both require a total order on your keys, but I suppose this is necessary for your AVL tree, too.
Here is a Comparator implementation which works on any comparable objects, so you could use it (maybe internally) as an adapter for the Comparable variant.
public static <X extends Comparable<X>> Comparator<X> makeComparator() {
return new Comparator<X>() {
public int compare(X left, X right) {
return left.compareTo(right);
}
};
}