配列のリストをソートする

先日の投稿、入れ子リスト、List<List<T>> をソートする - Oboe吹きプログラマの黙示録 と、
yipuran-core/NestedListComparator.java at master · yipuran/yipuran-core · GitHub
に続いて配列のリストをソートする場合もついでなので書いてみる。。

前回同様、配列要素の要素が持つ属性値によるソートである。

こちらも、
yipuran-core/Fieldgetter.java at master · yipuran/yipuran-core · GitHub
を使うのですが、以下のとおり。

import java.util.Comparator;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.IntStream;
import org.yipuran.util.Fieldgetter;
/**
 * ArrayListComparator
 */
public class ArrayListComparator{

   private int size;

   private ArrayListComparator(int size) {
      this.size = size;
   }

   public static ArrayListComparator of(int size) {
      return new ArrayListComparator(size);
   }

   @SuppressWarnings({ "rawtypes", "unchecked" })
   public <T> Comparator<T[]> build(String name){
      AtomicReference<Comparator<T[]>> cp
      = new AtomicReference<>(Comparator.comparing(t->(Comparable)Fieldgetter.of(e->name).apply(t[0])));
      IntStream.range(1, size).boxed().forEach(i->{
         cp.set(cp.get().thenComparing( Comparator.comparing(t->(Comparable) Fieldgetter.of(e->name).apply(t[i]))));
      });
      return cp.get();
   }

   @SuppressWarnings({ "rawtypes", "unchecked" })
   public <T> Comparator<T[]> build(String...names){
      if (names.length==1) return build(names[0]);
      Comparator<T[]> c = IntStream.range(0, names.length).boxed()
      .<Comparator<T[]>>map(i->Comparator.comparing(t->(Comparable)Fieldgetter.of(e->names[i]).apply(t[0])))
      .collect(()->Comparator.comparing(t->(Comparable)Fieldgetter.of(e->names[0]).apply(t[0]))
      ,(t, r)->r.thenComparing(t),(t, r)->{});
      AtomicReference<Comparator<T[]>> cp = new AtomicReference<>(c);

      IntStream.range(1, size).boxed().forEach(i->{
         IntStream.range(0, names.length).boxed().forEach(ni->{
            cp.set(cp.get().thenComparing( Comparator.comparing(t->(Comparable) Fieldgetter.of(e->names[ni]).apply(t[i]))));
         });
      });
      return cp.get();
   }

   @SuppressWarnings({ "rawtypes", "unchecked" })
   public <T> Comparator<T[]> build(String name, boolean reverse){
      AtomicReference<Comparator<T[]>> cp
      = new AtomicReference<>(Comparator.comparing(t->(Comparable)Fieldgetter.of(e->name).apply(t[0])));
      IntStream.range(1, size).boxed().forEach(i->{
         cp.set(cp.get().thenComparing( Comparator.comparing(t->(Comparable) Fieldgetter.of(e->name).apply(t[i]))));
      });
      if (reverse) cp.set(cp.get().reversed());
      return cp.get();
   }

   @SuppressWarnings({ "rawtypes", "unchecked" })
   public <T> Comparator<T[]> build(boolean reverse, String...names){
      if (names.length==1) return build(names[0]);
      Comparator<T[]> c = IntStream.range(0, names.length).boxed()
      .<Comparator<T[]>>map(i->Comparator.comparing(t->(Comparable)Fieldgetter.of(e->names[i]).apply(t[0])))
      .collect(()->Comparator.comparing(t->(Comparable)Fieldgetter.of(e->names[0]).apply(t[0]))
      ,(t, r)->r.thenComparing(t),(t, r)->{});
      AtomicReference<Comparator<T[]>> cp = new AtomicReference<>(c);

      IntStream.range(1, size).boxed().forEach(i->{
         IntStream.range(0, names.length).boxed().forEach(ni->{
            cp.set(cp.get().thenComparing( Comparator.comparing(t->(Comparable) Fieldgetter.of(e->names[ni]).apply(t[i]))));
         });
      });
      if (reverse) cp.set(cp.get().reversed());
      return cp.get();
   }
}


使用例、、

List<Item[]>  list = new ArrayList<>();

// list セット済

list.stream()
.sorted(ArrayListComparator.of(3).build("price"))
.forEach(a->{
   System.out.println(Arrays.toString(a));
});