class CollectionUtil {

  public static <T> Collector<T, ?, Integer> toOrderedHashCode() {
    // See https://stackoverflow.com/a/39396614 for mode detail
    return Collector.of(
        // Initial state: [0] - current hashcode, [1] - number of elements encountered
        () -> new int[2],
        // accumulator: single element added to hashcode
        (a, o) -> {
          a[0] = a[0] * 31 + Objects.hashCode(o);
          a[1]++;
        },
        // combiner: merge two hashcodes
        (a1, a2) -> {
          a1[0] = a1[0] * IntMath.pow(31, a2[1]) + a2[0];
          a1[1] += a2[1];
          return a1;
        },
        // finisher: collapse the state to a single int
        a -> IntMath.pow(31, a[1]) + a[0]);
  }

  private  CollectionUtil();

}