【Java】Longラッパークラスの使い方

Longラッパークラスは、数値をオブジェクトとして扱うための便利なクラスです。

この記事を読むことで、以下のことがわかります:

  1. Longラッパークラスとは何か
  2. プリミティブ型longとの違い
  3. Longラッパークラスの基本的な使い方
  4. 便利なメソッドの紹介
  5. 注意点と実践例

これらの知識を身につけることで、Javaプログラミングがもっと楽しく、効率的になります。

目次から探す

Longラッパークラスとは

Javaには、基本データ型(プリミティブ型)をオブジェクトとして扱うためのラッパークラスが用意されています。

Longラッパークラスは、その中でもプリミティブ型のlongをオブジェクトとして扱うためのクラスです。

これにより、プリミティブ型ではできない操作や、コレクションフレームワークでの利用が可能になります。

基本概念

Longラッパークラスは、java.langパッケージに含まれており、プリミティブ型のlongをオブジェクトとして扱うためのクラスです。

Longクラスは、数値の操作や変換、比較など、さまざまな便利なメソッドを提供しています。

Long longObject = Long.valueOf(12345L);

上記の例では、プリミティブ型のlong値12345LをLongオブジェクトに変換しています。

このように、Longクラスを使用することで、数値をオブジェクトとして扱うことができます。

プリミティブ型longとの違い

プリミティブ型のlongとLongラッパークラスの主な違いは以下の通りです:

  1. メモリ使用量:
  • プリミティブ型のlongは64ビットのメモリを使用します。
  • Longラッパークラスはオブジェクトであり、オブジェクトヘッダや参照のための追加メモリを使用します。
  1. 機能:
  • プリミティブ型のlongは基本的な数値操作しかできません。
  • Longラッパークラスは、数値の変換、比較、ビット操作など、さまざまなメソッドを提供します。
  1. nullの扱い:
  • プリミティブ型のlongはnullを扱うことができません。
  • Longラッパークラスはオブジェクトであるため、nullを扱うことができます。

なぜLongラッパークラスを使うのか

Longラッパークラスを使用する理由はいくつかあります:

  1. コレクションフレームワークの利用:
  • Javaのコレクションフレームワーク(例:ArrayList、HashMap)はオブジェクトを扱うため、プリミティブ型のlongを直接使用することはできません。

Longラッパークラスを使用することで、これらのコレクションに数値を格納することができます。

  1. メソッドの利用:
  • Longラッパークラスは、数値の変換や比較、ビット操作など、さまざまな便利なメソッドを提供しています。

これにより、数値操作が簡単になります。

  1. nullの扱い:
  • データベースや外部システムからのデータを扱う際に、null値が含まれることがあります。

プリミティブ型のlongはnullを扱うことができないため、Longラッパークラスを使用することで、null値を適切に処理することができます。

以上の理由から、LongラッパークラスはJavaプログラミングにおいて非常に便利であり、特定の状況での使用が推奨されます。

Longラッパークラスの基本的な使い方

Longオブジェクトの生成

コンストラクタを使った生成

Longラッパークラスのオブジェクトを生成する最も基本的な方法は、コンストラクタを使用することです。

以下のコード例では、Longオブジェクトを生成しています。

Long longObj1 = new Long(12345L);
Long longObj2 = new Long("12345");

この方法では、数値リテラルや文字列からLongオブジェクトを生成することができます。

ただし、newキーワードを使うと新しいオブジェクトが毎回生成されるため、メモリ効率が悪くなる可能性があります。

valueOfメソッドを使った生成

Longクラスには、valueOfメソッドも用意されています。

このメソッドは、指定された値に対応するLongオブジェクトを返します。

valueOfメソッドはキャッシュを利用するため、同じ値の場合は同じオブジェクトを返すことが多く、メモリ効率が良いです。

Long longObj1 = Long.valueOf(12345L);
Long longObj2 = Long.valueOf("12345");

この方法は、特に頻繁に同じ値を使う場合に有効です。

Longオブジェクトの比較

equalsメソッド

Longオブジェクトを比較するためには、equalsメソッドを使用します。

このメソッドは、オブジェクトの値が等しいかどうかを判定します。

Long longObj1 = Long.valueOf(12345L);
Long longObj2 = Long.valueOf(12345L);
if (longObj1.equals(longObj2)) {
    System.out.println("longObj1とlongObj2は等しいです。");
} else {
    System.out.println("longObj1とlongObj2は等しくありません。");
}

このコードは、longObj1longObj2が等しいことを確認し、longObj1とlongObj2は等しいです。と出力します。

compareToメソッド

compareToメソッドは、Longオブジェクト同士を比較するために使用されます。

このメソッドは、オブジェクトの値を比較し、以下のような結果を返します。

  • 0: 等しい
  • 正の値: 呼び出し元のオブジェクトが引数のオブジェクトより大きい
  • 負の値: 呼び出し元のオブジェクトが引数のオブジェクトより小さい
Long longObj1 = Long.valueOf(12345L);
Long longObj2 = Long.valueOf(67890L);
int result = longObj1.compareTo(longObj2);
if (result == 0) {
    System.out.println("longObj1とlongObj2は等しいです。");
} else if (result > 0) {
    System.out.println("longObj1はlongObj2より大きいです。");
} else {
    System.out.println("longObj1はlongObj2より小さいです。");
}

このコードは、longObj1longObj2より小さいことを確認し、longObj1はlongObj2より小さいです。と出力します。

Longオブジェクトの変換

longへの変換

Longオブジェクトをプリミティブ型のlongに変換するには、longValueメソッドを使用します。

Long longObj = Long.valueOf(12345L);
long primitiveLong = longObj.longValue();
System.out.println("プリミティブ型のlong値: " + primitiveLong);

このコードは、Longオブジェクトをプリミティブ型のlongに変換し、その値を出力します。

Stringへの変換

Longオブジェクトを文字列に変換するには、toStringメソッドを使用します。

Long longObj = Long.valueOf(12345L);
String longStr = longObj.toString();
System.out.println("文字列に変換されたLong値: " + longStr);

このコードは、Longオブジェクトを文字列に変換し、その値を出力します。

以上が、Longラッパークラスの基本的な使い方です。

これらの方法を理解することで、Longオブジェクトを効率的に操作することができます。

Longラッパークラスの便利なメソッド

JavaのLongラッパークラスには、数値変換や数学的操作、ビット操作など、さまざまな便利なメソッドが用意されています。

これらのメソッドを活用することで、より効率的にプログラムを作成することができます。

以下では、代表的なメソッドについて詳しく解説します。

数値変換メソッド

parseLongメソッド

parseLongメソッドは、文字列をlong型の数値に変換するためのメソッドです。

例えば、ユーザーから入力された数値を文字列として受け取り、それをlong型に変換する際に使用します。

public class ParseLongExample {
    public static void main(String[] args) {
        String numberStr = "12345";
        long number = Long.parseLong(numberStr);
        System.out.println("変換された数値: " + number);
    }
}

このコードを実行すると、以下のように出力されます。

変換された数値: 12345

toStringメソッド

toStringメソッドは、long型の数値を文字列に変換するためのメソッドです。

数値を文字列として表示したい場合や、文字列として他の処理に渡したい場合に使用します。

public class ToStringExample {
    public static void main(String[] args) {
        long number = 12345L;
        String numberStr = Long.toString(number);
        System.out.println("変換された文字列: " + numberStr);
    }
}

このコードを実行すると、以下のように出力されます。

変換された文字列: 12345

数学的操作メソッド

sumメソッド

sumメソッドは、2つのlong型の数値を加算するためのメソッドです。

簡単に2つの数値を足し合わせることができます。

public class SumExample {
    public static void main(String[] args) {
        long a = 10L;
        long b = 20L;
        long result = Long.sum(a, b);
        System.out.println("合計: " + result);
    }
}

このコードを実行すると、以下のように出力されます。

合計: 30

maxメソッド

maxメソッドは、2つのlong型の数値のうち、より大きい方を返すメソッドです。

2つの数値を比較して大きい方を取得したい場合に使用します。

public class MaxExample {
    public static void main(String[] args) {
        long a = 10L;
        long b = 20L;
        long result = Long.max(a, b);
        System.out.println("最大値: " + result);
    }
}

このコードを実行すると、以下のように出力されます。

最大値: 20

minメソッド

minメソッドは、2つのlong型の数値のうち、より小さい方を返すメソッドです。

2つの数値を比較して小さい方を取得したい場合に使用します。

public class MinExample {
    public static void main(String[] args) {
        long a = 10L;
        long b = 20L;
        long result = Long.min(a, b);
        System.out.println("最小値: " + result);
    }
}

このコードを実行すると、以下のように出力されます。

最小値: 10

ビット操作メソッド

bitCountメソッド

bitCountメソッドは、long型の数値の2進数表現における1のビットの数を返すメソッドです。

ビット操作を行う際に便利です。

public class BitCountExample {
    public static void main(String[] args) {
        long number = 15L; // 2進数で1111
        int bitCount = Long.bitCount(number);
        System.out.println("1のビットの数: " + bitCount);
    }
}

このコードを実行すると、以下のように出力されます。

1のビットの数: 4

highestOneBitメソッド

highestOneBitメソッドは、最も高い位置にある1のビットだけが立っているlong型の数値を返すメソッドです。

ビット操作を行う際に便利です。

public class HighestOneBitExample {
    public static void main(String[] args) {
        long number = 18L; // 2進数で10010
        long highestOneBit = Long.highestOneBit(number);
        System.out.println("最も高い位置にある1のビット: " + highestOneBit);
    }
}

このコードを実行すると、以下のように出力されます。

最も高い位置にある1のビット: 16

lowestOneBitメソッド

lowestOneBitメソッドは、最も低い位置にある1のビットだけが立っているlong型の数値を返すメソッドです。

ビット操作を行う際に便利です。

public class LowestOneBitExample {
    public static void main(String[] args) {
        long number = 18L; // 2進数で10010
        long lowestOneBit = Long.lowestOneBit(number);
        System.out.println("最も低い位置にある1のビット: " + lowestOneBit);
    }
}

このコードを実行すると、以下のように出力されます。

最も低い位置にある1のビット: 2

以上が、JavaのLongラッパークラスにおける便利なメソッドです。

これらのメソッドを活用することで、より効率的にプログラムを作成することができます。

Longラッパークラスの注意点

オートボクシングとアンボクシング

Javaでは、プリミティブ型とラッパークラスの間で自動的に変換が行われる機能があります。

これをオートボクシング(自動ボクシング)とアンボクシング(自動アンボクシング)と呼びます。

オートボクシング

プリミティブ型の値が自動的に対応するラッパークラスのオブジェクトに変換されることを指します。

例えば、long型の値がLongオブジェクトに変換される場合です。

Long longObj = 100L; // オートボクシング

アンボクシング

ラッパークラスのオブジェクトが自動的に対応するプリミティブ型の値に変換されることを指します。

例えば、Longオブジェクトがlong型の値に変換される場合です。

Long longObj = 100L;
long longValue = longObj; // アンボクシング

オートボクシングとアンボクシングは便利ですが、頻繁に行われるとパフォーマンスに影響を与える可能性があります。

特にループ内で大量のボクシングやアンボクシングが発生する場合は注意が必要です。

NullPointerExceptionのリスク

ラッパークラスはオブジェクトであるため、nullを許容します。

しかし、nullの状態でアンボクシングを行うとNullPointerExceptionが発生します。

Long longObj = null;
try {
    long longValue = longObj; // ここでNullPointerExceptionが発生
} catch (NullPointerException e) {
    System.out.println("NullPointerExceptionが発生しました");
}

このようなエラーを防ぐためには、アンボクシングを行う前にnullチェックを行うことが重要です。

Long longObj = null;
if (longObj != null) {
    long longValue = longObj;
} else {
    System.out.println("longObjはnullです");
}

パフォーマンスの考慮

ラッパークラスはプリミティブ型に比べてメモリを多く消費し、処理速度も遅くなります。

特に大量のデータを扱う場合や、頻繁にオブジェクトを生成・破棄する場合はパフォーマンスに影響を与える可能性があります。

パフォーマンスの改善策

  1. プリミティブ型の使用: 可能な限りプリミティブ型を使用することで、メモリ消費と処理速度を改善できます。
  2. キャッシュの利用: LongクラスのvalueOfメソッドは、-128から127までの値をキャッシュするため、頻繁に使用する値はキャッシュを利用することでパフォーマンスが向上します。
Long longObj1 = Long.valueOf(100); // キャッシュを利用
Long longObj2 = Long.valueOf(100); // 同じオブジェクトを参照
System.out.println(longObj1 == longObj2); // true
  1. 適切なデータ構造の選択: 大量の数値を扱う場合は、ArrayList<Long>よりもlong[]を使用する方が効率的です。
// 非推奨: メモリ消費が多い
ArrayList<Long> longList = new ArrayList<>();
for (long i = 0; i < 1000000; i++) {
    longList.add(i);
}
// 推奨: メモリ消費が少ない
long[] longArray = new long[1000000];
for (long i = 0; i < 1000000; i++) {
    longArray[(int)i] = i;
}

これらの注意点を理解し、適切に対処することで、Longラッパークラスを効果的に利用することができます。

実践例

基本的な使用例

まずは、Longラッパークラスの基本的な使用例を見てみましょう。

以下のコードは、Longオブジェクトの生成、比較、変換を行う基本的な例です。

public class LongExample {
    public static void main(String[] args) {
        // Longオブジェクトの生成
        Long longObj1 = new Long(100L);
        Long longObj2 = Long.valueOf(200L);
        // Longオブジェクトの比較
        boolean isEqual = longObj1.equals(longObj2);
        System.out.println("longObj1とlongObj2は等しいか: " + isEqual);
        // Longオブジェクトの変換
        long primitiveLong = longObj1.longValue();
        String longStr = longObj2.toString();
        System.out.println("primitiveLong: " + primitiveLong);
        System.out.println("longStr: " + longStr);
    }
}

このコードを実行すると、以下のような出力が得られます。

longObj1とlongObj2は等しいか: false
primitiveLong: 100
longStr: 200

コレクションとの併用例

次に、Longラッパークラスをコレクションと併用する例を見てみましょう。

以下のコードは、Longオブジェクトをリストに格納し、リスト内の要素を操作する例です。

import java.util.ArrayList;
import java.util.List;
public class LongCollectionExample {
    public static void main(String[] args) {
        // Longオブジェクトをリストに格納
        List<Long> longList = new ArrayList<>();
        longList.add(100L);
        longList.add(200L);
        longList.add(300L);
        // リスト内の要素を操作
        for (Long longObj : longList) {
            System.out.println("リストの要素: " + longObj);
        }
        // リスト内の要素を合計
        long sum = 0;
        for (Long longObj : longList) {
            sum += longObj;
        }
        System.out.println("リスト内の要素の合計: " + sum);
    }
}

このコードを実行すると、以下のような出力が得られます。

リストの要素: 100
リストの要素: 200
リストの要素: 300
リスト内の要素の合計: 600

スレッドセーフな操作例

最後に、Longラッパークラスを使ったスレッドセーフな操作の例を見てみましょう。

以下のコードは、複数のスレッドからLongオブジェクトを操作する例です。

import java.util.concurrent.atomic.AtomicLong;
public class LongThreadSafeExample {
    public static void main(String[] args) {
        // AtomicLongを使用してスレッドセーフな操作を実現
        AtomicLong atomicLong = new AtomicLong(0);
        // スレッドを作成してAtomicLongを操作
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                atomicLong.incrementAndGet();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                atomicLong.incrementAndGet();
            }
        });
        // スレッドを開始
        thread1.start();
        thread2.start();
        // スレッドの終了を待機
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 最終的な値を出力
        System.out.println("最終的な値: " + atomicLong.get());
    }
}

このコードを実行すると、以下のような出力が得られます。

最終的な値: 2000

この例では、AtomicLongクラスを使用してスレッドセーフな操作を実現しています。

AtomicLongは、内部的にスレッドセーフな操作を提供するため、複数のスレッドから同時にアクセスしてもデータの整合性が保たれます。

目次から探す