简体   繁体   English

将比较器从 C# 移植到 Java

[英]Porting a comparator from C# to 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.我试图将这些小的数学调用从 C# 转换为 Java,只是想确保它们以相同的方式运行。 I added one additional call as it is not supported in Java.我添加了一个额外的调用,因为它在 Java 中不受支持。

Here is code in C#这是 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.注意 Math.Sign 没有被调用。

/**
* 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:这是在 Java 中使用两个 int 参数复制 C# 的“next”的方法:

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?从 C# 到 Java,这些方法是否等效?

Why not just use Java's compareTo?为什么不直接使用 Java 的 compareTo? This is assuming currentFitness is of type Integer and not the primitive type int.这是假设 currentFitness 是 Integer 类型而不是原始类型 int。 Otherwise you can just wrap it in Integer.否则,您可以将其包装在 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.不,因为 C# 中的 Math.Sign 返回三个值之一:如果值 < 0,则为 -1,如果值等于 0,则为 0,如果值大于 0,则为 1。它不会翻转符号乘以 -1,就像您在 Java 代码中所做的那样。

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.在 C# 中,CompareTo 函数期望 -1 表示调用它的对象小于传入的对象。由于您返回的是从值 2 中减去值 1 的符号,因此这将被切换。 I doubt this is what you want for your algorithm, given your Java code.鉴于您的 Java 代码,我怀疑这是否是您想要的算法。 Traditionally you would subtract value 2 from value 1 and use that sign.传统上,您会从值 1 中减去值 2 并使用该符号。

If your Java version of EquationGenome implements the Comparable interface, you'll be able to take advantage of many Java APIs .如果您的EquationGenome Java 版本实现了Comparable接口,您将能够利用许多Java API 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.按照惯例,您应该实现equals方法以与您的compareTo方法“一致” ,或者清楚地记录您的类以注意不一致。 If you implement equals , you should also implement hashCode for consistency too.如果你实现了equals ,你也应该实现hashCode以保持一致性。

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;产生随机数的方法没问题,只要你明白max是排除在外的; 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 .该方法从半开区间(min, max]生成随机数。如果要在范围中包含max ,请在diff添加一个。

I would write something like.我会写一些类似的东西。

Note: You have be very careful using Comparator with mutable fields as this can have undesirable side effects.注意:您必须非常小心地将 Comparator 与可变字段一起使用,因为这可能会产生不良副作用。

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM