Java Tips | 文字列処理:パディング

Java Java
スポンサーリンク

パディングは「長さをそろえて“機械が扱いやすい文字列”にする」技

業務システムでは、「桁数が決まっている文字列」がよく出てきます。
顧客番号は10桁、請求書番号は8桁、固定長ファイルの項目は右詰め・左詰めで何桁、といった世界です。

人間は「123」と「0000000123」が同じ番号だとすぐ分かりますが、
機械は「文字列として同じ長さ・同じ内容」になっていないと、きれいに扱えません。

そこで使うのが パディング(padding)――「足りない分を埋めて長さをそろえる」テクニックです。
左側に埋める(左パディング)、右側に埋める(右パディング)、スペースで埋める、ゼロで埋める、などのバリエーションがあります。


まずは「何を」「どちら側に」「何で」埋めるかを決める

パディングの3要素を意識する

パディングを考えるときは、必ず次の3つをセットで考えます。

何を:対象の文字列(例:数字、コード、名前など)
どちら側に:左側(先頭)か、右側(末尾)か
何で:埋める文字(例:'0'、スペース ' ''*' など)

例えば、よくあるパターンはこうです。

数字を左側にゼロで埋めて、固定桁にする(例:12300000123)。
名前を右側にスペースで埋めて、固定長ファイル用にする(例:山田山田)。

この3要素をユーティリティのメソッド名や引数にきちんと表現しておくと、
「このパディングは何のためのものか」が読みやすくなります。


左パディング(ゼロ埋め)の基本実装

数値IDや連番を「固定桁」にそろえる

まずは一番よく使う「左側ゼロ埋め」のユーティリティからいきます。
顧客番号や連番などを、8桁・10桁にそろえるときの定番です。

public final class Padding {

    private Padding() {}

    public static String leftPad(String text, int length, char padChar) {
        if (text == null) {
            text = "";
        }
        if (text.length() >= length) {
            return text;
        }
        StringBuilder sb = new StringBuilder(length);
        int padCount = length - text.length();
        for (int i = 0; i < padCount; i++) {
            sb.append(padChar);
        }
        sb.append(text);
        return sb.toString();
    }

    public static String leftPadZero(String text, int length) {
        return leftPad(text, length, '0');
    }
}
Java

使い方はこうなります。

System.out.println(Padding.leftPadZero("123", 8));   // 00000123
System.out.println(Padding.leftPadZero("99999", 8)); // 00099999
System.out.println(Padding.leftPadZero(null, 5));    // 00000
Java

ここで深掘りしたい重要ポイントは三つです。

一つ目は、「足りない分だけ padChar を先頭に追加している」ことです。
length - text.length() で必要なパディング数を計算し、その分だけ padCharStringBuilder に詰めています。

二つ目は、「すでに十分な長さがある場合は、そのまま返している」ことです。
text.length() >= length のときにそのまま返すことで、「長すぎる場合に切り捨てる」のではなく、「そのまま通す」という挙動になります。
ここは要件によって変わるので、「長すぎるときは例外にする」「右側を切る」など、プロジェクトのルールを決めておくとよいです。

三つ目は、「leftPadZero のような“用途が分かる薄いラッパー”を用意している」ことです。
leftPad(text, length, '0') と毎回書くより、leftPadZero と名前をつけておくほうが、
「これはゼロ埋めなんだな」と一目で分かります。


右パディング(スペース埋め)の基本実装

固定長ファイルや帳票で「右詰め・左詰め」を表現する

固定長ファイルや帳票では、「文字列を左詰めにして、右側をスペースで埋める」というパターンがよくあります。
例えば、10桁の項目に 山田 を入れるなら、"山田 " のように右側をスペースで埋めます。

public final class Padding {

    private Padding() {}

    public static String rightPad(String text, int length, char padChar) {
        if (text == null) {
            text = "";
        }
        if (text.length() >= length) {
            return text;
        }
        StringBuilder sb = new StringBuilder(length);
        sb.append(text);
        int padCount = length - text.length();
        for (int i = 0; i < padCount; i++) {
            sb.append(padChar);
        }
        return sb.toString();
    }

    public static String rightPadSpace(String text, int length) {
        return rightPad(text, length, ' ');
    }
}
Java

使い方はこうです。

System.out.println("[" + Padding.rightPadSpace("山田", 10) + "]");
// [山田        ]
System.out.println("[" + Padding.rightPadSpace(null, 5) + "]");
// [     ]
Java

ここでのポイントは、「左パディングと左右対称の実装にしている」ことです。
左パディングは「先に padChar を詰めてから text を追加」、
右パディングは「先に text を追加してから padChar を詰める」、
というだけの違いにしておくと、実装が頭の中で整理しやすくなります。


例題:固定長ファイルの1レコードを組み立てる

「項目ごとにパディングルールを決めておく」イメージ

固定長ファイルでは、1レコードが「決まった長さの項目」の連結でできています。
例えば、こんな仕様だとします。

顧客ID:8桁、左ゼロ埋め
氏名:20桁、右スペース埋め

これをユーティリティを使って組み立てると、こうなります。

public final class FixedRecordBuilder {

    private FixedRecordBuilder() {}

    public static String buildRecord(String customerId, String name) {
        String idPart = Padding.leftPadZero(customerId, 8);
        String namePart = Padding.rightPadSpace(name, 20);
        return idPart + namePart;
    }
}
Java

使い方はこうです。

String record = FixedRecordBuilder.buildRecord("123", "山田太郎");
System.out.println("[" + record + "]");
System.out.println("length=" + record.length());
// [00000123山田太郎              ]
// length=28
Java

ここで深掘りしたいのは、「“項目ごとのパディングルール”をコードとして明示している」ことです。
leftPadZero(customerId, 8) を見れば、「顧客IDは8桁ゼロ埋めなんだな」とすぐ分かります。
仕様書に書いてあるルールを、そのままユーティリティ呼び出しとして表現するイメージです。


例題:ログや画面で「桁をそろえて見やすくする」

数字やレベル名をそろえて、読みやすいログにする

ログやコンソール出力で、数字やラベルの桁をそろえると、視認性がぐっと上がります。

public final class LogFormat {

    private LogFormat() {}

    public static String formatIndex(int index) {
        // 3桁ゼロ埋め
        return Padding.leftPadZero(String.valueOf(index), 3);
    }

    public static String formatLevel(String level) {
        // 5文字右スペース埋め
        return Padding.rightPadSpace(level, 5);
    }
}
Java

使い方はこうです。

for (int i = 1; i <= 3; i++) {
    String idx = LogFormat.formatIndex(i);
    String level = LogFormat.formatLevel("INFO");
    System.out.println(idx + " " + level + " message " + i);
}
// 001 INFO  message 1
// 002 INFO  message 2
// 003 INFO  message 3
Java

ここでのポイントは、「パディングは“見た目の整形”にも使える」ということです。
固定長ファイルだけでなく、ログや画面表示でも「桁をそろえる」ことで、
人間が読みやすい出力を作ることができます。


例題:String.format や Formatter とどう使い分けるか

フォーマット指定子でもパディングはできる

Java には String.formatFormatter という仕組みがあり、
これを使ってもパディングができます。

String s1 = String.format("%08d", 123);   // 00000123
String s2 = String.format("%-10s", "山田"); // 山田        (右スペース埋め)
Java

%08d は「8桁、ゼロ埋めの整数」、%-10s は「左詰め、幅10、右スペース埋めの文字列」という意味です。

では、なぜわざわざ自前ユーティリティを書くのか。
理由は主に二つあります。

一つ目は、「フォーマット文字列が読みにくくなりがち」だからです。
"%08d""%-10s" に慣れていない人にとっては、意味が一瞬で分かりません。
leftPadZero(id, 8) のほうが、直感的に理解しやすい場面も多いです。

二つ目は、「パディングルールを“業務用の名前”で表現したい」からです。
buildRecord の中で String.format を直接使うより、
leftPadZero(customerId, 8) のように書いたほうが、「顧客IDは8桁ゼロ埋め」という仕様がコードに刻まれます。

String.format は便利な一方で、「フォーマット文字列が散らばる」と管理しづらくなるので、
業務ルールとして固定したいパディングは、ユーティリティメソッドにしておくのがおすすめです。


まとめ:パディングユーティリティで身につけたい感覚

パディングは、「人間には同じに見えるけれど、機械にとっては違う長さの文字列」を、
「同じ長さ・同じ形式」にそろえるための、業務システムの基礎テクニックです。

押さえておきたい感覚は、まず「何を・どちら側に・何で埋めるか」という3要素で考えること。
次に、「左パディングと右パディングを対称な実装にし、leftPadZerorightPadSpace のような“用途が分かる薄いラッパー”を用意する」こと。
そして、「固定長ファイル・帳票・ログ・画面など、文脈ごとのパディングルールをユーティリティとしてコードに刻み、仕様書とコードのあいだのズレを減らす」ことです。

タイトルとURLをコピーしました