##環境
このページにあるJavaは
1.8
で組んでいます。
##やろうとしていること
・List内のクラスを特定の順番で並び替える
・Streamを使ってみる
・Comparatorは使わない
※Comparatorを使ったやり方はページ下のコメント欄にswordoneさんから投稿いただいてますのでそちらを参照を!
##さっそくやってみる
まずはList内のクラス
private class Hoge {
private final String priority;
private final String name;
private Hoge(String priority, String name) {
this.priority = priority;
this.name = name;
}
}
こんな感じで。
面倒なのでgetter/setterなし。
###List生成クラス
private List<Hoge> createList() {
List<Hoge> list = new ArrayList<>();
list.add(new Hoge("ほげ1S", "S"));
list.add(new Hoge("ほげ2A", "A"));
list.add(new Hoge("ほげ3SS", "SS"));
list.add(new Hoge("ほげ4B", "B"));
list.add(new Hoge("ほげ5A", "A"));
list.add(new Hoge("ほげ6SS", "SS"));
return list;
}
サンプルだし、シンプルが1番w
ということでこんな感じ。
これをpriorityで
SS > S > A > B
の順に並べてみる
###実行してみる
public static void main(String[] args) {
List<Hoge> list = createList();
Stream.of(
list.stream().filter(o -> "SS".equals(o.priority)),
list.stream().filter(o -> "S".equals(o.priority)),
list.stream().filter(o -> "A".equals(o.priority)),
list.stream().filter(o -> "B".equals(o.priority))
).flatMap(s -> s).forEach(h -> System.out.println(h.name));
}
特筆するとしたらパッとみ無駄に見えるflatMapの使い方ぐらい?
これをここで使うわないとStream<Stream<Hoge>>になっちゃいます。
ここではStream<Hoge>にしたいのでこんな感じに。
※createListメソッドはstaticにしてます~
###実行結果
ほげ3SS
ほげ6SS
ほげ1S
ほげ2A
ほげ5A
ほげ4B
一応完成。
###いじる
Stream.of(
list.stream().filter(o -> "SS".equals(o.priority)),
list.stream().filter(o -> "S".equals(o.priority)),
list.stream().filter(o -> "A".equals(o.priority)),
list.stream().filter(o -> "B".equals(o.priority))
)
ここの部分をもうちょっと何とかしたい・・・
とりあえずPredicate型に置き換えてみる。
Predicate<Hoge> isSs = o -> "SS".equals(o.priority);
Predicate<Hoge> isS = o -> "S".equals(o.priority);
Predicate<Hoge> isA = o -> "A".equals(o.priority);
Predicate<Hoge> isB = o -> "B".equals(o.priority);
Stream.of(
list.stream().filter(isSs),
list.stream().filter(isS),
list.stream().filter(isA),
list.stream().filter(isB)
).flatMap(s -> s).forEach(h -> System.out.println(h.name));
微妙だ。
Predicate型が4個あるのはちょっとね。。
###さらにいじる
Predicate型の4つの関数はequalsの前の部分しか変わらないんだし、
このString部分だけ渡す感じにしてなんとかならんかな?
Stringを渡してPredicate型が返ってくるような感じで。
・・・ということでFunction型で囲ってみる。
Function<String, Predicate<Hoge>> priority = p -> new Predicate<Hoge>(){
@Override
public boolean test(Hoge t) {
return p.equals(t.priority);
}
};
Stream.of(
list.stream().filter(priority.apply("SS")),
list.stream().filter(priority.apply("S")),
list.stream().filter(priority.apply("A")),
list.stream().filter(priority.apply("B"))
).flatMap(s -> s).forEach(h -> System.out.println(h.name));
一旦、無名クラスで書いてみたけどだいぶマシになったかな。
無名クラスをラムダに変換。
Function<String, Predicate<Hoge>> priority = p -> t -> { return p.equals(t.priority); }
returnもいらないね。
とっちゃおう。
Function<String, Predicate<Hoge>> priority = p -> t -> p.equals(t.priority);
Stream.of(
list.stream().filter(priority.apply("SS")),
list.stream().filter(priority.apply("S")),
list.stream().filter(priority.apply("A")),
list.stream().filter(priority.apply("B"))
).flatMap(s -> s).forEach(h -> System.out.println(h.name));
こんな感じになりました。
もう少しなんとかなるかな?