Sunday, 10 May 2015

A kink in the API

In TreeSet Javadoc we have:

"Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface."

Lets see what this means in practice. In this example we have a Transaction object which has an id and amount instance variables. Transactions are considered equal if they have the same id.
   public class Transaction {
        private final String id;
        private final int amount;

        public Transaction(String id, int amount) {
            this.id = id;
            this.amount = amount;
        }

        public int getAmount() {
            return amount;
        }

        @Override
        public int hashCode() {
            return id != null ? id.hashCode() : 0;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || !(o instanceof Transaction)) return false;
            return id != null ? id.equals(((Transaction) o).id) : ((Transaction) o).id == null;
        }
    }
To compare Transaction objects based on the value of the amount so we introduce the relevant Comparator:
    public static class TransactionComparator implements Comparator {
        @Override
        public int compare(Transaction t1, Transaction t2) {
            return t1.getAmount() - t2.getAmount();
        }
    }
We now have everything in place for a small experiment:
TreeSet set = new TreeSet<>(new TransactionComparator());
Transaction t1 = new Transaction("T1", 100);
Transaction t2 = new Transaction("T2", 100);

System.out.printf("set did not already contain t1: %b\n", set.add(t1)); // set did not already contain t1: true
System.out.printf("set did not already contain t2: %b\n", set.add(t2)); // set did not already contain t2: false
System.out.printf("|set| = %d\n", set.size()); // |set| = 1
The quote at the top of the post means that as far as the TreeSet (and its friendss in SortedSet interface) is concerned, object equality is derived from compareTo() and not equal(), hence the two transactions t1 and t2 are equal. This is pretty unusual but one could argue that a fair warning was given.

Except that "The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface." doesn't really match:
System.out.printf("t1 is in set: %b\n", set.contains(t1)); // t1 is in set: true
System.out.printf("t2 is in set: %b\n", set.contains(t2)); // t2 is in set: true
And there we have it: |set| == 1 and set contains two elements. I think that it is more correct to say that "All bets are off regarding the behavior of a set if its ordering is inconsistent with equals"

-- Gist link 


Friday, 24 April 2015

Hash function benchmarks

Some hashing benchmarks using JMH. Code and results are on GitHub. SipHash and CRC-32C look good, some generate collisions on the test data though.


Monday, 13 April 2015

Setting up Java 8 Maven Ubuntu on Vagrant

Prerequsites:

  • VirtualBox is installed
  • Vagrant is installed
  • ssh and wget are available in PATH. Cygwin will do, e.g.: c:\cygwin\bin
  • We will use some of the Ubuntu setup scripts from ubuntu-equip - have a look.
You may want to download the Ubuntu Vagrant box so its available locally like so:
  E:\VagrantBoxes>wget http://files.vagrantup.com/precise64.box
Create a project directory, I have E:\vagrant_java. In the project directory create a file named Vagrantfile with the following content:
Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu.lts.64"
  config.vm.box_url = "file:///E:/VagrantBoxes/precise64.box"
  config.vm.provision :shell, inline: 'wget --no-check-certificate https://github.com/aglover/ubuntu-equip/raw/master/equip_java8.sh && bash equip_java8.sh'
  config.vm.provision :shell, inline: 'wget --no-check-certificate https://github.com/resilva87/ubuntu-equip/raw/master/equip_maven3.sh && bash equip_maven3.sh'
end
Bring up the vm, this may take a while as the relevant packages are provisioned from the net:
E:\vagrant_java>vagrant up
Lets have a look at what we ended up with
E:\vagrant_java>vagrant ssh
 vagrant@precise64:~$ java -version                                   
 java version "1.8.0_40"                                              
 Java(TM) SE Runtime Environment (build 1.8.0_40-b25)                 
 Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)                                                    

 vagrant@precise64:~$ readlink -f $(which java)
 /usr/lib/jvm/java-8-oracle/jre/bin/java

 vagrant@precise64:~$  /opt/maven/bin/mvn -version
 Apache Maven 3.2.5 (...)
 Maven home: /opt/maven
 Java version: 1.8.0_40, vendor: Oracle Corporation
 Java home: /usr/lib/jvm/java-8-oracle/jre
 Default locale: en_US, platform encoding: ISO-8859-1
 OS name: "linux", version: "3.2.0-23-generic", arch: "amd64", family: "unix"
All done :-)

Saturday, 28 February 2015

Need... more... time...

Machine Learning: https://www.coursera.org/learn/machine-learning/outline

Thursday, 5 February 2015

Slide

There is a technical presentation, just waiting to be written, in which this will be the first slide:



Dagen H, was the day, 3 September 1967, on which traffic in Sweden switched from driving on the left-hand side of the road to the right.


http://en.wikipedia.org/wiki/Dagen_H

Friday, 30 January 2015

ThreadLocal for thread saferty


Some code I saw recently that is really a kind of concurrency pattern in Java

Problems and Constraints 

There is an implementation of an interface that is not thread safe. You would like to use it in a multi threaded scenario without modifying the interface.

Example:
public interface Calculator {
    public int calculate(int input) ;
}

public class NonThreadSafeCalculatorImpl implements Calculator {
    public int calculate(int input) {
        //...
        // non thread safe logic here
        // ...
    }
}
An instance of NonThreadSafeCalculatorImplcan't be safely shared by multiple threads.

Solution
Implement the interface by delegating to a ThreadLocal that wraps the unsafe implementation

Example:
public class ThreadSafeCalculatorImpl implements Calculator {

    private static final ThreadLocal threadLocal = new ThreadLocal() {
        @Override
        protected Calculator initialValue() {
            return new NonThreadSafeCalculatorImpl();
        }
    };

    public int calculate(int input) {
        return threadLocal.get().calculate(input);
    }
}
An instance of ThreadSafeCalculatorImpl can be safely shared by multiple threads.

Monday, 26 January 2015

NIST Randomness Beacon

Perhaps it's odd but I find that someone is publishing a 512-bit, full-entropy random number every minute of every day, well, romantic. There is a nice write-up on Hackaday  and I wrote some code that uses the Bouncy Castle library  to validate the cryptographic promises made by NIST. The code is available here.