条件に合致した順にソートする。(Java)

JavaのComparingを使って、条件に合致した順にソートする場合。

複数の値でソートするのはわかるんだけれども、
特定の条件に合致した順にソートしたい場合は、こうすると良さそうです。

条件一致順にソート

list.sort(Comparator.comparing(o -> 条件1)
                .thenComparing(o -> 条件2)
                .thenComparing(o -> 条件3)
                .reversed());

条件には、bool式を返すものを書きます。

Boolean をcompareToすると、
Falseが優先されるため、
最後にreverseすることで、条件に合致した順にソートすることができます。

サンプルコード

enum Color {
    RED,
    GREEN,
    BLUE,
    YELLOW,
    WHITE,
    BLACK,
}

enum Shape {
    CIRCLE,
    TRIANGLE,
    SQUARE,
}

static class MyObject {
  String name;
  Color color;
  Shape shape;
  int size;

  @Override
  public String toString() {
    return "MyObject{" +
             "name='" + name + '\'' +
             ", color=" + color +
             ", shape=" + shape +
             ", size=" + size +
             '}';
  }
}

こんなクラスがあったとして、
特定の色、形状、サイズに一致したもの順にソートしてみる。

final Color[] COLORS = Color.values();
final Shape[] SHAPES = Shape.values();

// サンプルのリスト作成
Random rand = new Random();
List<MyObject> list = IntStream.rangeClosed(1, 20)
        .mapToObj(i -> {
            MyObject o = new MyObject();
            o.name = String.format("name-%02d", i);
            o.color = COLORS[rand.nextInt(COLORS.length)];
            o.shape = SHAPES[rand.nextInt(SHAPES.length)];
            o.size = 1 + rand.nextInt(100);
            return o;
        })
        .collect(Collectors.toList());

// 条件に合致した順にソート
list.sort(Comparator
        .comparing((MyObject o) -> Color.GREEN == o.color && 50 <= o.size)
        .thenComparing((MyObject o) -> Color.WHITE == o.color || Color.BLACK == o.color)
        .thenComparing((MyObject o) -> Shape.SQUARE == o.shape)
        .thenComparing((MyObject o) -> 50 <= o.size)
        .reversed());

// ダンプ
list.forEach(System.out::println);

出力結果

MyObject{name='name-01', color=GREEN, shape=SQUARE, size=84}
MyObject{name='name-12', color=GREEN, shape=CIRCLE, size=53}
MyObject{name='name-07', color=BLACK, shape=TRIANGLE, size=90}
MyObject{name='name-18', color=BLACK, shape=CIRCLE, size=97}
MyObject{name='name-02', color=WHITE, shape=CIRCLE, size=33}
MyObject{name='name-13', color=WHITE, shape=CIRCLE, size=32}
MyObject{name='name-17', color=WHITE, shape=TRIANGLE, size=38}
MyObject{name='name-05', color=BLUE, shape=SQUARE, size=67}
MyObject{name='name-09', color=BLUE, shape=SQUARE, size=59}
MyObject{name='name-04', color=GREEN, shape=SQUARE, size=40}
MyObject{name='name-06', color=RED, shape=CIRCLE, size=61}
MyObject{name='name-15', color=BLUE, shape=CIRCLE, size=54}
MyObject{name='name-19', color=YELLOW, shape=CIRCLE, size=87}
MyObject{name='name-20', color=YELLOW, shape=CIRCLE, size=56}
MyObject{name='name-03', color=YELLOW, shape=TRIANGLE, size=38}
MyObject{name='name-08', color=BLUE, shape=TRIANGLE, size=39}
MyObject{name='name-10', color=BLUE, shape=TRIANGLE, size=11}
MyObject{name='name-11', color=RED, shape=CIRCLE, size=34}
MyObject{name='name-14', color=YELLOW, shape=CIRCLE, size=16}
MyObject{name='name-16', color=YELLOW, shape=CIRCLE, size=20}

条件1 緑でサイズが50以上のもの
条件2 色が白か黒のもの
条件3 形が四角のもの
条件4 サイズが50以上のもの

条件に合致した順でソートがされています。

コメントを残す