LoginSignup
10
17

More than 5 years have passed since last update.

Java Collections Frameworkのおさらいメモ

Last updated at Posted at 2017-08-30

概要

Collections Frameworkのおさらいメモです。Java8のstreamで追加された部分を中心におさらいしましたので内容がだいぶ偏っています。

環境

  • Windows10 Professional
  • Oracle JDK 1.8.0_144
  • Oracle JDK 10.0.1

参考

この記事のサンプルコードでは、下記のclass,enumを使用しています。

サンプルコードで使用するclass
public class Employee {
  private Long id;
  private String name;

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

  // getter/setterは省略

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

}
サンプルコードで使用するenum
public enum DeepPurple {
  IanGillan("vocal"),
  SteveMorse("guitar"),
  RogerGlover("base"),
  IanPaice("drums"),
  DonAirey("keyboard");

  private String part;

  DeepPurple(String part) {
    this.part = part;
  }

  public String getPart() {
    return part;
  }
}

Collections

コレクションを操作するユーティリティークラスです。

コレクションに要素を追加する

第1引数に渡すコレクションに、第2引数で渡す任意の数の要素を追加します。

addAll
@SafeVarargs
public static <T> boolean addAll(Collection<? super T> c, T... elements)

Listに要素を追加する

List<String> lists = new ArrayList<>();
lists.add("rubytomato");

Collections.addAll(lists,
  "garnetpepper",
  "spinelginger",
  "rubellitebeets"
);

System.out.println(lists);
// → [rubytomato, garnetpepper, spinelginger, rubellitebeets]

Setに要素を追加する

Set<String> sets = new HashSet<>();
sets.add("rubytomato");

Collections.addAll(sets,
  "garnetpepper",
  "spinelginger",
  "rubellitebeets"
);

System.out.println(sets);
// → [rubytomato, spinelginger, rubellitebeet, garnetpepper]

Listをソートする

第1引数で渡すListを、第2引数で渡すコンパレータでソートします。

sort
public static <T> void sort(List<T> list, Comparator<? super T> c)

Integerをソートする

List<Integer> lists = Arrays.asList(5, 3, 1, 4, 2);

System.out.println(lists);
// → [5, 3, 1, 4, 2]

// Integer.compareToの結果でソート
Collections.sort(lists, Integer::compareTo);

System.out.println(lists);
// → [1, 2, 3, 4, 5]

Stringをソートする

List<String> lists = Arrays.asList("bbbb", "ddd", "aaaaa", "c", "ee");

System.out.println(lists);
// → [bbbb, ddd, aaaaa, c, ee]

// 文字列の自然順序でソート
Collections.sort(lists, Comparator.naturalOrder());

System.out.println(lists);
// → [aaaaa, bbbb, c, ddd, ee]

// 文字列の自然順序の逆順でソート
Collections.sort(lists, Comparator.reverseOrder());

System.out.println(lists);
// → [ee, ddd, c, bbbb, aaaaa]

// 文字列の長さでソート
Collections.sort(lists, Comparator.comparing(String::length));

System.out.println(lists);
// → [c, ee, ddd, bbbb, aaaaa]
Employee emp1 = new Employee(100L, "rubytomato");
Employee emp2 = new Employee(200L, "garnetpepper");
Employee emp3 = new Employee(300L, "spinelginger");
Employee emp4 = new Employee(400L, "rubellitebeets");

List<Employee> lists = Arrays.asList(emp4, emp3, emp2, emp1);

System.out.println(lists);
// → [Employee{id=400, name='rubellitebeets'}, Employee{id=300, name='spinelginger'}, Employee{id=200, name='garnetpepper'}, Employee{id=100, name='rubytomato'}]

// Employee.idで数値的にソート
Collections.sort(lists, Comparator.comparing(Employee::getId));

System.out.println(lists);
// → [Employee{id=100, name='rubytomato'}, Employee{id=200, name='garnetpepper'}, Employee{id=300, name='spinelginger'}, Employee{id=400, name='rubellitebeets'}]

ListにもsortメソッドがあるのでCollectionsを使わずに、下記のようにすることができます。

lists.sort(Comparator.comparing(Employee::getId));

空の不変なコレクション、マップを返す

List

Listの実装クラスはjava.util.Collections.EmptyListで、要素数が変わる操作(add、addAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

emptyList
public static final <T> List<T> emptyList()
List<String> lists = Collections.emptyList();

Set

Setの実装クラスはjava.util.Collections.EmptySetで、要素数が変わる操作(add、addAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

emptySet
public static final <T> Set<T> emptySet()
Set<String> sets = Collections.emptySet();

Map

Mapの実装クラスはjava.util.Collections.EmptyMapで、要素数が変わる操作(put、putAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

emptyMap
public static final <K,V> Map<K,V> emptyMap()
Map<Long, String> maps = Collections.emptyMap();

要素を1つだけ持つ不変なコレクション、マップを返す

List

Listの実装クラスはjava.util.Collections.SingletonListで、引数に渡した要素だけを持つListを返します。要素数の変更(add、addAll、remove、clearメソッド等)や、要素の変更(set、replaceAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

singletonList
public static <T> List<T> singletonList(T o)
List<String> list = Collections.singletonList("rubytomato");

Set

Setの実装クラスはjava.util.Collections.SingletonSetで、引数に渡した要素だけを持つSetを返します。要素数の変更(add、remove、clearメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

singleton
public static <T> Set<T> singleton(T o)
Set<String> set = Collections.singleton("rubytomato");

Map

Mapの実装クラスはjava.util.Collections.SingletonMapで、引数に渡したキー/バリューだけを持つMapを返します。要素数の変更(put、remove、clearメソッド等)や、要素の変更(replace、replaceAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

singletonMap
public static <K,V> Map<K,V> singletonMap(K key, V value)
Map<Long, String> map = Collections.singletonMap(100L, "rubytomato");

不変なコレクション、マップを返す

Collection

実装クラスはjava.util.Collections.UnmodifiableCollectionで、引数に渡したCollectionを不変化したコレクションを返します。要素数の変更(add、remove、clearメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

unmodifiableCollection
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "ruby", "garnet", "spinel");

Collection<String> unmodifiable = Collections.unmodifiableCollection(lists);

unmodifiable.add("rubellite");
// → UnsupportedOperationExceptionをスロー

List

Listの実装クラスはjava.util.Collections.UnmodifiableRandomAccessListで、引数に渡したListを不変化したコレクションを返します。要素数の変更(add、addAll、remove、clearメソッド等)や、要素の変更(set、replaceAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

unmodifiableList
public static <T> List<T> unmodifiableList(List<? extends T> list)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "ruby", "garnet", "spinel");

List<String> unmodifiedLists = Collections.unmodifiableList(lists);

unmodifiedLists.add("rubellite");
// → UnsupportedOperationExceptionをスロー

Set

Setの実装クラスはjava.util.Collections.UnmodifiableSetで、引数に渡したSetを不変化したコレクションを返します。要素数の変更(add、remove、clearメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

unmodifiableSet
public static <T> Set<T> unmodifiableSet(Set<? extends T> s)
Set<String> sets = new HashSet<>();
Collections.addAll(sets, "ruby", "garnet", "spinel");

Set<String> unmodifiedSets = Collections.unmodifiableSet(sets);

unmodifiedSets.add("rubellite");
// → UnsupportedOperationExceptionをスロー

Map

Mapの実装クラスはjava.util.Collections.UnmodifiableMapで、引数に渡したMapを不変化したマップを返します。要素数の変更(put、remove、clearメソッド等)や、要素の変更(replace、replaceAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。

unmodifiableMap
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
Map<Long, String> maps = new HashMap<>();
maps.put(100L, "ruby");
maps.put(200L, "garnet");
maps.put(300L, "spinel");

Map<Long, String> unmodifiedMaps = Collections.unmodifiableMap(maps);

unmodifiedMaps.put(400L, "rubellite");
// → UnsupportedOperationExceptionをスロー

Arrays

配列を操作するユーティリティークラスです。

配列からListを生成する

Listの実装クラスはjava.util.Arrays.ArrayListで、引数に渡す配列からListを生成して返します。要素数の変更(add、removeメソッド等)を行うとUnsupportedOperationExceptionがスローされます。
要素の変更(set、replaceAllメソッド等)は可能です。

asList
@SafeVarargs
public static <T> List<T> asList(T... a)
String[] arrays = new String[] {"rubytomato", "garnetpepper", "spinelginger"};
List<String> lists = Arrays.asList(arrays);

System.out.println(lists);
// → [rubytomato, garnetpepper, spinelginger]
List<String> lists = Arrays.asList("rubytomato", "garnetpepper", "spinelginger");

System.out.println(lists);
// → [rubytomato, garnetpepper, spinelginger]

// 要素をすべて大文字に更新する
lists.replaceAll(String::toUpperCase);

System.out.println(lists);
// → [RUBYTOMATO, GARNETPEPPER, SPINELGINGER]

配列の要素を更新する

導入バージョン Java 1.8

第1引数で渡す配列の各要素を、第2引数で渡す関数の演算結果で更新します。

setAll
public static <T> void setAll(T[] array,
    IntFunction<? extends T> generator)
String[] arrays = new String[] {"rubytomato", "garnetpepper", "spinelginger", "rubellitebeets"};

Arrays.stream(arrays).forEach(e -> { System.out.println(e +  " ID:" + System.identityHashCode(e));});
// → rubytomato ID:864237698
// → garnetpepper ID:537548559
// → spinelginger ID:380894366
// → rubellitebeets ID:237852351

Arrays.setAll(arrays, index -> {
  if (index % 2 == 0) {
    return arrays[index].toUpperCase();
  }
  return arrays[index];
});

Arrays.stream(arrays).forEach(e -> { System.out.println(e +  " ID:" + System.identityHashCode(e));});
// → RUBYTOMATO ID:1221555852
// → garnetpepper ID:537548559
// → SPINELGINGER ID:1509514333
// → rubellitebeets ID:237852351

配列からStreamを生成する

導入バージョン Java 1.8

引数に渡す配列からStreamを生成します。

stream
public static <T> Stream<T> stream(T[] array)
String[] arrays = new String[] {"rubytomato", "garnetpepper", "spinelginger"};

Arrays.stream(arrays).forEach(System.out::println);
// → rubytomato
// → garnetpepper
// → spinelginger

2つの配列が同等かチェックする

引数に渡す2つの配列が同等(同じ並びでそれぞれの要素が同等)かチェックします。

equals
public static boolean equals(Object[] a, Object[] a2)
String[] arrays1 = new String[] {"ruby", "garnet", "spinel", "rubellite"};
String[] arrays2 = new String[] {"ruby", "garnet", "spinel", "rubellite"};
String[] arrays3 = new String[] {"garnet", "ruby", "spinel", "rubellite"};

System.out.println(arrays1.equals(arrays2));
// → false

System.out.println(Arrays.equals(arrays1, arrays2));
// → true

// 要素の並びも同じでなければ同等と判断されない
System.out.println(Arrays.equals(arrays1, arrays3));
// → false

2つの多次元配列が同等かチェックする

引数に渡す2つの配列が同等かチェックします。多次元配列向けです。

deepEquals
public static boolean deepEquals(Object[] a1, Object[] a2)
String[][] arrays1 = new String[][] {
  {"ruby", "garnet"},
  {"spinel", "rubellite"}
};
String[][] arrays2 = new String[][] {
  {"ruby", "garnet"},
  {"spinel", "rubellite"}
};

System.out.println(Arrays.equals(arrays1, arrays2));
// → false

System.out.println(Arrays.deepEquals(arrays1, arrays2));
// → true

配列の文字列表現を返す

引数に渡した配列の文字列表現を返します。配列がnullの場合は"null"という文字列が返ります。

toString
public static String toString(Object[] a)
Employee[] employees = new Employee[] {
  new Employee(100L, "rubytomato"),
  new Employee(200L, "garnetpepper"),
  new Employee(300L, "rubytomato"),
  new Employee(400L, "rubellitebeets")
};

System.out.println(employees.toString());
// → [Lcom.example.Employee;@51521cc1

System.out.println(Arrays.toString(employees));
// → [Employee{id=100, name='rubytomato'}, Employee{id=200, name='garnetpepper'}, Employee{id=300, name='rubytomato'}, Employee{id=400, name='rubellitebeets'}]

nullの場合

配列がnullの場合は、NullPointerExceptionはスローされず、"null"という文字列が出力されます。

Employee[] employees = null;

System.out.println(Arrays.toString(employees));
// → null

多次元配列の文字列表現を返す

引数に渡した配列の文字列表現を返します。多次元配列向けです。配列がnullの場合は"null"という文字列が返ります。

deepToString
public static String deepToString(Object[] a)
Employee[][] employees = new Employee[][] {
  {
    new Employee(100L, "rubytomato"),
    new Employee(200L, "garnetpepper")
  },
  {
    new Employee(300L, "spinelginger"),
    new Employee(400L, "rubellitebeets")
  }
;

System.out.println(Arrays.toString(employees));
// → [[Lcom.example.Employee;@1b4fb997, [Lcom.example.Employee;@deb6432]

System.out.println(Arrays.deepToString(employees));
// → [[Employee{id=100, name='rubytomato'}, Employee{id=200, name='garnetpepper'}], [Employee{id=300, name='spinelginger'}, Employee{id=400, name='rubellitebeets'}]]

nullの場合

配列がnullの場合は、NullPointerExceptionはスローされず、"null"という文字列が出力されます。

Employee[][] employees = null;

System.out.println(Arrays.deepToString(employees));
// → null

Collection

removeIf

導入バージョン Java 1.8

引数に渡すfilterの条件に一致する要素をコレクションから削除します。

removeIf
default boolean removeIf(Predicate<? super E> filter)
List<String> fruits = new ArrayList<>();
Collections.addAll(fruits, "chocolate vine", "fig tree", "blackcurrant", "bramble",
    "silverberry", "mulberry", "cranberry", "lingonberry", "pomegranate", "seaberry",
    "jujube", "japanese bush cherry", "bilberry", "redcurrant", "grape");

// "berry"で終わる要素を削除する
fruits.removeIf(name -> name.endsWith("berry"));

System.out.println(fruits);
// → [chocolate vine, fig tree, blackcurrant, bramble, pomegranate, jujube, japanese bush cherry, redcurrant, grape]

retainAll

引数に渡すコレクションの要素と同じ要素を残します。一致しない要素はコレクションから削除します。

retainAll
boolean retainAll(Collection<?> c)
List<String> jewels = new ArrayList<>();
Collections.addAll(jewels, "amber", "aquamarine", "citrine", "garnet", "rubellite", "ruby",
    "sapphire", "sinhalight", "spinel", "tanzanite", "tourmaline");

System.out.println(jewels);
// → [amber, aquamarine, citrine, garnet, rubellite, ruby, sapphire, sinhalight, spinel, tanzanite, tourmaline]

List<String> red = Arrays.asList("ruby", "rubellite", "spinel", "garnet");

boolean modified = jewels.retainAll(red);

System.out.println(modified);
// → true
System.out.println(jewels);
// → [garnet, rubellite, ruby, spinel]

stream

導入バージョン Java 1.8

コレクションからstreamを生成します。

stream
default Stream<E> stream()
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "ruby", "garnet", "spinel");

lists.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);
// → RUBY
// → GARNET
// → SPINEL

toArray

コレクションから配列を生成します。

toArray
<T> T[] toArray(T[] a)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "ruby", "garnet", "spinel");

// Listから配列へ
String[] arrays = lists.toArray(new String[0]);

System.out.println(Arrays.toString(arrays));
// → [ruby, garnet, spinel]

List

add

第1引数で指定するindexの位置に、第2引数で指定する要素を追加します。

add
void add(int index, E element)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

// index=3の位置に要素を追加します
lists.add(3, "Darryl");

System.out.println(lists);
// → [Louis, Keith, Charles, Darryl, Williams, Michael, Ronald]
リストの先頭に追加
lists.add(0, "Darryl");
リストの末尾に追加
lists.add(lists.size(), "Darryl");

addAll

第1引数で指定するindexの位置に、第2引数で指定するコレクションの要素を追加します。

addAll
boolean addAll(int index, Collection<? extends E> c)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

System.out.println(lists);
// → [Louis, Keith, Charles, Williams, Michael, Ronald]

List<String> others = Arrays.asList("Darryl", "Ian", "Tony");
lists.addAll(3, others);

System.out.println(lists);
// → [Louis, Keith, Charles, Darryl, Ian, Tony, Williams, Michael, Ronald]

set

第1引数で指定するindexの要素を、第2引数に指定した要素で置き換えます。

set
E set(int index, E element)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

String oldValue = lists.set(3, "Darryl");

System.out.println(oldValue);
// → Williams

System.out.println(lists);
// → [Louis, Keith, Charles, Darryl, Michael, Ronald]

replaceAll

導入バージョン Java 1.8

引数に渡すoperatorの演算結果を各要素に適用し、その結果で置き換えます。

replaceAll
default void replaceAll(UnaryOperator<E> operator)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

System.out.println(lists);
// → [Louis, Keith, Charles, Williams, Michael, Ronald]

lists.replaceAll(s -> String.join("", "[", s.toUpperCase(), "]"));

System.out.println(lists);
// → [[LOUIS], [KEITH], [CHARLES], [WILLIAMS], [MICHAEL], [RONALD]]

remove

引数で指定するindexの要素をコレクションから削除します。

remove
E remove(int index)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

String value = lists.remove(3);

System.out.println(value);
// → Williams

System.out.println(lists);
// → [Louis, Keith, Charles, Michael, Ronald]

sort

導入バージョン Java 1.8

引数に渡すコンパレータを使ってListをソートします。

sort
default void sort(Comparator<? super E> c)
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "AAAA", "BBBB", "CCC", "DDD", "EE", "FFFFF", "AAAA", "BBB");

// String.compareToの結果でソートします
lists.sort(String::compareTo);

System.out.println(lists);
// → [AAAA, AAAA, BBB, BBBB, CCC, DDD, EE, FFFFF]
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "AAAA", "BBBB", "CCC", "DDD", "EE", "FFFFF", "AAAA", "BBB");

// 文字列長でソートします。
lists.sort(Comparator.comparing(String::length));

System.out.println(lists);
// → [EE, CCC, DDD, BBB, AAAA, BBBB, AAAA, FFFFF]
List<String> lists = new ArrayList<>();
Collections.addAll(lists, "AAAA", "BBBB", "CCC", "DDD", "EE", "FFFFF", "AAAA", "BBB");

// 文字列長 + String.compareToの結果でソートします
lists.sort(Comparator.comparing(String::length)
    .thenComparing(String::compareTo));

System.out.println(lists);
// → [EE, BBB, CCC, DDD, AAAA, AAAA, BBBB, FFFFF]

ArrayList

コレクションから新しいArrayListを生成

コンストラクタの引数に渡すコレクションからArrayListを生成します。

コンストラクタ
public ArrayList(Collection<? extends E> c)

SetからArrayList

Set<String> sets = new HashSet<>();
Collections.addAll(sets, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

// SetからArrayListを生成
List<String> lists = new ArrayList<>(sets);

System.out.println(lists);
// → [Charles, Keith, Williams, Ronald, Michael, Louis]

Set

Setインタフェース独自のメソッドはありませんので割愛します。

HashSet

コレクションから新しいHashSetを生成

コンストラクタの引数に渡すコレクションからHashSetを生成します。

コンストラクタ
public HashSet(Collection<? extends E> c)

ListからHashSet

List<String> lists = new ArrayList<>();
Collections.addAll(lists, "Louis", "Keith", "Charles", "Williams", "Michael", "Ronald");

// ListからHashSetを生成
Set<String> sets = new HashSet<>(lists);

System.out.println(sets);
// → [Charles, Keith, Williams, Ronald, Michael, Louis]

EnumSet

導入バージョン Java 1.5

allOf

引数に渡す列挙名のすべての列挙子から成るEnumSetを生成します。

allOf
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)
EnumSet<DeepPurple> enums = EnumSet.allOf(DeepPurple.class);

System.out.println(enums);
// → [IanGillan, SteveMorse, RogerGlover, IanPaice, DonAirey]

copyOf

引数に渡すCollectionからEnumSetを生成します。

copyOf
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)
Set<DeepPurple> sets = new HashSet<>();
Collections.addAll(sets, DeepPurple.IanGillan, DeepPurple.IanPaice);

EnumSet<DeepPurple> enums = EnumSet.copyOf(sets);

System.out.println(enums);
// → [IanGillan, IanPaice]
List<DeepPurple> lists = new ArrayList<>();
Collections.addAll(lists, DeepPurple.IanGillan, DeepPurple.IanPaice);

EnumSet<DeepPurple> enums = EnumSet.copyOf(lists);

System.out.println(enums);
// → [IanGillan, IanPaice]

noneOf

引数に渡す列挙名の型の空のEnumSetを生成します。

noneOf
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType)
EnumSet<DeepPurple> enums = EnumSet.noneOf(DeepPurple.class);

System.out.println(enums);
// → []

of

引数に渡す列挙子から成るEnumSetを生成します。

of
public static <E extends Enum<E>> EnumSet<E> of(E e)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)
of
@SafeVarargs
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest)
EnumSet<DeepPurple> enums = EnumSet.of(DeepPurple.RogerGlover, DeepPurple.DonAirey, DeepPurple.SteveMorse);

System.out.println(enums);
// → [SteveMorse, RogerGlover, DonAirey]

Map

MapがCollectionを継承しないのはなぜですか。
これは設計によるものです。マッピングはコレクションではなく、コレクションはマッピングではないと考えています。そのため、MapがCollectionインタフェースを継承する(その逆も)ということにはほとんど意味がありません。

compute

導入バージョン Java 1.8

第1引数で指定するキーにマッピングされている値に、第2引数で渡す関数を適用しその計算結果でキーの値を更新しそれを返します。
キーがマッピングされていない場合は値をnullとして計算します。
関数がnullを返す場合、エントリーは削除されます。

compute
default V compute(K key,
    BiFunction<? super K,? super V,? extends V> remappingFunction)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", null);

// マッピングの有無にかかわらず実行される関数
BiFunction<String, String, String> remapping = (key, val) -> {
  if (val == null) {
    // この例では文字列を返していますが、
    // 例えば、keyでDBから値を検索するなどの処理を実行することができます
    return "UNKNOWN";
  }
  return val.toUpperCase();
};

// マッピングされている
String value = maps.compute("ruby", remapping);

System.out.println(value);
// → TOMATO

// nullにマッピングされている
value = maps.compute("rubellite", remapping);

System.out.println(value);
// → UNKNOWN

// マッピングされていない
value = maps.compute("sapphire", remapping);

System.out.println(value);
// → UNKNOWN

System.out.println(maps);
// → {spinel=ginger, rubellite=UNKNOWN, garnet=pepper, sapphire=UNKNOWN, ruby=TOMATO}

computeIfAbsent

導入バージョン Java 1.8

第1引数で指定するキーに値がマッピングされていない(またはnullがマッピングされている)場合、第2引数で渡す関数の計算結果をキーの値として更新しそれを返します。
キーに値がマッピングされている場合はマップは更新せず、キーの値を返します。
関数がnullを返す場合、エントリーは保存されません。

computeIfAbsent
default V computeIfAbsent(K key,
    Function<? super K,? extends V> mappingFunction)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", null);

// キーにnull以外の値がマッピングされていない場合に実行される関数
Function<String, String> mapping = (key) -> {
  // この例では文字列を返していますが、
  // 例えば、keyでDBから値を検索するなどの処理を実行することができます
  return "UNKNOWN";
};

// マッピングされているので、関数は実行されず
String value = maps.computeIfAbsent("ruby", mapping);

System.out.println(value);
// → tomato

// nullにマッピングされているので、関数を実行しその結果を返す
value = maps.computeIfAbsent("rubellite", mapping);

System.out.println(value);
// → UNKNOWN

// マッピングされていないので、関数を実行しその結果を返す
value = maps.computeIfAbsent("sapphire", mapping);

System.out.println(value);
// → UNKNOWN

System.out.println(maps);
// → {spinel=ginger, rubellite=UNKNOWN, garnet=pepper, sapphire=UNKNOWN, ruby=tomato}

computeIfPresent

導入バージョン Java 1.8

第1引数で指定するキーにnull以外の値がマッピングされている場合、第2引数で渡す関数を適用しその計算結果でキーの値を更新しそれを返します。
キーに値がマッピングされていない場合は関数を実行せずマップも更新しません。
関数がnullを返す場合、エントリーは削除されます。

computeIfPresent
default V computeIfPresent(K key,
    BiFunction<? super K,? super V,? extends V> remappingFunction)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", null);

// キーにnull以外の値がマッピングされている場合に実行される関数
BiFunction<String, String, String> remapping = (key, val) -> {
  return val.toUpperCase();
};

// マッピングされているので、関数を実行しその結果を返す
String value = maps.computeIfPresent("ruby", remapping);

System.out.println(value);
// → TOMATO

// nullにマッピングされているので、関数は実行されず
value = maps.computeIfPresent("rubellite", remapping);

System.out.println(value);
// → null

// マッピングされていないので、関数は実行されず
value = maps.computeIfPresent("sapphire", remapping);

System.out.println(value);
// → null

System.out.println(maps);
// → {spinel=ginger, rubellite=null, garnet=pepper, ruby=TOMATO}

forEach

導入バージョン Java 1.8

マップの各エントリーに対して引数に渡す関数を実行します。

forEach
default void forEach(BiConsumer<? super K,? super V> action)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", "beets");

maps.forEach((key, val) -> {
  System.out.println("key=" + key + ", value=" + val);
});
// → key=spinel, value=ginger
// → key=rubellite, value=beets
// → key=garnet, value=pepper
// → key=ruby, value=tomato

merge

導入バージョン Java 1.8

第1引数で指定するキーに値がマッピングされていない(またはnullがマッピングされている場合)に、第2引数で渡す値をマッピングします。
キーがマッピングされている場合、第3引数で渡す関数の計算結果で値を置換します。関数がnullを返す場合はエントリーを削除します。

merge
default V merge(K key, V value,
    BiFunction<? super V,? super V,? extends V> remappingFunction)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", null);

Map<String, String> otherMaps = new HashMap<>();
otherMaps.put("rubellite", "BEETS");
otherMaps.put("ruby", "TOMATO");
otherMaps.put("sapphire", "SPINACH");

otherMaps.forEach((key, value) -> {
  maps.merge(key, value, (oldVal, newVal) -> {
    return oldVal + " -> " + newVal;
  });
});

System.out.println(maps);
// → {spinel=ginger, rubellite=BEETS, garnet=pepper, sapphire=SPINACH, ruby=tomato -> TOMATO}

putIfAbsent

導入バージョン Java 1.8

第1引数で指定するキーに値がマッピングされていない(またはnullがマッピングされている場合)に、第2引数で渡す値でキーの値を更新します。
すでにnull以外の値がマッピングされている場合はマップを更新しません。

putIfAbsent
default V putIfAbsent(K key, V value)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", null);

// nullにマッピングされている場合は更新します
String value = maps.putIfAbsent("rubellite", "BEETS");

System.out.println(value);
// → null

// マッピングされている場合は更新しません
value = maps.putIfAbsent("ruby", "TOMATO");

System.out.println(value);
// → tomato

// マッピングされていない場合は引数でマッピングします
value = maps.putIfAbsent("sapphire", "SPINACH");

System.out.println(value);
// → null

System.out.println(maps);
// → {spinel=ginger, rubellite=BEETS, garnet=pepper, ruby=tomato, sapphire=SPINACH}

remove

導入バージョン Java 1.8

第1引数で指定するキーに第2引数で指定する値がマッピングされている場合(値がnullの場合も含む)、そのエントリーを削除します。

remove
default boolean remove(Object key, Object value)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", "beets");
maps.put("sapphire", null);

boolean modified = maps.remove("ruby", "TOMATO");

System.out.println(modified);
// → false

modified = maps.remove("ruby", "tomato");

System.out.println(modified);
// → true

modified = maps.remove("sapphire", null);

System.out.println(modified);
// → true

System.out.println(maps);
// → {spinel=ginger, rubellite=beets, garnet=pepper}

replace

導入バージョン Java 1.8

第1引数で指定するキーがマッピングされている場合(値がnullの場合も含む)、第2引数で渡す値で置換します。
キーがマッピングされていない場合はマップを更新しません。

replace
default V replace(K key, V value)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", "beets");

String oldValue = maps.replace("ruby", "TOMATO");

System.out.println(oldValue);
// → tomato

oldValue = maps.replace("sapphire", "spinach");

System.out.println(oldValue);
// → null

System.out.println(maps);
// → {spinel=ginger, rubellite=beets, garnet=pepper, ruby=TOMATO}

replaceAll

導入バージョン Java 1.8

引数に渡す関数の演算結果で値を置き換えます。

replaceAll
default void replaceAll(BiFunction<? super K,? super V,? extends V> function)
Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");
maps.put("rubellite", "beets");
maps.put("sapphire", null);

maps.replaceAll((key, value) -> {
  if (value == null) {
    return "UNKNOWN";
  }
  return value.toUpperCase();
});

System.out.println(maps);
// → {spinel=GINGER, rubellite=BEETS, garnet=PEPPER, ruby=TOMATO, sapphire=UNKNOWN}

HashMap

Mapから新しいHashMapを生成

コンストラクタの引数に渡すマップから新しいHashMapを生成します。

コンストラクタ
public HashMap(Map<? extends K,? extends V> m)

MapからHashMap

Map<String, String> maps = new HashMap<>();
maps.put("ruby", "tomato");
maps.put("garnet", "pepper");
maps.put("spinel", "ginger");

// 新しいHashMapを生成
Map<String, String> newMaps = new HashMap<>(maps);
newMaps.put("rubellite", "beets");

System.out.println(maps);
// → {spinel=ginger, garnet=pepper, ruby=tomato}

System.out.println(newMaps);
// → {spinel=ginger, garnet=pepper, ruby=tomato, rubellite=beets}

EnumMap

導入バージョン Java 1.5

Mapから新しいEnumMapを生成

コンストラクタの引数に渡すマップから新しいEnumMapを生成します。

コンストラクタ
public EnumMap(Map<K,? extends V> m)
Map<DeepPurple, LocalDate> maps = new HashMap<>();
maps.put(DeepPurple.IanGillan, LocalDate.of(1945, 8, 19));
maps.put(DeepPurple.SteveMorse, LocalDate.of(1954, 7, 28));
maps.put(DeepPurple.RogerGlover, LocalDate.of(1945, 11, 30));
maps.put(DeepPurple.IanPaice, LocalDate.of(1948, 6, 29));
maps.put(DeepPurple.DonAirey, LocalDate.of(1948, 6, 21));

EnumMap<DeepPurple, LocalDate> enums = new EnumMap<>(maps);

System.out.println(enums);
// → {IanGillan=1945-08-19, SteveMorse=1954-07-28, RogerGlover=1945-11-30, IanPaice=1948-06-29, DonAirey=1948-06-21}

EnumMapからSetを生成

entrySet
public Set<Map.Entry<K,V>> entrySet()
EnumMap<DeepPurple, LocalDate> enums = new EnumMap<>(DeepPurple.class);
enums.put(DeepPurple.IanGillan, LocalDate.of(1945, 8, 19));
enums.put(DeepPurple.SteveMorse, LocalDate.of(1954, 7, 28));
enums.put(DeepPurple.RogerGlover, LocalDate.of(1945, 11, 30));
enums.put(DeepPurple.IanPaice, LocalDate.of(1948, 6, 29));
enums.put(DeepPurple.DonAirey, LocalDate.of(1948, 6, 21));

Set<Map.Entry<DeepPurple, LocalDate>> sets = enums.entrySet();

System.out.println(sets);
// → [IanGillan=1945-08-19, SteveMorse=1954-07-28, RogerGlover=1945-11-30, IanPaice=1948-06-29, DonAirey=1948-06-21]

Java 9で追加されたAPI

Collections

追加はありません。

Arrays

equals

以下のようなequalsメソッドが幾つか追加されています。

public static boolean equals​(int[] a, int aFromIndex, int aToIndex,
                             int[] b, int bFromIndex, int bToIndex)

compare

以下のようなcompareメソッドが幾つか追加されています。

public static int compare​(int[] a,
                          int[] b)

compareUnsigned

以下のようなcompareUnsignedメソッドが幾つか追加されています。

public static int compareUnsigned​(int[] a,
                                  int[] b)

mismatch

以下のようなmismatchメソッドが幾つか追加されています。

public static int mismatch​(int[] a,
                           int[] b)

Collection

追加はありません。

List

of

static <E> List<E> of​()

e1からe10まで

static <E> List<E> of​(E e1)

static <E> List<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
@SafeVarargs
static <E> List<E> of​(E... elements)

ArrayList

追加はありません。

Set

of

static <E> Set<E> of​()

e1からe10まで

static <E> Set<E> of​(E e1)

static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
@SafeVarargs
static <E> Set<E> of​(E... elements)

HashSet

追加はありません。

EnumSet

追加はありません。

Map

of

static <K,V> Map<K,V> of​()

k1,v1からk10,v10まで

static <K,V> Map<K,V> of​(K k1, V v1)

static <K,V> Map<K,V> of​(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                         K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)

ofEntries

@SafeVarargs
static <K,V> Map<K,V> ofEntries​(Map.Entry<? extends K,? extends V>... entries)

entry

static <K,V> Map.Entry<K,V> entry​(K k, V v)

HashMap

追加はありません。

EnumMap

追加はありません。

Java 10で追加されたAPI

Collections

追加はありません。

Arrays

追加はありません。

Collection

追加はありません。

List

copyOf

static <E> List<E> copyOf​(Collection<? extends E> coll)

ArrayList

追加はありません。

Set

copyOf

static <E> Set<E> copyOf​(Collection<? extends E> coll)

HashSet

追加はありません。

EnumSet

追加はありません。

Map

copyOf

static <K,V> Map<K,V> copyOf​(Map<? extends K,? extends V> map)

HashMap

追加はありません。

EnumMap

追加はありません。

その他のおさらいメモ

10
17
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
10
17