LoginSignup
0
0

More than 3 years have passed since last update.

List内ソート、自分メモ用

Last updated at Posted at 2019-08-01

環境

このページにあるJavaは
1.8
で組んでいます。

やろうとしていること

・List内のクラスを特定の順番で並び替える
・Streamを使ってみる
・Comparatorは使わない

※Comparatorを使ったやり方はページ下のコメント欄にswordoneさんから投稿いただいてますのでそちらを参照を!

さっそくやってみる

まずはList内のクラス

Hoge.java
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));

こんな感じになりました。
もう少しなんとかなるかな?

0
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0