はじめに
座標クラス(x, y)のコレクションを、ソートしたいという状況になりました。
簡単にやる方法が無いか調べていたところ、Streamが使えそうだったので使用してみました。
コンソールに出すまでは順調だったのですが、ソート後にコレクションへ変換する時にはまりましたので、メモとして残しておきます。
実装
まずは、座標のクラスを作成します。
Point.java
public class Point{
int x;
int y;
Point(int x, int y){
this.x = x;
this.y = y;
}
//getter
public int getX(){return x;}
public int getY(){return y;}
}
続いて、座標クラスのコレクションをStreamを使用し、ソートします。
sorted
メソッドでソート内容を記載し、内部ではComparator
クラスを使用して比較しています。
xに続きyのソートを実行するため、thenComparing
メソッドを使用しています。
.collect(Collectors.toCollection(ArrayList::new)
最後にコレクションに変換するのですが、ここでかなりハマりました。
単純にtoArrayList
でいけると思っていたんですけどね。
Main.java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Stream;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args ) throws Exception {
ArrayList<Point> node = new ArrayList<Point>();
//座標をリストに追加
node.add(new Point(4,3));
node.add(new Point(2,2));
node.add(new Point(1,3));
node.add(new Point(1,1));
node.add(new Point(2,4));
node.add(new Point(2,1));
node.add(new Point(5,3));
//Sort前
System.out.println("===Before Sort===");
node.stream().forEach(nodes ->
System.out.println("node X:"+nodes.getX()+" Y:"+nodes.getY()));
//X:昇順、Y:昇順でソートし、ArrayListに格納
ArrayList<Point> nodeSort = node.stream()
.sorted(Comparator.comparingInt(Point::getX)
.thenComparing(Comparator.comparingInt(Point::getY)))
.collect(Collectors.toCollection(ArrayList::new));
//Sort後
System.out.println("===After Sort===");
nodeSort.stream().forEach(nodes ->
System.out.println("node X:"+nodes.getX()+" Y:"+nodes.getY()));
}
}
実行結果
===Before Sort===
node X:4 Y:3
node X:2 Y:2
node X:1 Y:3
node X:1 Y:1
node X:2 Y:4
node X:2 Y:1
node X:5 Y:3
===After Sort===
node X:1 Y:1
node X:1 Y:3
node X:2 Y:1
node X:2 Y:2
node X:2 Y:4
node X:4 Y:3
node X:5 Y:3
まとめ
今回は、クラスのコレクションをStreamを使用してソートする方法を記載しました。
他にも、条件抽出もできるようですので、Streamを使いこなせればかなり便利ですね。