6日目のゴール
6日目のテーマは
「ArrayList を“自分でゴリゴリ書くレベル”から、“標準ライブラリを使いこなすレベル”に引き上げること」 です。
ここまでであなたはすでに、
ArrayList は伸び縮みする箱であること
クラスのフィールドとして ArrayList を持てること
オブジェクトのリスト(Task や Book)を扱えること
検索・更新・削除・自前ソートが書けること
というところまで来ています。
6日目ではここから一歩進んで、
標準ライブラリの Collections.sort を使った並び替えComparator を使って「並び替えのルール」を外出しする
「表示の仕方」と「データの持ち方」を分けて考える
このあたりを、小さな「本の並び替え&ビュー切り替えアプリ」で固めていきます。
今日の題材:本のリストを「いろんな基準で並び替える」
まずはおなじみの Book クラス
6日目でも、題材はシンプルな本にします。
public class Book {
String title;
int price;
int pages;
Book(String title, int price, int pages) {
if (title == null || title.isEmpty()) {
throw new IllegalArgumentException("タイトルは必須です。");
}
if (price < 0) {
throw new IllegalArgumentException("価格は 0 以上で指定してください。");
}
if (pages <= 0) {
throw new IllegalArgumentException("ページ数は 1 以上で指定してください。");
}
this.title = title;
this.price = price;
this.pages = pages;
}
void show() {
System.out.println("タイトル: " + title + " / 価格: " + price + "円 / ページ数: " + pages);
}
}
Javaここまでは、これまでと同じです。
1冊分の情報をクラスで表現し、show で自己紹介できるようにしています。
BookList で ArrayList<Book> を管理する
import java.util.ArrayList;
public class BookList {
ArrayList<Book> books;
BookList() {
books = new ArrayList<>();
}
void add(Book book) {
if (book == null) {
System.out.println("null の本は追加できません。");
return;
}
books.add(book);
}
void showAll() {
System.out.println("=== 本一覧 ===");
if (books.isEmpty()) {
System.out.println("本はまだありません。");
return;
}
for (int i = 0; i < books.size(); i++) {
System.out.print((i + 1) + "冊目: ");
books.get(i).show();
}
}
}
Javaここまでは復習です。
6日目では、この books に対して「いろんな並び替え」をしていきます。
自前ソートから「標準ライブラリの sort」へ
昨日までの“自前ソート”を思い出す
5日目では、こんな感じで自分でソートを書きました。
void sortByPriceAscManual() {
for (int i = 0; i < books.size() - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < books.size(); j++) {
if (books.get(j).price < books.get(minIndex).price) {
minIndex = j;
}
}
if (minIndex != i) {
Book tmp = books.get(i);
books.set(i, books.get(minIndex));
books.set(minIndex, tmp);
}
}
}
Javaこれは「選択ソート」というアルゴリズムでした。
アルゴリズムの中身を知ることはとても大事ですが、
実際のアプリでは、毎回これを書く必要はありません。
Java には、
「並び替えは任せてくれ」
という標準ライブラリが用意されています。
Collections.sort と Comparator の基本
Collections.sort を使うための import
まずは、Collections.sort を使うために import を追加します。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
JavaCollections は「コレクション(List など)を扱う便利メソッド集」です。Comparator は「並び替えのルール」を表すインターフェースです。
価格の昇順で並び替える Comparator
まずは「価格の安い順」に並び替えるルールを作ります。
class PriceAscComparator implements Comparator<Book> {
@Override
public int compare(Book a, Book b) {
return Integer.compare(a.price, b.price);
}
}
Javaここが今日の重要ポイントのひとつです。
Comparator<Book> は「Book 同士を比べるルール」です。compare(a, b) は、
負の値を返す → a が b より“前”
0 を返す → a と b は同じ順番扱い
正の値を返す → a が b より“後ろ”
という約束になっています。
Integer.compare(a.price, b.price) は、
a.price < b.price → 負の値
a.price == b.price → 0
a.price > b.price → 正の値
を返してくれる便利メソッドです。
つまりこの Comparator は、
「価格が安い本ほど前に来るように並び替えるルール」
を表しています。
Collections.sort と組み合わせる
BookList に、標準ソートを使ったメソッドを追加します。
void sortByPriceAsc() {
Collections.sort(books, new PriceAscComparator());
}
Javaこれだけで、books の中身が「価格の安い順」に並び替えられます。
自前で二重ループを書いていたのが、
たった1行に置き換わりました。
並び替えの“ルール”を差し替える
タイトルの五十音順で並び替える Comparator
今度は「タイトルの五十音順」で並び替えてみます。
class TitleAscComparator implements Comparator<Book> {
@Override
public int compare(Book a, Book b) {
return a.title.compareTo(b.title);
}
}
JavaString#compareTo は、
a.title が b.title より辞書順で前 → 負の値
同じ → 0
後 → 正の値
を返します。
つまりこの Comparator は、
「タイトルが辞書順で早い本ほど前に来る」
というルールです。
BookList にメソッドを追加する
void sortByTitleAsc() {
Collections.sort(books, new TitleAscComparator());
}
Javaこれで、BookList は
sortByPriceAsc() → 価格の安い順sortByTitleAsc() → タイトルの五十音順
という2種類の並び替えができるようになりました。
Main から「ビューを切り替える」感覚を味わう
同じデータを、違う順番で眺める
Main を書いてみます。
public class Main {
public static void main(String[] args) {
BookList list = new BookList();
list.add(new Book("Java入門", 3000, 350));
list.add(new Book("アルゴリズム図鑑", 2500, 250));
list.add(new Book("オブジェクト指向設計", 4000, 500));
System.out.println("=== 追加した順番 ===");
list.showAll();
System.out.println("=== 価格の安い順 ===");
list.sortByPriceAsc();
list.showAll();
System.out.println("=== タイトルの五十音順 ===");
list.sortByTitleAsc();
list.showAll();
}
}
Javaここで感じてほしいのは、
中身の「本」は同じ
見せ方(順番)だけを変えている
ということです。
「データは1つ、ビューはいくつも」
という感覚は、アプリ開発でとても重要になります。
無名クラス・ラムダで“その場のルール”を書く
一回きりの並び替えなら、クラスを作らなくてもいい
さっきは PriceAscComparator というクラスを作りましたが、
「このメソッドの中でしか使わないルール」なら、
その場で書いてしまうこともできます。
void sortByPagesDesc() {
Collections.sort(books, new Comparator<Book>() {
@Override
public int compare(Book a, Book b) {
return Integer.compare(b.pages, a.pages); // ページ数の多い順
}
});
}
Javaここでは「無名クラス」という書き方を使っています。new Comparator<Book>() { ... } の中に、compare の実装を直接書いています。
さらに Java 8 以降なら、ラムダ式でこう書けます。
void sortByPagesDesc() {
Collections.sort(books, (a, b) -> Integer.compare(b.pages, a.pages));
}
Java(a, b) -> ... がラムダ式です。
「a と b を受け取って、これを返す関数」という意味になります。
今日の段階では、
Collections.sort(リスト, (a, b) -> 比較ロジック);
という形がある、と知っておけば十分です。
「データ」と「ビュー」を分けて考える
並び替え専用の“ビュー用リスト”を作る
5日目でやったように、
「元の順番はそのまま残しておきたい」
ということもあります。
その場合は、
「元データ」と「ビュー用のコピー」を分けます。
public class Main {
public static void main(String[] args) {
BookList original = new BookList();
original.add(new Book("Java入門", 3000, 350));
original.add(new Book("アルゴリズム図鑑", 2500, 250));
original.add(new Book("オブジェクト指向設計", 4000, 500));
System.out.println("=== 元データ(追加順) ===");
original.showAll();
ArrayList<Book> copy = new ArrayList<>(original.books);
Collections.sort(copy, new PriceAscComparator());
System.out.println("=== ビュー用(価格の安い順) ===");
for (int i = 0; i < copy.size(); i++) {
System.out.print((i + 1) + "冊目: ");
copy.get(i).show();
}
System.out.println("=== 元データが変わっていないか確認 ===");
original.showAll();
}
}
Javaここで大事なのは、
original.books と copy は別の ArrayListCollections.sort(copy, ...) は copy の順番だけを変える
元の original.books の順番はそのまま
という動きです。
「1つのデータを、複数のビューで眺める」
というのは、現実のアプリでよく出てくるパターンです。
6日目で絶対に押さえてほしい本質
今日いちばん大事なのは、
「ArrayList の並び替えを、“自前で頑張る”から“ルールを渡して任せる”に切り替える感覚」
を持てたかどうかです。
ArrayList 自体は「順番付きの可変長データ」
並び替えは Collections.sort に任せられるComparator で「並び替えのルール」を表現できる
ルールを差し替えるだけで、同じデータを違う順番で見られる
元データとビュー用のリストを分けることで、「元の順番」を守れる
ここまで来ると、
ArrayList は単なる「伸び縮みする配列」ではなく、
「アプリの中の“データの世界”を支える土台」
として見えてくるはずです。
もし余力があれば、
価格の高い順、ページ数の少ない順、
タイトルの長さ順、など
自分で好きな並び替えルールをいくつか書いてみてください。
「ルールを変えるだけで、同じデータが違う顔を見せる」
この感覚がつかめたら、6日目はかなりいい仕上がりです。

