Showing posts with label compare. Show all posts
Showing posts with label compare. Show all posts

Thursday, 27 May 2021

Java Comparison for Beginners

So, we all know about boxing and unboxing in Java, and the fact that we have "int" which is a primitive, and we have "Integer" which is an Object.

So, when comparing "int", we can use ==. When comparing "Integer" it's better to use .equals().

It may seem like it works, but this is only for small values that are cached in the JVM. Do not rely on that!

See the following example:

So, what happens when using different comparisons? let's explain the test below:

It works fine! Exactly as we would expect.

In short, according to the JLS1, first unboxing takes place, in order to be able to compare two primitives.

Then a widening primitive conversion2 takes place, in this case the int will be converted up to type long.

Now the comparison can take place.

References

[1] JLS Java 16 - 15.20. Relational Operators
https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.20
[2] JLS Java 16 - 5.6. Numeric Contexts
https://docs.oracle.com/javase/specs/jls/se16/html/jls-5.html#jls-5.6

Thursday, 28 April 2016

java.lang.IllegalArgumentException: Comparison method violates its general contract!

I got the error message in the title whilst using Flyway to run database scripts at work1.

I find it very satisfying that sorting methods in the JDK can detect if your comparer is not obeying the contract.

There are a lot of errors that cause the contract to be violated according to [2].

Here are the rules in short as described in [3]:
  • sign(compare(x,y)) == -sign(compare(y,x))
  • (compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0 (transitivity)
  • compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z))
Sounds like an excellent starting point for some good JUnit Tests.

References

[1] GitHub - Flyway - Issue 1249
https://github.com/flyway/flyway/issues/1249
[2] StackOverflow - “Comparison method violates its general contract!”
http://stackoverflow.com/questions/8327514/comparison-method-violates-its-general-contract
[3] Oracle Javadoc - Interface Comparator>T>
https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

Thursday, 25 June 2015

Comparing Files using Find and CMP

I needed to compare two directories containing binary files. Rsync was confusing, Diff only compares text-files.

I tried the following:
#!/bin/bash
# Example: ~/compare.sh FC30-3DA9
# where $1 is the directory name
# requirement: you are in one of the two parent dirs.
# the directories to compare must have the same name

find $1 -type f -exec sh -c '
  for f; do
    cmp "$f" /directory/of/mr/bear/"$f"
  done
' sh {} +
Seemed to work fine.

References

How to compare files in two folders using cmp?
http://www.unix.com/shell-programming-and-scripting/144821-how-compare-files-two-folders-using-cmp.html