Ⅰ. はじめに
この記事ではStream APIを利用したソートとLightweight-Stream-APIを利用したソートの2つを紹介します。
Java8で追加されたStream APIとComparatorを使ったソートはAndroid N (Android 7.0)以上でなければ動作しません。
Android N 以下の場合はlambdaで例外が発生しアプリが強制終了します。
Ⅱ. 使うライブラリ
Lightweight-Stream-API を使います。
Android 4.4.4で動作確認済みです。
略称はLSAだそうです。(ライブラリ作者がReadmeでLSAと書いている)
LSAはStream APIではできない書き方ができるので便利です。
例えば、以下のようにメソッドの評価結果でソートが可能です。
persons = persons
.sorted(theComparing(comparing(x -> x.getSomething(argSomething))))
.toList();
ラムダ式を使ったこの書き方はStream APIでも1つだけのソートであれば可能ですが、
複数キーでソートする場合は不可能です。
なんとも中途半端な作りですね・・・
// OK persons.sort(comparing(x -> x.name)); // OK persons.sort(comparing(x -> x.getName())); // NG persons.sort(comparing(x -> x.name).thenComparing(x -> x.age)); // NG persons.sort(comparing(x -> x.getName()).thenComparing(x -> x.getAge()));
また、ixJavaなど他のライブラリもありましたが、複数キーでソートするにはLSAが最適でした。
(ixJavaはそもそも複数キーソートに対応していない)
Ⅲ. プログラム
import java.util.ArrayList; import java.util.List; public class Main { static class Person { public Person(String name, Integer age){ this.name = name; this.age = age; } private String name; public String getName() { return name; } private Integer age; public Integer getAge() { return age; } } public static void main(String[] args) { List<Person> persons = new ArrayList<>(); persons.add(new Person("a", 1)); persons.add(new Person("b", 4)); persons.add(new Person("b", 2)); persons.add(new Person("c", 3)); // Stream API // Android 7.0未満では動きません // import static java.util.Comparator.*; // persons.sort(comparing(Person::getName, reverseOrder()).thenComparing(Person::getAge)); // Lightweight-Stream-API // Android 4.4.4で動作確認済み // import static com.annimon.stream.ComparatorCompat.*; persons = Stream.of(persons) .sorted(thenComparing(comparing(x -> x.name, reverseOrder()), comparing(x -> x.age))) .toList(); // または //persons = Stream.of(persons) // .sorted(thenComparing(comparing(Person::getName, reverseOrder()), comparing(Person::getAge))) // .toList(); for(Person p : persons) { System.out.println(p.name + p.age); } } }
Ⅳ. 出力結果
c3 b2 b4 a1