先日の投稿、入れ子リスト、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)); });