How to compare values of generic types?
IComparable
doesn't overload the >=
operator. You should use
value.CompareTo(_minimumValue) >= 0
c# compare two generic values
You cannot use operators on generic types (except for foo == null which is special cased) unless you add where T : class to indicate it is a reference type (then foo == bar is legal)
Use EqualityComparer<T>
.Default to do it for you. This will not work on types which only supply an operator overload for == without also either:
- implement
IEquatable<T>
- overrides object.Equals()
In general implementing the == operator and not also doing at least one of these would be a very bad idea anyway so this is not likely to be an issue.
public bool IsDataChanged<T>()
{
T value1 = GetValue2;
T value2 = GetValue1();
return !EqualityComparer<T>.Default.Equals(value1 , value2);
}
If you do not restrict to IEquatable<T>
then the EqualityComparer default fallback may cause boxing when used with value types if they do not implement IEquatable<T>
(if you control the types which are being used this may not matter). I am assuming you were using =! for performance though so restricting to the Generic type will avoid accidental boxing via the Object.Equals(object) route.
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;
}
Java comparing generic types
You cannot overload operators in Java. The <
operator only applies to primitive (or numeric) types, not reference types. Since T
is a type variable that represents a reference type, you cannot use <
on variables of type T
. You have to use
if (item.compareTo(bn.item) < 0)
check the value returned and decide to do what you wish with it.
You don't know what the type T
will be but you know that it will be a type that implements Comparable
and therefore implements the compareTo()
method.
Comparing the values of two generic Numbers
A working (but brittle) solution is something like this:
class NumberComparator implements Comparator<Number> {
public int compare(Number a, Number b){
return new BigDecimal(a.toString()).compareTo(new BigDecimal(b.toString()));
}
}
It's still not great, though, since it counts on toString
returning a value parsable by BigDecimal
(which the standard Java Number
classes do, but which the Number
contract doesn't demand).
Edit, seven years later: As pointed out in the comments, there are (at least?) three special cases toString
can produce that you need to take into regard:
Infinity
, which is greater than everything, except itself to which it is equal-Infinity
, which is less than everything, except itself to which it is equalNaN
, which is extremely hairy/impossible to compare since all comparisons withNaN
result infalse
, including checking equality with itself.
Java-How do I compare generic types?
Your line insert((T)input.next());
doesn't make sense - input.next()
is a String
, but you're casting it to a T
even though T
isn't associated with a real type at this point. When constructing a Tree
a caller could, for instance, say new Tree<Integer>
making that line, in essence, insert((Integer)input.next());
, which is broken.
If your goal is for Tree
to always contain String
s, just remove the generic T
type from Tree
and just use String
. If you actually want to support arbitrary types you need to move the file-reading behavior out of the Tree
constructor (e.g. into a static method that returns a Tree<String>
).
For example:
public static Tree<String> readFromFile(Path file) throws FileNotFoundException {
try (Scanner input = new Scanner(file)) {
Tree<String> tree = new Tree<>();
while(input.hasNext()) {
tree.insert(input.next());
}
return tree;
}
}
Notice that I used Path
instead of File
, the try-with-resources pattern, and I don't suppress the exception, instead the caller (likely the main
method) should handle the exception properly (likely by reporting the file doesn't exist and exiting). Alternatively adding a catch block like so:
catch (IOException e) {
throw new RuntimeException("Could not open " + file, e);
}
would avoid forcing callers to handle the exception.
Now that we've cleaned up the Tree
type, your ordering question is likely simpler to answer. If you intend to order the elements as integers, convert the inputs to Integers, e.g.
public static Tree<Integer> readIntsFromFile(Path file) throws FileNotFoundException {
...
tree.insert(Integer.valueOf(input.next()));
...
}
This will order the tree based on the integer ordering, rather than the strings' lexicographic ordering. This is what I'd suggest you do. It's straightforward and does what you want.
If you really want a Tree<String>
but you want to order them as if they were integers you need a custom Comparator
, as you mention. You would then need to pass the Comparator
into the Tree
's constructor, and call comparator.compare(element, current.element)
where you currently call element.compareTo(current.element)
.
Related Topics
"Updatesourcetrigger=Propertychanged" Equivalent for a Windows Phone 7 Textbox
Matching Strings with Wildcard
How to Render a Razor View to a String in ASP.NET MVC 3
Why Was "Switchto" Removed from Async Ctp/Release
Are There Any Reasons to Use Private Properties in C#
Fast and Compact Object Serialization in .Net
How to Upload a File to a Document Library in Sharepoint
Why Is the "F" Required When Declaring Floats
Raise Event Thread Safely - Best Practice
How to Find Default Web Browser Using C#
How to Post Data Using Httpclient
An Attempt Was Made to Access a Socket in a Way Forbidden by Its Access Permissions
What Is the Best Scripting Language to Embed in a C# Desktop Application
How to Read Values from the Querystring with ASP.NET Core