Java配列をソートするコードを書く
いざJavaでコードを書かなければならないという時、配列のソートを思い出すのに苦労することが多いので、備忘も兼ねて、ここにアウトプットしてしまいます。検討項目
- プリミティブ型な値を一つだけ持つ配列をソートする
- ArrayListに変換した後、SortやparallelSortを使う
- 複数のフィールドを持つ要素の単一のフィールドをソートキーにしてソートする
- SortやparallelSortを使う。Comparableを継承したフィールド定義クラスを作ったり、Comparatorクラスを実装した比較用クラスを作ったりする。lambdaも使える。
- 複数のフィールドを持つ要素について、複数のフィールドを優先度付きソートキーにしてソートする
- 上記同
プリミティブ型な値を一つしか持たない配列をソートする
arraysのソートを活用する
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int score[] = { 4, 2, 0, 3, 1 };
Arrays.sort(score);
for (int item : score) {
System.out.print(item + " ");
}
}
}
実行結果java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
0 1 2 3 4
複数のフィールドを持つ要素の単一のフィールドをソートキーにしてソートする
SortやparallelSortを使う。フィールドを持つComparableを継承したクラスも作る。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Player implements Comparable {
private int ranking;
private String name;
private int age;
public Player(int ranking, String name, int age) {
this.ranking = ranking;
this.name = name;
this.age = age;
}
@Override
public int compareTo(Player o) {
return (this.getRanking() - o.getRanking());
}
public int getRanking() {
return ranking;
}
@Override
public String toString() {
return ranking + " " + name;
}
}
public class Main {
public static void main(String[] args) {
List footballTeam = new ArrayList();
footballTeam.add(new Player(23, "たかし", 24));
footballTeam.add(new Player(16, "ひろし", 20));
footballTeam.add(new Player(18, "けんた", 22));
System.out.println("Before Sorting : " + footballTeam);
Collections.sort(footballTeam);
System.out.println("After Sorting : " + footballTeam);
}
}
import java.util.*;
class Player {
private int ranking;
private String name;
private int age;
public Player(int ranking, String name, int age) {
this.ranking = ranking;
this.name = name;
this.age = age;
}
public int getRanking() {
return ranking;
}
@Override
public String toString() {
return ranking + " " + name;
}
}
class PlayerRankingComparator implements Comparator<Player> {
public int compare(Player firstPlayer, Player secondPlayer) {
return (firstPlayer.getRanking() - secondPlayer.getRanking());
}
}
public class Main {
public static void main(String[] args) {
PlayerRankingComparator playerComparator = new PlayerRankingComparator();
List footballTeam = new ArrayList<Player>();
footballTeam.add(new Player(23, "たかし", 24));
footballTeam.add(new Player(16, "ひろし", 20));
footballTeam.add(new Player(16, "けんた", 22));
System.out.println("Before Sorting : " + footballTeam);
Collections.sort(footballTeam, playerComparator);
System.out.println("After Sorting : " + footballTeam);
}
}
ComparatorをLambdaにしてやれば、comparator継承クラスも必要なくなる。
import java.util.*;
class Player {
private int ranking;
private String name;
private int age;
public Player(int ranking, String name, int age) {
this.ranking = ranking;
this.name = name;
this.age = age;
}
public int getRanking() {
return ranking;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return age + " " + name;
}
}
public class Main {
public static void main(String[] args) {
Comparator<Player> byAge = (Player player1, Player player2) ->
player1.getAge() - player2.getAge();
//Comparator byAge = Comparator.comparingInt(Player::getAge); こちらでも可
List footballTeam = new ArrayList<Player>();
footballTeam.add(new Player(23, "たかし", 24));
footballTeam.add(new Player(16, "ひろし", 20));
footballTeam.add(new Player(18, "けんた", 22));
System.out.println("Before Sorting : " + footballTeam);
Collections.sort(footballTeam, byAge);
System.out.println("After Sorting : " + footballTeam);
}
}
複数のフィールドを持つ要素について、複数のフィールドを優先度付きソートキーにしてソートする
import java.util.*;
class Player implements Comparable<Player> {
private int ranking;
private String name;
private int age;
public Player(int ranking, String name, int age) {
this.ranking = ranking;
this.name = name;
this.age = age;
}
@Override
public int compareTo(Player o) {
if (this.getRanking() == o.getRanking()) {
return (this.getAge() - o.getAge());
} else {
return (this.getRanking() - o.getRanking());
}
}
public int getRanking() {
return ranking;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return ranking + " " + age + " " + name;
}
}
public class Main {
public static void main(String[] args) {
List<Player> footballTeam = new ArrayList<Player>();
footballTeam.add(new Player(23, "たかし", 24));
footballTeam.add(new Player(16, "ひろし", 22));
footballTeam.add(new Player(18, "けんた", 20));
footballTeam.add(new Player(16, "しげき", 18));
System.out.println("Before Sorting : " + footballTeam);
Collections.sort(footballTeam);
System.out.println("After Sorting : " + footballTeam);
}
}
結果java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
Before Sorting : [23 24 たかし, 16 22 ひろし, 18 20 けんた, 16 18 しげき]
After Sorting : [16 18 しげき, 16 22 ひろし, 18 20 けんた, 23 24 たかし]
Lambdaで記載してみる。import java.util.*;
class Player {
private int ranking;
private String name;
private int age;
public Player(int ranking, String name, int age) {
this.ranking = ranking;
this.name = name;
this.age = age;
}
public int getRanking() {
return ranking;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return ranking + " " + age + " " + name;
}
}
public class Main {
public static void main(String[] args) {
Comparator<Player> byRankAndAge = (
(Player player1, Player player2) ->
{
if (player1.getRanking() == player2.getRanking()) {
return (player1.getAge() - player2.getAge());
} else {
return (player1.getRanking() - player2.getRanking());
}
}
);
List<Player> footballTeam = new ArrayList<Player>();
footballTeam.add(new Player(23, "たかし", 24));
footballTeam.add(new Player(16, "ひろし", 22));
footballTeam.add(new Player(18, "けんた", 20));
footballTeam.add(new Player(16, "しげき", 18));
System.out.println("Before Sorting : " + footballTeam);
Collections.sort(footballTeam, byRankAndAge);
System.out.println("After Sorting : " + footballTeam);
}
}
Java学習ならこの本。第3版には、LambdaやStreamなど、Java8から追加されたイディオムもしっかり載っています。オススメ。