#1458 sys::List API tweaks

vkuzkokov Thu 24 Mar 2011

I have 2 little changes to List:

  • hash was calculated in a way that lists differing by permutation had the same hashCode.
  • shuffle was non-uniform. You can check it with:
class Check {
  Void main() {
    res := Int[]:Int[:]
    (1..60000).each {
      idx := [1,2,3].shuffle.toImmutable;
      res[idx] = (res[idx] ?: 0) + 1
    }
    echo(res)
  }
}

Here's a patch

--- a/src/sys/java/fan/sys/List.java    Wed Mar 23 15:53:52 2011 -0400
+++ b/src/sys/java/fan/sys/List.java    Thu Mar 24 21:43:55 2011 +0600
@@ -298,6 +298,7 @@
     for (int i=0; i<size; ++i)
     {
       Object obj = values[i];
+      hash *= 31;
       if (obj != null) hash ^= hash(obj);
     }
     return hash;
@@ -966,7 +967,7 @@
     modify();
     for (int i=0; i<size; ++i)
     {
-      int randi = FanInt.random.nextInt(size);
+      int randi = FanInt.random.nextInt(i+1);
       Object temp = values[i];
       values[i] = values[randi];
       values[randi] = temp;

brian Thu 24 Mar 2011

thanks @vkuzkokov

I pushed those changes

I tweaked the list hashing to do what Java's AbstractList does which I think handles null better to ensure unique hash codes.

Login or Signup to reply.