Java Snippet & Java Snippet Row Filter

I have two columns (both doubles)

and I create the statement for the Java Snippet Row Filter: 

return  col1 == col2;

This does not return the rows that are equal!  I have even used the round double node to make sure the values are really equal, but to no avail.

This phenomenon also occurs in the java snippet node:

if (col1 == col2){

d = "No Difference";}

else { d = "Different";}

out_xyz = d;

This works in eclipse, but not in KNIME.  Am I doing something wrong?

--Stephen

Interesting problem which can be explained with the node interna and auot-boxing in Java: the double is not a generic rather than a Object of type Double, calling col0 == col1 compares object references from col0 and col1. Two workarounds are possible, you either use col0.doubleValue() == col1.doubleValue() or col0.compareTo(col1) == 0.

Column comparator node could be used for this.

Could you please tell why col0 > col1 and col0 < col1 works, but not col0 == col1 if they are all objects?  I find this behavior very confusing.

--Stephen

This has to do with Java's unboxing of number objects. The variables are objects and not number, but Java is intelligent enough to use numeric comparators for < and >. But == is a valid operator for objects (reference identity) and therefore not automatically replaced by a numeric comparison. You could use col1.equals(col2) though (except if you have missing values in col1).

Thanks this makes it clear, but I still think KNIME should not treat my defined double variables as objects.  I would expect to seem the same behavior in KNIME as I find in eclipse, so I class this as a bug.

Thanks again

Stephen

 

But how would you represent missing values then? If you are using Number objects "null" is perfect for a missing value. If you use doubles, then what would be the equivalent of a missing entry?

OK I believe you it makes sense, but I would rather see an error for a missing entry, than not performing the equal (==) statement correctly.

--Stephen 

Well, it behaves correctly, exactly as using Number objects in Java does. Also, throwing an error if there is a missing value in the input doesn't make much sense in general. In many cases you want to treat them somehow, if only just ignore them. Believe me, there are good reasons why it's working as it is.

Hi,

I also face the same problem with equality when using Java Snippet. I find it very confusing that the Java Snippet nodes do not give same output for a code as excuted in Netbeans or Eclipse. 

I understand that there might be some reasons for this. But I expect seeing that 'val_1' == 'val_1' is true. Or at least if Knime evaluates 'val_1' == 'val_1'  to false then it should also evaluate 'val_2' == 'val_2'  to false, too. 

I have attached a figure demostrating this.

Another question related to this: in the column list the type ' i ' stands for int or Integer? 

Thanks in advance for the clarifications

Aziza

Actually it works similarly. Just try the following in Java:

new String("val1") == new String("val1")

Something similar happens behind the scenes. You should use the equals method when you are working with objects. (With integers you might face surprises when the absolute value is higher than 128 on Oracle JVM.)

Thanks for your prompt reply. I understand what you mean, but how do I know if  "i" stands for the  primitive int or for Integer? I assumed it stands for int. Ok, so if I use the class methods I guess I will be on the safe side. 

cheers

aziza

The node descriptions of all Java Snippet nodes state that numbers are represented as Java objects and not primitives.

Proabably a statically imported equals method would help to compare values for equality. Something which can handle the missing values:

/**
 * Somewhat safe equals method.
 *
 * @param left An object.
 * @param right Another object.
 * @param <T> Common type of both objects.
 * @return Both have the same values (assuming equals is properly defined on {@code left})?
 */
public static final <T> boolean equals(T left, T right) {
   if (left == null) {
     return right == null;
   }
   return right != null && left.equals(right);
}

Probably the T parameter is not so important, but might give further compile-time checks if specified. (For example this would fail to compile: equals<String>(myString, myInteger).) This has the advantage that it does not always compare NaNs as not equals (unlike ==). Do you think this would help reduce confusion?

Cheers, gabor

This is what java.util.Objects.equals does (sine Java 7) :-)

Hello all,

 need help regarding .I am using column filter and i  want to compare entries in a same columns downwords...and i want to store there results also in columns...

m =1

 

 

for(int i=1; i<=51; i++){
 for(int j=2; j<=52;j++){
  if (c_Startzelle(i)==c_Startzelle(j) && c_Zielzelle(i)==c_Zielzelle(j) && c_Wochentag(i)==c_Wochentag(j) && abs(c_UhrzeitBeginndesWeges(i)-c_UhrzeitBeginndesWeges(j))<100 && abs(c_UhrzeitEndedesWeges(I)-c_UhrzeitEndedesWeges(j)<100)) {
   
  out_Trip1(m) = ROWID(i);
  out_Trip2(m) = ROWID(j);
  out_AddTime(m) = c_UhrzeitBeginndesWeges(i)-c_UhrzeitBeginndesWeges(j)+c_UhrzeitEndedesWeges(i)-c_UhrzeitEndedesWeges(j);
  m=m+1;