Using Comparable to compare generic variables
Option 1.Use a Comparator
public class Cmp<K extends Comparable<K>, V> implements Comparator<Pair<K, V>> {
@Override
public int compare(Pair<K, V> o1, Pair<K, V> o2) {
return o1.k.compareTo(o2.k);
}
}
public class Utils {
public static <K extends Comparable<K>, V> Collection<Pair<K, V>> sortPairCollection(
Collection<Pair<K, V>> col) {
ArrayList<Pair<K, V>> list = new ArrayList<>();
Collections.sort(list, new Cmp<>());
return list;
}
}
Option 2.
Implement Comparable
public class Pair<K extends Comparable<K>, V> implements Comparable<Pair<K, V>> {
private K k;
private V v;
@Override
public int compareTo(Pair<K, V> o) {
return k.compareTo(o.k);
}
}
public class Utils {
public static <K extends Comparable<K>, V> Collection<Pair<K, V>> sortPairCollection(Collection<Pair<K, V>> col) {
ArrayList<Pair<K, V>> list = new ArrayList<>();
Collections.sort(list);
return list;
}
}
Or just
public class Utils {
public static <K extends Comparable<K>, V> Collection<Pair<K, V>> sortPairCollection(Collection<Pair<K, V>> col) {
ArrayList<Pair<K, V>> list = new ArrayList<>();
Collections.sort(list, (p, o) -> p.k.compareTo(o.k));
return list;
}
}
You don't have do create an instance for your static method btw. just invoke
Utils.sortPairCollection(list);
Compare generic types from a collection to the same type java
but if I type
<E extends Comparable>
in my Box.count method then i cant pass the arguments.
The reason why you can't pass the arguments is because Box
does not implement Comparable
.
What you should do instead is add the generic constraint in the Box
class:
class Box<T extends Comparable<T>> { ... }
Also, your count
method is a bit too generic. It will probably make more sense if compeer
's type is changed to Box<T>
and list
to List<Box<T>>
.
The method signature now looks like this:
public static <T extends Comparable<T>> int count(List<Box<T>> list, Box<T> compeer) {
And you can implement the method like this:
return (int)list.stream().
filter(x -> x.name.compareTo(compeer.name) < 0).count();
Comparing generic types using Comparable and Comparator
Thanks to the combined efforts of Chrylis, Catalin Pol, and Louis Wasserman, I learned I needed to correct my class to:
public class SortedValueStore<K, V extends Comparable<? super V>> implements PairStore187<K, V>, Iterable<K>, {
I no longer needed to write my own compareTo() method.
This did the trick. I'm relatively new to java so it took me a while to get what everyone was saying, but everyone was persistent with their efforts. Thanks to all for the help!
Java how to compare two generic type parameters
The < and > operators can only be used with primitive types, and the Number
class does not implement Comparable
itself, so you can't use compareTo.
However if you add Comparable<T>
as a type bound:
public class MyList<T extends Number & Comparable<T>> {
...
}
then you can use the compareTo
method:
public T largest() {
boolean onFirstObj = true;
T largestVal = null;
for (T t : list) {
if (onFirstObj) {
largestVal = t;
onFirstObj = false;
} else {
if (t.compareTo(largestVal) > 0) {
largestVal = t;
}
}
}
return largestVal;
}
compareTo() with generic type
Comparable<?>
means that you don't know what kind of Comparable
you're getting; you could be getting Comparable<Object>
, which doesn't work unless you explicitly override compareTo
for that instance of Object
.
The correct solution to this is to introduce a type parameter to the method such that the type you care about is bound to Comparable
.
private <T extends Comparable<T>> int compare(T[] arr, T item) {
return arr[0].compareTo(item);
}
The above will still work with a Comparable[]
, not a Comparable<?>[]
. Generics and arrays don't mix very well, so where you can, try to avoid combining the two.
If you want to avoid the unchecked warnings (which at this point can be safely ignored due to array covariance),then you would modify the signature of your methodArr
method to accept a similar bound.
<T extends Comparable<T>> void methodArr(final T[] arr, T item) {
// use the passed-in arr and item variables instead.
}
Implementing Comparable with a generic class
Item
(without any type argument) is a raw type, so:
We could pass any kind of
Item
toItem.compareTo
. For example, this would compile:new Item<String>().compareTo(new Item<Integer>())
The method
o.getT()
returnsComparable
instead ofT
, which causes the compilation error.In the example under the 1st point, after passing
Item<Integer>
toItem.compareTo
, we would then erroneously pass anInteger
toString.compareTo
. The compilation error prevents us from writing the code which does that.
I think you just need to remove the raw types:
public class Item<T extends Comparable<T>>
implements Comparable<Item<T>> {
...
@Override
public int compareTo(Item<T> o) {
return getT().compareTo(o.getT());
}
}
Comparing Generics that are comparable in Java
I know the data value will be a object-wrapped primitive or a String, so they are comparable.
Then you can tell the compiler about it:
public class TreeNode<T extends Comparable<T>>
If you do that, you will get access to the compareTo
method defined in Comparable
.
How to compare Strings & ints in Generic Using comparable C#
You have to specify that T
can be compared, the compiler can't know otherwise that type to expect. This way you can use CompareTo
for both your conditions:
public class QuickSort
{
public static int Partition<T>(T[] arr, int lo, int hi) where T : IComparable
{
int i = lo + 1;
int j = hi;
while (j > i)
{
while (arr[i].CompareTo(arr[lo]) == 0)
i++;
while (arr[j].CompareTo(arr[lo]) > 0) // means arr[j] > arr[lo]
j--;
Swap(ref arr[i], ref arr[j]);
}
Swap(ref arr[lo], ref arr[j]);
return j;
}
}
Also, I don't think you want to compare different QuickSort
instances, so I removed its interface.
Update: Based on Hawkmooon's comment, I took a second look at your method and thought its signature can be even simpler:
public static int Partition(IComparable[] arr, int lo, int hi)
{
int i = lo + 1;
int j = hi;
while (j > i)
{
while (arr[i].CompareTo(arr[lo]) == 0)
i++;
while (arr[j].CompareTo(arr[lo]) > 0)
j--;
Swap(ref arr[i], ref arr[j]);
}
Swap(ref arr[lo], ref arr[j]);
return j;
}
I think your code may be missing something. Just in case, here you have a full C# example of a working quicksort method.
Create a compareTo to a Generic Class that Implements Comparable
so to summarize the said above and to puzzle it together into a working code this is:
public class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
implements Comparable<DoubleKey<K, J>> {
private K key1;
private J key2;
public DoubleKey(K key1, J key2) {
this.key1 = key1;
this.key2 = key2;
}
public K getFirstKey() {
return this.key1;
}
public J getSecondKey() {
return this.key2;
}
public int compareTo(DoubleKey<K, J> that) {
int cmp = this.getFirstKey().compareTo(that.getFirstKey());
if (cmp == 0)
cmp = this.getSecondKey().compareTo(that.getSecondKey());
return cmp;
}
}
Related Topics
Handling the Null Value from a Resultset
Ora-00942 Sqlexception With Hibernate (Unable to Find a Table)
Subscript and Superscript a String in Android
How to Count Method Calls by Instance
How to Find Max Date in List<Object>
Object Cannot Be Converted to Integer Error
How to Generate a Unique and Short File Name in Java
Regex, Remove Whitespace and All Other Characters
Several Ports (8005, 8080, 8009) Required by Tomcat Server At Localhost Are Already in Use
Optimizing Multiple If-Else Condition in Java
How to Restart a Java Program Here
Regular Expression to Match a Backslash Followed by a Quote
How to Scroll to the Bottom of a Recyclerview? Scrolltoposition Doesn't Work
Delete Not Working in Hibernate/Spring Data
Spring Data JPA Saveall Not Doing Batch Insert
How to Return a List of Specific Type Instead of List<Object[]> in Hibernate