LoginSignup
43
50

More than 3 years have passed since last update.

クラス java.util.Objectsのおさらいメモ

Last updated at Posted at 2017-08-25

概要

Java 1.7より導入されたjava.util.Objectsクラスのおさらいメモです。

環境

  • Windows 10 Professional
  • Oracle JDK 1.8.0_144
  • Oracle JDK 9.0.4
  • Oracle JDK 10.0.1

参考

Employeeクラス

この記事のサンプルコードでは下記のEmployeeクラスを使います。

Employee
public class Employee {
  private Long id;
  private String name;

  public Employee(Long id, String name) {
    this.id = id;
    this.name = name;
  }

  @Override
  public String toString() {
    return "Employee{" +
        "id=" + id +
        ", name='" + name + '\'' +
        '}';
  }

  // getter/setterは省略
}

Objects

compare

Employee emp1 = new Employee(100L, "rubytomato");
Employee emp2 = new Employee(200L, "garnetpepper");

System.out.println(Objects.compare(emp1, emp2, Comparator.comparing(Employee::getId)));
// → -1
System.out.println(Objects.compare(emp1, emp1, Comparator.comparing(Employee::getId)));
// → 0
System.out.println(Objects.compare(emp2, emp1, Comparator.comparing(Employee::getId)));
// → 1

第1引数の比較対象がnullの場合、NullPointerExceptionが発生しますが、nullを許容したい場合はComparator#nullsFirst(nullを最小値とする)またはComparator#nullsLast(nullを最大値とする)を指定します。

Employee emp1 = new Employee(null, "rubytomato");
Employee emp2 = new Employee(200L, "garnetpepper");

System.out.println(Objects.compare(emp1, emp2,
        Comparator.comparing(Employee::getId, Comparator.nullsLast(Comparator.naturalOrder()))));
// → 1

LocalDateTimeでの例です。

LocalDateTime d1 = LocalDateTime.of(2017, 8, 1, 0, 0, 0);
LocalDateTime d2 = LocalDateTime.of(2017, 8, 2, 0, 0, 0);

System.out.println(Objects.compare(d1, d2, LocalDateTime::compareTo));
// → -1
System.out.println(Objects.compare(d1, d1, LocalDateTime::compareTo));
// → 0
System.out.println(Objects.compare(d2, d1, LocalDateTime::compareTo));
// → 1

Integerでの例です。

Integer i1 = 100;
Integer i2 = 200;

System.out.println(Objects.compare(i1, i2, Integer::compareTo));
// → -1
System.out.println(Objects.compare(i1, i1, Integer::compareTo));
// → 0
System.out.println(Objects.compare(i2, i1, Integer::compareTo));
// → 1

// 自然順序付け
System.out.println(Objects.compare(i1, i2, Comparator.naturalOrder()));
// → -1
System.out.println(Objects.compare(i1, i1, Comparator.naturalOrder()));
// → 0
System.out.println(Objects.compare(i2, i1, Comparator.naturalOrder()));
// → 1

equals

Objects#equalsは第1引数のオブジェクトのequalsメソッドを使ってオブジェクト同士が等しいか判定を行います。どちらかのオブジェクトがnullの場合はfalseを返します。
第1引数のオブジェクトがnullの場合でもNullPointerExceptionは発生しません。
ただし、判定する両方のオブジェクトがnullの場合はtrueが返ります。

テストデータ
Employee emp1 = new Employee(100L, "rubytomato");
Employee emp1Null = null;
Employee emp2 = new Employee(200L, "garnetpepper");
Employee emp2Null = null;

Objects#equals

Objects#equalsを使った例です。nullの場合でもNullPointerExceptionはスローされません。

Objects
System.out.println(Objects.equals(emp1, emp2));
// → false

System.out.println(Objects.equals(emp1, emp2Null));
// → false

System.out.println(Objects.equals(emp1Null, emp2));
// NullPointerExceptionはスローされない
// → false

System.out.println(Objects.equals(emp1, emp1));
// → true

System.out.println(Objects.equals(emp1Null, emp2Null));
// null同士はtrueが返る
// → true

Object.equals

Object
System.out.println(emp1.equals(emp2));
// → false

System.out.println(emp1.equals(emp2Null));
// → false

System.out.println(emp1Null.equals(emp2));
// → NullPointerExceptionがスローされる

System.out.println(emp1.equals(emp1));
// → true

System.out.println(emp1Null.equals(emp2Null));
// → NullPointerExceptionがスローされる

deepEquals

使いどころがよくわかっていないのですが、配列同士を比較する際に使用するようです。
なお配列同士の比較を行うと内部的にArrays.deepEqualsへ処理を委譲しています。

テストデータ
Employee emp1 = new Employee(100L, "rubytomato");
Employee emp2 = new Employee(200L, "garnetpepper");
Employee emp3 = new Employee(300L, "rubytomato");

Employee[] emps1 = new Employee[]{emp1, emp2, emp3};
Employee[] emps2 = new Employee[]{emp1, emp2, emp3};

Objects#deepEquals

Objects
System.out.println(Objects.deepEquals(emps1, emps2));
// → true

emps1 = null;

System.out.println(Objects.deepEquals(emps1, emps2));
// NullPointerExceptionはスローされません
// → false

Object.equals

Object
System.out.println(emps1.equals(emps2));
// → false

emps1 = null;

System.out.println(emps1.equals(emps2));
// → NullPointerExceptionがスローされる

ちなみにコレクション同士だと両方ともtrueが返ります。

Employee emp1 = new Employee(100L, "rubytomato");
Employee emp2 = new Employee(200L, "garnetpepper");
Employee emp3 = new Employee(300L, "rubytomato");

List<Employee> emps1 = Arrays.asList(emp1, emp2, emp3);
List<Employee> emps2 = Arrays.asList(emp1, emp2, emp3);
System.out.println(Objects.deepEquals(emps1, emps2));
// → true

System.out.println(emps1.equals(emps2));
// → true

isNull

導入されたバージョン: 1.8

JavaDoc
APIの注:
このメソッドは、Predicate(filter(Objects::isNull))として使用するために存在します。

配列にnullが含まれているかチェックする例です

テストデータ
String[] params = {"p1", "p2", null, "p4", null, "p6"};
System.out.println(Arrays.stream(params).anyMatch(Objects::isNull));
// → true

System.out.println(Arrays.stream(params).filter(Objects::isNull).count());
// → 2

nonNull

導入されたバージョン: 1.8

JavaDoc
APIの注:
このメソッドは、Predicate(filter(Objects::nonNull))として使用するために存在します。

配列からnullの要素を除外する例です

テストデータ
String[] params = {"p1", "p2", null, "p4", null, "p6"};
Arrays.stream(params).filter(Objects::nonNull).forEach(System.out::println);
// → p1
// → p2
// → p4
// → p6

requireNonNull

導入されたバージョン: 1.8

引数に取るオブジェクトのnullチェックを行います。
引数がnullでなければ引数をそのまま返し、nullであればNullPointerExceptionをスローします。

Employee emp = null;

Objects.requireNonNull(emp);
// → java.lang.NullPointerException

第2引数にNullPointerExceptionをスローするときのエラーメッセージを指定することができます。

Employee emp = null;

Objects.requireNonNull(emp , "employee must not be null");
// メッセージ付きで例外がスローされる
// → java.lang.NullPointerException: employee is null

NullPointerExceptionをスローする前に何か実行する必要がある場合は、第2引数にラムダ式を指定します。

Employee emp = null;

Objects.requireNonNull(emp, () -> {

  // do something else.

  return "employee must not be null";
});
// メッセージ付きで例外がスローされる
// → java.lang.NullPointerException: employee is null 

toString

Objects#toStringを使用するとオブジェクトがnullかどうかを気にしなくてもよくなります。

Objects#toString

empがnullのときは"null"という文字列を返します。

Objects
Employee emp = new Employee(100L, "rubytomato");

System.out.println(Objects.toString(emp));
// → Employee{id=100, name='rubytomato'}

emp = null;

System.out.println(Objects.toString(emp));
// "null"という文字列が返ります
// → null

第2引数にnullの場合の代替文字列を指定することができます。

System.out.println(Objects.toString(emp, "employee is null"));
// → employee is null

Object.toString

Object
Employee emp = new Employee(100L, "rubytomato");

System.out.println(emp.toString());
// → Employee{id=100, name='rubytomato'}

emp = null;

System.out.println(emp.toString());
// → java.lang.NullPointerExceptionをスロー

Java 9で追加されたAPI

requireNonNullElse

Java 1.8で追加されたrequireNonNullにバリエーションが増えました。

public void demo(String obj1, String obj2) {
    String result = Objects.requireNonNullElse(obj1, obj2);
    System.out.println("result : " + result);
}
demo("obj1", "obj2");
// result : obj1

demo("obj1", null);
// result : obj1

demo(null, "obj2");
// result : obj2

// demo(null, null);
// java.lang.NullPointerException: defaultObj

requireNonNullElseGet

public void demo2(String obj, Supplier<String> supplier) {
    String result = Objects.requireNonNullElseGet(obj, supplier);
    System.out.println("result : " + result);
}
demo("obj1", () -> "obj2");
// result : obj1

demo(null, () -> "obj2");
// result : obj2

//demo(null, () -> null);
// java.lang.NullPointerException: supplier.get()

checkIndex

indexが、0(inclusive)からlength(exclusive)の範囲内かチェックします。

public void demo(int index, String[] fruits) {
    int result = Objects.checkIndex(index, fruits.length);
    System.out.println("result : " + result + " fruits : " + fruits[index]);
}
String[] fruits = {"apple", "banana", "cherry"};

demo(0, fruits);
// result : 0 fruits : apple

demo(1, fruits);
// result : 1 fruits : banana

demo(2, fruits);
// result : 2 fruits : cherry

demo(3, fruits);
// java.lang.IndexOutOfBoundsException: Index 3 out-of-bounds for length 3

checkFromToIndex

from(inclusive)からto(exclusive)のサブレンジが、0(inclusive)からlength(exclusive)の範囲内かチェックします。

public void demo(int from, int to, String[] fruits) {
    int result = Objects.checkFromToIndex(from, to, fruits.length);
    System.out.println("result : " + result + " fruits : " + fruits[from]);
}
String[] fruits = {"apple", "banana", "cherry"};

demo(0, 1, fruits);
// result : 0 fruits : apple

demo(1, 2, fruits);
// result : 1 fruits : banana

demo(2, 3, fruits);
// result : 2 fruits : cherry

demo(2, 4, fruits);
// java.lang.IndexOutOfBoundsException: Range [2, 4) out-of-bounds for length 3

checkFromIndexSize

from(inclusive)からfrom + size(exclusive)のサブレンジが、0(inclusive)からlength(exclusive)の範囲内かチェックします。

public void demo(int index, int size, String[] fruits) {
    int result = Objects.checkFromIndexSize(index, size, fruits.length);
    System.out.println("result : " + result + " fruits : " + fruits[index]);
}
String[] fruits = {"apple", "banana", "cherry"};

demo(0, 1, fruits);
// result : 0 fruits : apple

demo(1, 2, fruits);
// result : 1 fruits : banana

demo(2, 3, fruits);
// java.lang.IndexOutOfBoundsException: Range [2, 2 + 3) out-of-bounds for length 3

Preconditions

これらのstaticメソッドは、Preconditionsクラスへ処理を委譲しています。

Utility methods to check if state or arguments are correct.

Java 10で追加されたAPI

追加されたAPIはありません。

Java 11で追加されたAPI

追加されたAPIはありません。

Java 12で追加されたAPI

追加されたAPIはありません。

Java 13で追加されたAPI

追加されたAPIはありません。

Java 14で追加されたAPI

追加されたAPIはありません。

その他のおさらいメモ

43
50
0

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
43
50