Porting a comparator from C# to Java - java

I am trying to convert these small math calls to Java from C# and just wanted to make sure that they operate the same way. I added one additional call as it is not supported in Java.
Here is code in C#
public override int CompareTo(object a)
{
EquationGenome Gene1 = this;
EquationGenome Gene2 = (EquationGenome)a;
return Math.Sign(Gene2.CurrentFitness - Gene1.CurrentFitness);
}
Java:
Notice the Math.Sign is not being called.
/**
* Compare to.
*/
public int compareTo(final Object a) {
final EquationGenome gene1 = this;
final EquationGenome gene2 = (EquationGenome) a;
return (int) ((-1.0) * (gene2.currentFitness - gene1.currentFitness));
}
And here is one to replicate C#'s 'next' with two int parameters in Java:
public static final int nextInt(final Random r, final int min, final int max) {
final int diff = max - min;
final int n = r.nextInt(diff);
return n + min;
}
Are these methods equivalent from C# to Java?

Why not just use Java's compareTo? This is assuming currentFitness is of type Integer and not the primitive type int. Otherwise you can just wrap it in Integer. This is not the most efficient method but it's more clear to me.
/**
* Compare to.
*/
public int compareTo(final Object a) {
final EquationGenome gene1 = this;
final EquationGenome gene2 = (EquationGenome) a;
return gene1.currentFitness.compareTo(gene2.currentFitness);
}

No, because Math.Sign in C# returns one of three values: -1 if the value is < 0, 0 if the value is equal to 0, and 1 if the value is greater than 0. It doesn't flip the sign by multiplying by -1 as you're doing in the Java code.
In C# the CompareTo function expects -1 to mean that the object on which it is called is less than the object being passed in. Since you're returning the sign of subtracting value 1 from value 2, this will be switched. I doubt this is what you want for your algorithm, given your Java code. Traditionally you would subtract value 2 from value 1 and use that sign.

If your Java version of EquationGenome implements the Comparable interface, you'll be able to take advantage of many Java APIs. This would alter your class to look like this:
final class EquationGenome
implements Comparable<EquationGenome>
{
...
public int compareTo(final EquationGenome gene2) ...
Then, what you are doing with the multiplication isn't clear. I assume the "natural order" is from most fit to least fit. Then I'd implement the comparison like this:
public int compareTo(final EquationGenome that) {
if (currentFitness == that.currentFitness) {
/* TODO: Add more tests if there are other properties that distinguish
* one EquationGenome from another (secondary sort keys). */
return 0;
} else
return (currentFitness > that.currentFitness) ? -1 : +1;
}
By convention, you should either implement the equals method to be "consistent" with your compareTo method, or clearly document your class to note the inconsistency. If you implement equals, you should also implement hashCode for consistency too.
public boolean equals(Object o) {
return o instanceof EquationGenome && compareTo((EquationGenome) o) == 0;
}
public int hashCode() {
return currentFitness;
}
The method for producing random numbers is alright, as long as you understand that max is excluded; the method generates random numbers from the half-open interval (min, max]. If you want to include max in the range, add one to diff.

I would write something like.
Note: You have be very careful using Comparator with mutable fields as this can have undesirable side effects.
public class EquationGenome implenents Comparable<EquationGenome> {
private final double currentFitness;
public EquationGenome(double currentFitness) {
this.currentFitness = currentFitness;
}
public int compareTo(EquationGenome eg) {
return Double.compareTo(currentFitness, eg.currentFitness);
}
}

Related

How to implement compareTo for any types of comparable objects

I don’t know how I can compare 2 comparable objects without some other variable which tells me which is larger. The question is: Create a class called Max that provides a single class method called max. max takes two arguments to objects that can be compared—that is, that implement the Java Comparable interface as shown above. It returns a reference to whichever is larger. If the two objects are equal, you should return the first. How Comparable is implemented is up to each class, and your method will be called on multiple different kinds of objects.
It gives the int compareTo (Object other) method in the interface but I’m having trouble finding a solution.
public class Max implements Comparable
{
public int compareTo(Object other)
{
}
public static Comparable max(Comparable first, Comparable second)
{
int fi = first.compareTo(second);
if(fi >0)
return first;
else if (fi<0)
return second;
return first;
}
}
java.lang.AssertionError: Class should not implement Comparable: expected [false] but found [true]
That is one of the errors. But also I need help writing the compareTo method.
I deleted my previous answer because I think, imho, you are over complicating this. Since the two arguments to max have implemented the Comparable<T> interface, all you have to do is call it as:
int ret = first.compareTo(second);
Then return first or second like you are doing based on the value of ret. That way you don't need to know anything about how it was implemented. Perhaps you could get some clarification from either your instructor or someone else who is working on this (I presume it is for an assignment).
It would be worthwhile for you to create some test classes which implement the interface. You can just make up some variable that represents size.
The keyword for your question is generics. You might want to do some research and read something about it. Take a look at the following example. I've implemented the class Max as a static class to keep it simple:
import java.time.LocalDate;
public class MyTestClass{
public static void main(String args[]) {
Integer i = 16;
Integer j = 15;
Integer m = Max.max(i, j);
System.out.println(m);
String k = "aaaa";
String n = "zzzz";
String s = Max.max(k, n);
System.out.println(s);
LocalDate d = LocalDate.now();
LocalDate e = LocalDate.now().plusDays(2);
LocalDate f = Max.max(d , e);
System.out.println(f);
}
static class Max{
public static <T extends Comparable> T max(T first, T second) {
if (first.compareTo(second) >= 0)
return first;
else
return second;
}
}
}
As you can see, there is a class Max with a single method max which accepts two objects, for example two integers, two strings or two date objects.
Since all these classes implement the comparable interface, you can use the max method for all object types. The compiler then decides during the runtime which comapreTo method to call, that is the compareTo of the class Integer, String, LocalDate or whatever.

Java: Why would someone widen and shorten a variable?

I'm taking a java course on lynda.com, and the course was explaining how to "cast" a variable if you want to shorten it.
WIDENING: Widening a variable is making it larger (e.g. int int1 = 4030; long long1 = int1;)
SHORTENING: Shortening a variable is making it smaller, and requires special syntax. (e.g. int int2 = 5024; short int3 = (short) int2;).
So, my question is, why would anyone want to do this? What's the advantage? If you know you'll need to widen a variable at some point, why don't you just start it as that variable? And why would you want to make your data type smaller if you're shortening? If you think that it could be used like this:
byte byte1 = 127;
byte1++;
if (byte1 > 127) {
short short1 = byte1;
}
(I know that this would give an error message, but you get the rough idea.)
You could do this, but why? It wouldn't save data, because it just adds more lines of code which would take up that data.
There are several reasons you might want to "shorten" a variable.
One is that an API or library you are working with requires data to be passed that is of a "shorter" type than the type you were using in your code.
Another is to save space. For example, if I only need to store a two digit number, using a long would be overkill as it would use much more system memory than is needed. This isn't something you normally need to worry too much about, but it could be an issue on certain systems or for very large projects.
There may be even more reasons; these are just a few examples.
You absolutely can't avoid this if you must pass a value received from a function that is out of your control into another function that is also out of your control:
package abc.def:
public class Foo {
public static long foo() { ... }
}
package xyz.qwerty:
public class Bar {
public static void bar(int n) { ... }
}
Your code:
import xyz.qwerty.Bar;
import abc.def.Foo;
...
Bar.bar((int)Foo.foo());
There may be intermediate variables temporarily holding the value received from Foo.foo() before it gets to Bar.bar() but that doesn't eliminate the inevitable need for converting from one type to another, which must happen somewhere in between.
Imagine you want to implement a min(...) method to calculate the minimum of two numbers. You could simply write:
public static double min(double lhs, double rhs) {
if (lhs >= rhs) {
return (lhs);
}
// else if (rhs > lhs) {
return (rhs);
// }
and through auto-casting (or what you refer to as "widening"), you could call this method with all primitives in Java. The downside, however, is that the result would always be double and if you want to save it as an int, you would have to downcast the result:
int i1 = 0;
int i2 = 100;
int max = (int) max(i1, i2);
It would be nice if the method returned an int iff. both parameters are int, a long iff. one parapeter is long and the other parameter is long or int and so on. This would result in the following code1:
public static int min(int lhs, int rhs) {
if (lhs >= rhs) {
return (lhs);
}
// else if (rhs > lhs) {
return (rhs);
// }
}
public static long min(long lhs, long rhs) {
if (lhs >= rhs) {
return (lhs);
}
// else if (rhs > lhs) {
return (rhs);
// }
}
public static float min(float lhs, float rhs) {
if (lhs >= rhs) {
return (lhs);
}
// else if (rhs > lhs) {
return (rhs);
// }
public static double min(double lhs, double rhs) {
if (lhs >= rhs) {
return (lhs);
}
// else if (rhs > lhs) {
return (rhs);
// }
}
Then you could write:
int i = 0;
long g = 1L;
float f = 2f;
double d = 3.0;
int intMax = max(i, i);
long longMax = max(i, g);
float floatMax = max(i, f);
double doubleMax = max(l, d);
Through the means of autocasting and method overloading, the most specific method will be called2,3.
1 You culd write those methods for byte, short and charas well. I would not recommend doing so since all arithemtic operations in Java return at least something of type int (e.g. byte + byte will return an int). This is due to the fact that the JVM does not know of the primitives boolean, char, byte and short, they are represented as int (see JLS §2.11.1).
2 The exact behaviour is specified in JLS, §15.12.2.5
3 This is actually the same mechanism used forjava.lang.Math's implementation of min(...), its implementation is slightly different.

Can you implement and override the list.sort() method to sort a list of rational numbers?

So I've been given the following problem:
Write a program that creates a List of Rationals and sorts them into increasing
order. Use appropriate methods from the Collections Framework classes to sort
the elements into increasing order.
I've created a 'Rational' class to represent rational numbers and I've also made the list of random Rational numbers. But I'm having trouble figuring out a way to implement a method of sorting the list. Here's samples of the code before I go on further:
public class Rational implements Comparable<Rational> {
private int num;
private int denom;
private int common;
// Default constructor initialises fields
public Rational() throws IllegalNumDenomException {
setNum(1);
setDenom(2);
}
// Constructor sets fields with given parameters
public Rational(int num, int denom) throws IllegalNumDenomException {
common = gcd(num,denom);
setNum(num/common);
setDenom(denom/common);
}
//Compares two rational numbers
public int compareTo(Rational rhs) {
int tempNumerator = this.getNum() * rhs.getDenom();
int tempNumeratorRhs = rhs.getNum() * this.getDenom();
//Compares rationalised numerators and returns a corresponding value
if (tempNumerator < tempNumeratorRhs) {
return -1;
} else if (tempNumerator > tempNumeratorRhs) {
return 1;
}
return 0;
}
// Overriden toString method
public String toString() {
return num + "/" + denom;
}
//Calculates the GCD of a fraction to simplify it later on
public int gcd(int x, int y) throws IllegalNumDenomException{
while(x != 1){ //Prevents infinite loop as everything is divisible by 1
if(x == y){
return x;
}
else if(x>y){
return gcd(x-y,y);
}
return gcd(x,y/x);
}
return 1;
}
public class RationalList {
public static void main(String[] args) throws IllegalNumDenomException {
List<Rational> rationals = new ArrayList<Rational>();
Random rand = new Random();
int n = rand.nextInt(50) + 1;
//Generates 9 random Rationals
for(int i = 1; i<10; i++){
rationals.add(new Rational(i,n));
n = rand.nextInt(50) + 1;
}
System.out.println("Original Order: " + rationals.toString());
sort(rationals);
System.out.println(rationals);
}
public static List<Rational> sort(List<Rational> rationals){
//Use compareTo method inside a loop until list is sorted
return rationals;
}
Sorry it's a bit long. So my thinking is creating a sort method and using the compareTo method to determine if a Rational is in the correct place, if not swap it. But then I'm unsure if you're able to even move elements around in a list like you can in an array. So I then thought maybe I need to implement the Collections.sort() method and override the sort method but I get to the same problem. Maybe I could use .toArray?
Can anyone shed some light on the way to do this please? Just hints would be useful.
Since you implemented comparable, Collections.sort(rationals) will work.
This is because Collections.sort will work on any List of Comparable things. It has already been designed to use the Comparable.compareTo() method that you have defined, and as long as your compareTo is implemented correctly it should sort your list.
What you are doing is roughly correct.
But then I'm unsure if you're able to even move elements around in a list like you can in an array.
Under the hood, the Collections.sort method can copy the elements of the list into an array, sort the array, and then rebuild the list from the sorted array. The actual behavior depends on the list implementation class.
In the main method of your application you should create a list of Rationals and then use the Collections.sort() method.
You should generate the random list of Rationals and then use Collection.sort(rationalsList);

Is there any Comparable not comparable to itself?

In the contract of Comparable, there's nothing forcing an object to be comparable to itself. It's just
strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y))
which implies that it's recommended for x.compareTo(x) not to throw. But it's possible to write a
class X implements Comparable<Y> {
...
}
where X and Y are two unrelated classes. I can't see what it could be good for, but in the Java 8 version of HashMap there's even a corresponding check.
Is it allowed to implement X implements Comparable<Y> with two unrelated classes?
Does it make any sense?
I guess the answers are yes and no, but it's just a guess
Comparable promotes a contract where comparisons should be consistent with equals, i.e. (a.compareTo(b) == 0) == a.equals(b). But it does not force you to do so and any weird contract can be enforced.
So you could create a:
class DumbInteger implements Comparable<DumbInteger> {
private final int i;
public DumbInteger(int i) { this.i = i; }
public int compareTo(DumbInteger di) { return 0; }
public boolean equals(Object other) { /* checks */ return other.i == this.i; }
}
And you could also create a:
class DumberInteger implements Comparable<String> {
private final int i;
public DumberInteger(int i) { this.i = i; }
public int compareTo(String s) { return 0; }
public boolean equals(Object other) { /* checks */ return other.i == this.i; }
public static void main(String[] args) {
System.out.println(new DumberInteger(0).compareTo("abc"));
}
}
but there is probably no point in doing that. In any case this is not specific to Java 8 as the Comparable interface has been there since Java 2 and "generified" in Java 5.
But it is probably not a flaw in the Comparable interface per se, because I don't think there is a way in Java to create a generic interface I<T> that can only be implemented by classes that are subtypes of T.
I see I missed one part of the contract and also failed to see the reason why HashMap.comparableClassFor exists.
The contract says
(x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0
so whenever there's an X greater than a Y and a Y greater than an X, then the two instances of X must be comparable to each other. This doesn't leave much freedom:
Either one of the types is empty. This makes no sense at all.
Or all instances of X are smaller or equal to all instances of Y (or the other way round). This is slightly less nonsensical.
So, I'm concluding that it's possible, but makes no sense. The simplest example is
class X implements Comparable<Void> {
public int compareTo(Void v) {
return 43; // or throw or whatever, it doesn't matter
}
}
I guess that the reason for HashMap.comparableClassFor is to support different implementations of a common superclass like
abstract class AByteArray implements Comparable<AByteArray> {}
class SparseByteArray extends AByteArray {...}
class DenseByteArray extends AByteArray {...}
This seems to make sense and can be even consistent with equals.
Does it make any sense?
One issue of having two classes Comparable with each other, is because it tightly couples these classes together. This makes it difficult to re-use the class in another scenario.
Just tried it, it is possible to compare two objects with different classes.
Here is the full code.
https://gist.github.com/cevaris/11099129
X x = new X();
x.xTest = 10;
Y y = new Y();
y.yTest = 100;
System.out.println("x.compareTo(y) == -1: " + (x.compareTo(y) == -1)); //True
System.out.println("y.compareTo(x) == 1: " + (y.compareTo(x) == 1)); //True
Here is the Y implementation.
class Y implements Comparable<X> {
int yTest;
#Override
public int compareTo(X o) {
if(this.yTest < o.xTest) return -1;
if(this.yTest > o.xTest) return 1;
return 0;
}
}
Here is the X implementation.
class X implements Comparable<Y> {
int xTest;
#Override
public int compareTo(Y o) {
if(this.xTest < o.yTest) return -1;
if(this.xTest > o.yTest) return 1;
return 0;
}
}
Well, it can technically be done (as per #cevaris' answer) and can be understood when you have several ways of representing the same object, e.g. an object and its String representation. But it would only make sense if you could implement the same interface twice like:
public class CompInt implements Comparable<CompInt>, Comparable<String> {
but that is forbidden in Java because of type erasure.

Speed profiler - abstract method or switch based on argument type

Problem details. I need to create a framework to perform various checks, like:
- is Date A between dates B and C?
- is Integer A greater than Integer B and smaller than Integer C?
etc.
So far, i am thinking of two possible implementations, detailed bellow.
Impl1 - using a single class to perform the checks, based on the check type.
import java.sql.Time;
import java.util.Date;
public class SearchManager {
public final static int SEARCH_TYPE_DATE = 0;
public final static int SEARCH_TYPE_INT = 1;
public final static int SEARCH_TYPE_STRING = 2;
public final static int SEARCH_TYPE_TIME = 3;
private final int searchType;
public SearchManager(int searchType) {
this.searchType = searchType;
}
public final boolean doCompare(Object minValue, Object maxValue, Object toBeCompared) {
switch (this.searchType) {
case SEARCH_TYPE_DATE: {
return compareDates((Date) minValue, (Date) maxValue, (Date) toBeCompared);
}
case SEARCH_TYPE_INT: {
return compareIntegers((Integer) minValue, (Integer) maxValue, (Integer) toBeCompared);
}
case SEARCH_TYPE_STRING: {
return compareStrings(String.valueOf(minValue), String.valueOf(maxValue), String.valueOf(toBeCompared));
}
case SEARCH_TYPE_TIME: {
return compareTimes((Time) minValue, (Time) maxValue, (Time) toBeCompared);
}
default:
return false;
}
}
private boolean compareDates(Date min, Date max, Date toBeCompared) {
boolean result = false;
// actual comparison
return result;
}
private boolean compareIntegers(Integer min, Integer max, Integer toBeCompared) {
boolean result = false;
// actual comparison
return result;
}
private boolean compareStrings(String min, String max, String toBeCompared) {
boolean result = false;
// actual comparison
return result;
}
private boolean compareTimes(Time min, Time max, Time toBeComparedDate) {
boolean result = false;
// actual comparison
return result;
}
}
Impl2 - Using an abstract class or interface, and having an implementation of the comparison method for each search type.
public abstract class AbstractSearch {
public final static int SEARCH_TYPE_DATE = 0;
public final static int SEARCH_TYPE_INT = 1;
public final static int SEARCH_TYPE_STRING = 2;
public final static int SEARCH_TYPE_TIME = 3;
public AbstractSearch() {
super(); //just for fun
}
protected abstract boolean doCompare(Object minValue, Object maxValue, Object toBeComparedValue);
}
Now, in this example, for X different search types, as you can imagine, X implementations of the AbstractSearch will be created.
Just imagine yourself that the class AbstractSearch from the 2nd implementation will need to perform additional tasks, other than the method doCompare(..) and that is why an interface is not my 1st candidate for this solution, and to write something like
public abstract class AbstractSearch implements Searcheable
would not help me a lot, since AbstractSearch or SearchManager will handle ALL the comparisons, and, if a new comparison type should be needed, an additional type/subclass implementation will be declared for corresponding super classes from Impl1 or Impl2.
My question is about which implementation is faster? And this is very important, since the comparison process will be called in loops containing thousands of elements.
Thank you for reading/answering my question.
EDIT1: Also, please have in mind the fact that minValue and maxValue will be extracted from the classes that extends the AbstractSearch, for the second example, or classes extending SearchManager, as for the 1st example. These implementation will actually be graphical components allowing the user to enter a minimum and a maximum value, and then, these value will be compared in a loop with some bean property, of objects displayed in a table.
EDIT2: I am doing some benchmarks, with dummy implementations (i just want to compare the method call time vs switch execution time). The results are..surprising:
Using AbstractSearch (500k loops): -0.047 seconds
Using SearchManager (500k loops): -0.422 seconds
Having these results, it is safe to assume that using inheritance is much faster than using a switch (or even worse an if-else test) ?
If you want to make this code as fast as possible, also try using overloaded methods like this:
public final static boolean doCompare(Date min, Date max, Date toCompare) {
// ...
}
public final static boolean doCompare(int min, int max, int toCompare) {
// ...
}
// ...and so on
At compile time, the compiler will generate a direct call to the appropriate method, based on the types which you pass. (If you are passing Object references which might point to an instance of any of the 4 types, this won't work.)
If the values which you are comparing are ints, passing them to a method which takes Object arguments will require boxing and unboxing, which adds overhead.
If performance is really important, I recommend you use static methods, since they are a bit faster in many Java implementations.
Also, rather than using compareTo, you can probably squeeze out a bit more performance by using your own inline code for the comparisons.
EDIT: You said in the edited question that min and max will actually be passed in by a subclass of SearchManager. In that case I would make SearchManager abstract, and put different implementations of doCompare in each subclass of SearchManager. What I said about static methods won't work in this case.
I would think that the best idea would be to combine both ideas (and make it more type safe) and take advantage of the fact that all the types that you provide in your example (Date, Time, String, and Integer) are Comparable
public final <A> boolean doCompare (Comparable<A> min, Comparable<A> max, A target)
{
return (min.compareTo(target) < 0) && (max.compareTo(target) > 0)
}
This is definitely a lot faster than the first implementation since it does not have to do any type checks (all checks will be done compile time) and is type safer and no slower than the second (while also being more flexible about type).
Is this just something that you can do with a comparison? (It looks like it.) Is this method essentially the same for all three implementations?
If so, just write
static <T extends Comparable<T>> boolean doCompare(T min, T max, T toCompare) {
// impl here
}
Fun question! Why don't you benchmark your two implementations?

Categories