お知らせ
2023.12.5(Tue)
目次
こんにちは。大城です。
本ブログでは、Java SE 8で追加されたStream APIについて、初心者向けに解説していきます。前回のブログでは、2重Listを1重に直すflatMapと重複を削除するdistinctについて説明しました。
中間処理3回目の今回は、ソートを行うsortedについて解説していきます。
IntegerやStringのような、java.lang.Comparableを実装しているクラスは簡単にソートすることができます。例をご覧ください。
public class Main { public static void main(String[] args) { List<Integer> intList = Arrays.asList(3, 1, 4, 5); System.out.println("------ ソートする前 ------"); intList.stream() .forEach(e -> System.out.println(e)); System.out.println("------ sorted()メソッドによってソートした結果 ------"); intList.stream() .sorted() // ソートの実施 .forEach(e -> System.out.println(e)); List<String> strList = Arrays.asList("Tokyo", "Chiba", "Saitama", "Kanagawa", "Gunma"); System.out.println("------ ソートする前 ------"); strList.stream() .forEach(e -> System.out.println(e)); System.out.println("------ sorted()メソッドによってソートした結果 ------"); strList.stream() .sorted() // ソートの実施 .forEach(e -> System.out.println(e)); } }
------ ソートする前 ------ 3 1 4 5 ------ sorted()メソッドによってソートした結果 ------ 1 3 4 5 ------ ソートする前 ------ Tokyo Chiba Saitama Kanagawa Gunma ------ sorted()メソッドによってソートした結果 ------ Chiba Gunma Kanagawa Saitama Tokyo
続いて、自作クラスなどのようなComparableを実装していないクラスをソートするする方法について解説します。この場合は、オブジェクトからComparableな値を取り出して比較するComparatorを生成して、sortedに引数として渡します。例をご覧ください。
class City { private String name; private int population; public City(String name, int population) { this.name = name; this.population = population; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } } public class Main { public static void main(String[] args) { List<City> cityList = new ArrayList<> (Arrays.asList( new City("Bunkyo-ku", 219724), new City("Taito-ku", 198073), new City("Chiyoda-ku", 58406), new City("Shinjuku-ku", 333560) )); System.out.println("------ ソートする前 ------"); cityList.stream() .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ nameで生成したComparatorでソートを実施 ------"); Comparator<City> nameComp = Comparator.comparing(e -> e.getName()); // CityクラスのプロパティnameによってComparatorを生成 cityList.stream() .sorted(nameComp) // nameで生成したComparatorでソートを実施 .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); } }
実行結果
------ ソートする前 ------ Bunkyo-ku :219724人 Taito-ku :198073人 Chiyoda-ku :58406人 Shinjuku-ku :333560人 ------ nameで生成したComparatorでソートを実施 ------ Bunkyo-ku :219724人 Chiyoda-ku :58406人 Shinjuku-ku :333560人 Taito-ku :198073人
class City { private String name; private int population; public City(String name, int population) { this.name = name; this.population = population; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } } public class Main { public static void main(String[] args) { List<City> cityList = new ArrayList<> (Arrays.asList( new City("Bunkyo-ku", 219724), new City("Taito-ku", 198073), new City("Chiyoda-ku", 58406), new City("Shinjuku-ku", 333560) )); System.out.println("------ ソートする前 ------"); cityList.stream() .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ nameによってソートした結果 ------"); cityList.stream() .sorted(Comparator.comparing(e -> e.getName())) .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ nameのlengthでソートした結果 ------"); cityList.stream() .sorted(Comparator.comparing(e -> e.getName().length())) .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ poplationでソートした結果 ------"); cityList.stream() .sorted(Comparator.comparing(e -> e.getPopulation())) .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); } }
------ ソートする前 ------ Bunkyo-ku :219724人 Taito-ku :198073人 Chiyoda-ku :58406人 Shinjuku-ku :333560人 ------ nameによってソートした結果 ------ Bunkyo-ku :219724人 Chiyoda-ku :58406人 Shinjuku-ku :333560人 Taito-ku :198073人 ------ nameのlengthでソートした結果 ------ Taito-ku :198073人 Bunkyo-ku :219724人 Chiyoda-ku :58406人 Shinjuku-ku :333560人 ------ poplationでソートした結果 ------ Chiyoda-ku :58406人 Taito-ku :198073人 Bunkyo-ku :219724人 Shinjuku-ku :333560人
上記では昇順ソートについて説明しましたが、最後に降順ソートのやり方も紹介します。
ComparableなオブジェクトはsortedにComparator.reverseOrder()を渡すことで降順ソートすることができます。例をご覧ください。
public class Main { public static void main(String[] args) { List<Integer> intList = Arrays.asList(3, 1, 4, 5); System.out.println("------ ソートする前 ------"); intList.stream() .forEach(e -> System.out.println(e)); System.out.println("------ sorted(Comparator.reverseOrder())によって降順ソートした結果 ------"); intList.stream() .sorted(Comparator.reverseOrder()) // ソートの実施 .forEach(e -> System.out.println(e)); List<String> strList = Arrays.asList("Tokyo", "Chiba", "Saitama", "Kanagawa", "Gunma"); System.out.println("------ ソートする前 ------"); strList.stream() .forEach(e -> System.out.println(e)); System.out.println("------ sorted(Comparator.reverseOrder())によって降順ソートした結果 ------"); strList.stream() .sorted(Comparator.reverseOrder()) // ソートの実施 .forEach(e -> System.out.println(e)); } }
------ ソートする前 ------ 3 1 4 5 ------ sorted(Comparator.reverseOrder())によって降順ソートした結果 ------ 5 4 3 1 ------ ソートする前 ------ Tokyo Chiba Saitama Kanagawa Gunma ------ sorted(Comparator.reverseOrder())によって降順ソートした結果 ------ Tokyo Saitama Kanagawa Gunma Chiba
Comparableが実装されていないオブジェクトは、Comparatorに.reversed()を指定します。例をご覧ください。
class City { private String name; private int population; public City(String name, int population) { this.name = name; this.population = population; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } } public class Main { public static void main(String[] args) { List<City> cityList = new ArrayList<> (Arrays.asList( new City("Bunkyo-ku", 219724), new City("Taito-ku", 198073), new City("Chiyoda-ku", 58406), new City("Shinjuku-ku", 333560) )); System.out.println("------ ソートする前 ------"); cityList.stream() .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ nameによって降順ソートした結果 ------"); cityList.stream() .sorted(Comparator.comparing(e -> ((City)e).getName()).reversed()) .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ nameのlengthで降順ソートした結果 ------"); cityList.stream() .sorted(Comparator.comparing(e -> ((City)e).getName().length()).reversed()) .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); System.out.println("------ poplationで降順ソートした結果 ------"); cityList.stream() .sorted(Comparator.comparing(e -> ((City)e).getPopulation()).reversed()) .forEach(e -> System.out.println(e.getName() + "\t:" + e.getPopulation() + "人")); } }
------ ソートする前 ------ Bunkyo-ku :219724人 Taito-ku :198073人 Chiyoda-ku :58406人 Shinjuku-ku :333560人 ------ nameによって降順ソートした結果 ------ Taito-ku :198073人 Shinjuku-ku :333560人 Chiyoda-ku :58406人 Bunkyo-ku :219724人 ------ nameのlengthで降順ソートした結果 ------ Shinjuku-ku :333560人 Chiyoda-ku :58406人 Bunkyo-ku :219724人 Taito-ku :198073人 ------ poplationで降順ソートした結果 ------ Shinjuku-ku :333560人 Bunkyo-ku :219724人 Taito-ku :198073人 Chiyoda-ku :58406人
いかがでしたか。
Streamのソートを行いたいときはsorted()を実行するだけで良く、非常にわかりやすいかと思います。次回では、Streamを用いた処理の略記やラムダ式・メソッド参照について解説していこうと思います。
それでは、また。
《関連記事》