LoginSignup
1
0

More than 5 years have passed since last update.

javaで特性関数的に文字列をソート

Posted at

やりたいこととしては"insert", "create", "drop"という文字列のリストがあるとき、自然順序ではなく、自分の好きな順序でソートしたい。具体的に言うと、"drop", "create", "insert"という順序にソートしたい。

この場合、集合の要素が限定されているため、SQLだと特性関数でcaseによるソートをすれば良い。同じようなことをjavaでもやりたい。

環境

java 1.8

コード

特性関数をMapで持つ

特性関数に相当するものをMapで持つ。keyが集合の要素でvalueがソート順序の整数。

Map<String, Integer> map = new HashMap<>();
map.put("drop", 1);
map.put("create", 2);
map.put("insert", 3);

List<String> list = Arrays.asList("insert", "create", "drop");
list.stream()
    .sorted((s1, s2) -> map.get(s1).compareTo(map.get(s2)))
    .forEach(System.out::println);

出力結果。

drop
create
insert

ファイル名を任意の順番でソート

これが必要になった状況としては、ある特定の順序でファイルをソートしたかった。たとえば、こんな感じのファイル群があるとする。

0001_create.sql
0001_drop.sql
0001_insert.sql
0002_create.sql
0002_drop.sql
0002_insert.sql

prefixの順番+suffixは前述の[drop -> create -> insert]、という順番でファイル一覧を取得したかった。

というわけでソースコード。

Map<String, Integer> map = new HashMap<>();
map.put("drop.sql", 1);
map.put("create.sql", 2);
map.put("insert.sql", 3);

Files.walk(Paths.get("files"))
    .filter(Files::isRegularFile)
    .sorted((p1, p2) -> {
        String[] sp1 = p1.getFileName().toString().split("_");
        String[] sp2 = p2.getFileName().toString().split("_");

        String pp1 = sp1[0] + map.get(sp1[1]);
        String pp2 = sp2[0] + map.get(sp2[1]);
        return pp1.compareTo(pp2);})
    .forEach(System.out::println);

出力結果。

files\0001_drop.sql
files\0001_create.sql
files\0001_insert.sql
files\0002_drop.sql
files\0002_create.sql
files\0002_insert.sql

といってもやることはそんな変わんない。ファイル名をセパレータで区切って、suffix部分を特性関数的なmapでソート順序の整数に変換。それをprefixの順番にくっつけると、"00013", "00012", "00011"という文字列になるので、あとはcompareToするだけ。

1
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0