概要
Collections Frameworkのおさらいメモです。Java8のstreamで追加された部分を中心におさらいしましたので内容がだいぶ偏っています。
環境
- Windows10 Professional
- Oracle JDK 1.8.0_144
- Oracle JDK 10.0.1
参考
- [Collections Framework] (https://docs.oracle.com/javase/jp/8/docs/technotes/guides/collections/index.html)
- [Collections Frameworkの概要] (https://docs.oracle.com/javase/jp/8/docs/technotes/guides/collections/reference.html)
- [JavaコレクションAPIの設計に関するFAQ] (https://docs.oracle.com/javase/jp/8/docs/technotes/guides/collections/designfaq.html)
- [java.util.stream ライブラリー入門] (https://www.ibm.com/developerworks/jp/java/library/j-java-streams-1-brian-goetz/index.html)
この記事のサンプルコードでは、下記のclass,enumを使用しています。
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 + '\'' +
'}';
}
}
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collections.html)
コレクションを操作するユーティリティークラスです。
コレクションに要素を追加する
第1引数に渡すコレクションに、第2引数で渡す任意の数の要素を追加します。
@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引数で渡すコンパレータでソートします。
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がスローされます。
public static final <T> List<T> emptyList()
List<String> lists = Collections.emptyList();
Set
Setの実装クラスはjava.util.Collections.EmptySet
で、要素数が変わる操作(add、addAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。
public static final <T> Set<T> emptySet()
Set<String> sets = Collections.emptySet();
Map
Mapの実装クラスはjava.util.Collections.EmptyMap
で、要素数が変わる操作(put、putAllメソッド等)を行うとUnsupportedOperationExceptionがスローされます。
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がスローされます。
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がスローされます。
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がスローされます。
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がスローされます。
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がスローされます。
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がスローされます。
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がスローされます。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Arrays.html)
配列を操作するユーティリティークラスです。
配列からListを生成する
Listの実装クラスはjava.util.Arrays.ArrayList
で、引数に渡す配列からListを生成して返します。要素数の変更(add、removeメソッド等)を行うとUnsupportedOperationExceptionがスローされます。
要素の変更(set、replaceAllメソッド等)は可能です。
@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引数で渡す関数の演算結果で更新します。
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を生成します。
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つの配列が同等(同じ並びでそれぞれの要素が同等)かチェックします。
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つの配列が同等かチェックします。多次元配列向けです。
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"という文字列が返ります。
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"という文字列が返ります。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collection.html)
[removeIf] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collection.html#removeIf-java.util.function.Predicate-)
導入バージョン Java 1.8
引数に渡すfilterの条件に一致する要素をコレクションから削除します。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collection.html#retainAll-java.util.Collection-)
引数に渡すコレクションの要素と同じ要素を残します。一致しない要素はコレクションから削除します。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collection.html#stream--)
導入バージョン Java 1.8
コレクションから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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collection.html#toArray-T:A-)
コレクションから配列を生成します。
<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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html)
[add] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html#add-int-E-)
第1引数で指定するindexの位置に、第2引数で指定する要素を追加します。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html#addAll-int-java.util.Collection-)
第1引数で指定するindexの位置に、第2引数で指定するコレクションの要素を追加します。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html#set-int-E-)
第1引数で指定するindexの要素を、第2引数に指定した要素で置き換えます。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html#replaceAll-java.util.function.UnaryOperator-)
導入バージョン Java 1.8
引数に渡すoperatorの演算結果を各要素に適用し、その結果で置き換えます。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html#remove-int-)
引数で指定するindexの要素をコレクションから削除します。
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html#sort-java.util.Comparator-)
<font color="blue">導入バージョン Java 1.8</font>
引数に渡すコンパレータを使ってListをソートします。
```text:sort
default void sort(Comparator<? super E> c)
```
```java:例
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]
```
```java:例
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]
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/ArrayList.html)
## コレクションから新しいArrayListを生成
コンストラクタの引数に渡すコレクションからArrayListを生成します。
```text:コンストラクタ
public ArrayList(Collection<? extends E> c)
```
**SetからArrayList**
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Set.html)
Setインタフェース独自のメソッドはありませんので割愛します。
# [HashSet] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/HashSet.html)
## コレクションから新しいHashSetを生成
コンストラクタの引数に渡すコレクションからHashSetを生成します。
```text:コンストラクタ
public HashSet(Collection<? extends E> c)
```
**ListからHashSet**
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/EnumSet.html)
<font color="green">導入バージョン Java 1.5</font>
## [allOf] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/EnumSet.html#allOf-java.lang.Class-)
引数に渡す列挙名のすべての列挙子から成るEnumSetを生成します。
```text:allOf
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)
```
```java:例
EnumSet<DeepPurple> enums = EnumSet.allOf(DeepPurple.class);
System.out.println(enums);
// → [IanGillan, SteveMorse, RogerGlover, IanPaice, DonAirey]
```
## [copyOf] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/EnumSet.html#copyOf-java.util.Collection-)
引数に渡すCollectionからEnumSetを生成します。
```text:copyOf
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)
```
```java:例
Set<DeepPurple> sets = new HashSet<>();
Collections.addAll(sets, DeepPurple.IanGillan, DeepPurple.IanPaice);
EnumSet<DeepPurple> enums = EnumSet.copyOf(sets);
System.out.println(enums);
// → [IanGillan, IanPaice]
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/EnumSet.html#noneOf-java.lang.Class-)
引数に渡す列挙名の型の空のEnumSetを生成します。
```text:noneOf
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType)
```
```java:例
EnumSet<DeepPurple> enums = EnumSet.noneOf(DeepPurple.class);
System.out.println(enums);
// → []
```
## [of] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/EnumSet.html#of-E-)
引数に渡す列挙子から成るEnumSetを生成します。
```text: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)
```
```text:of
@SafeVarargs
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest)
```
```java:例
EnumSet<DeepPurple> enums = EnumSet.of(DeepPurple.RogerGlover, DeepPurple.DonAirey, DeepPurple.SteveMorse);
System.out.println(enums);
// → [SteveMorse, RogerGlover, DonAirey]
```
# [Map] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html)
> [MapがCollectionを継承しないのはなぜですか。] (https://docs.oracle.com/javase/jp/8/docs/technotes/guides/collections/designfaq.html#a14)
> これは設計によるものです。マッピングはコレクションではなく、コレクションはマッピングではないと考えています。そのため、MapがCollectionインタフェースを継承する(その逆も)ということにはほとんど意味がありません。
## [compute] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#compute-K-java.util.function.BiFunction-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーにマッピングされている値に、第2引数で渡す関数を適用しその計算結果でキーの値を更新しそれを返します。
キーがマッピングされていない場合は値をnullとして計算します。
関数がnullを返す場合、エントリーは削除されます。
```text:compute
default V compute(K key,
BiFunction<? super K,? super V,? extends V> remappingFunction)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーに値がマッピングされていない(またはnullがマッピングされている)場合、第2引数で渡す関数の計算結果をキーの値として更新しそれを返します。
キーに値がマッピングされている場合はマップは更新せず、キーの値を返します。
関数がnullを返す場合、エントリーは保存されません。
```text:computeIfAbsent
default V computeIfAbsent(K key,
Function<? super K,? extends V> mappingFunction)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#computeIfPresent-K-java.util.function.BiFunction-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーにnull以外の値がマッピングされている場合、第2引数で渡す関数を適用しその計算結果でキーの値を更新しそれを返します。
キーに値がマッピングされていない場合は関数を実行せずマップも更新しません。
関数がnullを返す場合、エントリーは削除されます。
```text:computeIfPresent
default V computeIfPresent(K key,
BiFunction<? super K,? super V,? extends V> remappingFunction)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#forEach-java.util.function.BiConsumer-)
<font color="blue">導入バージョン Java 1.8</font>
マップの各エントリーに対して引数に渡す関数を実行します。
```text:forEach
default void forEach(BiConsumer<? super K,? super V> action)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#merge-K-V-java.util.function.BiFunction-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーに値がマッピングされていない(またはnullがマッピングされている場合)に、第2引数で渡す値をマッピングします。
キーがマッピングされている場合、第3引数で渡す関数の計算結果で値を置換します。関数がnullを返す場合はエントリーを削除します。
```text:merge
default V merge(K key, V value,
BiFunction<? super V,? super V,? extends V> remappingFunction)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#putIfAbsent-K-V-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーに値がマッピングされていない(またはnullがマッピングされている場合)に、第2引数で渡す値でキーの値を更新します。
すでにnull以外の値がマッピングされている場合はマップを更新しません。
```text:putIfAbsent
default V putIfAbsent(K key, V value)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#remove-java.lang.Object-java.lang.Object-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーに第2引数で指定する値がマッピングされている場合(値がnullの場合も含む)、そのエントリーを削除します。
```text:remove
default boolean remove(Object key, Object value)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#replace-K-V-)
<font color="blue">導入バージョン Java 1.8</font>
第1引数で指定するキーがマッピングされている場合(値がnullの場合も含む)、第2引数で渡す値で置換します。
キーがマッピングされていない場合はマップを更新しません。
```text:replace
default V replace(K key, V value)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#replaceAll-java.util.function.BiFunction-)
<font color="blue">導入バージョン Java 1.8</font>
引数に渡す関数の演算結果で値を置き換えます。
```text:replaceAll
default void replaceAll(BiFunction<? super K,? super V,? extends V> function)
```
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/HashMap.html)
## Mapから新しいHashMapを生成
コンストラクタの引数に渡すマップから新しいHashMapを生成します。
```text:コンストラクタ
public HashMap(Map<? extends K,? extends V> m)
```
**MapからHashMap**
```java:例
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] (https://docs.oracle.com/javase/jp/8/docs/api/java/util/EnumMap.html)
<font color="green">導入バージョン Java 1.5</font>
## Mapから新しいEnumMapを生成
コンストラクタの引数に渡すマップから新しいEnumMapを生成します。
```text:コンストラクタ
public EnumMap(Map<K,? extends V> m)
```
```java:例
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を生成
```text:entrySet
public Set<Map.Entry<K,V>> entrySet()
```
```java:例
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] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/package-summary.html)
## [Collections] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/Collections.html)
追加はありません。
## [Arrays] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/Arrays.html)
### equals
以下のようなequalsメソッドが幾つか追加されています。
```text
public static boolean equals(int[] a, int aFromIndex, int aToIndex,
int[] b, int bFromIndex, int bToIndex)
```
### compare
以下のようなcompareメソッドが幾つか追加されています。
```text
public static int compare(int[] a,
int[] b)
```
### compareUnsigned
以下のようなcompareUnsignedメソッドが幾つか追加されています。
```text
public static int compareUnsigned(int[] a,
int[] b)
```
### mismatch
以下のようなmismatchメソッドが幾つか追加されています。
```text
public static int mismatch(int[] a,
int[] b)
```
## [Collection] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/Collection.html)
追加はありません。
## [List] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/List.html)
### of
```text
static <E> List<E> of()
```
e1からe10まで
```text
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)
```
```text
@SafeVarargs
static <E> List<E> of(E... elements)
```
## [ArrayList] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/ArrayList.html)
追加はありません。
## [Set] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/Set.html)
### of
```text
static <E> Set<E> of()
```
e1からe10まで
```text
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)
```
```text
@SafeVarargs
static <E> Set<E> of(E... elements)
```
## [HashSet] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/HashSet.html)
追加はありません。
## [EnumSet] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/EnumSet.html)
追加はありません。
## [Map] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/Map.html)
### of
```text
static <K,V> Map<K,V> of()
```
k1,v1からk10,v10まで
```text
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
```text
@SafeVarargs
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
```
### entry
```text
static <K,V> Map.Entry<K,V> entry(K k, V v)
```
## [HashMap] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/HashMap.html)
追加はありません。
## [EnumMap] (https://docs.oracle.com/javase/jp/9/docs/api/java/util/EnumMap.html)
追加はありません。
# [Java 10で追加されたAPI] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/package-summary.html)
## [Collections] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/Collections.html)
追加はありません。
## [Arrays] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/Arrays.html)
追加はありません。
## [Collection] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/Collection.html)
追加はありません。
## [List] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/List.html)
### copyOf
```text
static <E> List<E> copyOf(Collection<? extends E> coll)
```
## [ArrayList] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/ArrayList.html)
追加はありません。
## [Set] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/Set.html)
### copyOf
```text
static <E> Set<E> copyOf(Collection<? extends E> coll)
```
## [HashSet] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/HashSet.html)
追加はありません。
## [EnumSet] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/EnumSet.html)
追加はありません。
## [Map] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/Map.html)
### copyOf
```text
static <K,V> Map<K,V> copyOf(Map<? extends K,? extends V> map)
```
## [HashMap] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/HashMap.html)
追加はありません。
## [EnumMap] (https://docs.oracle.com/javase/jp/10/docs/api/java/util/EnumMap.html)
追加はありません。
# その他のおさらいメモ
* [Java NIO2のおさらいメモ] (https://qiita.com/rubytomato@github/items/6880eab7d9c76524d112)
* 2017年08月15日
* [クラス java.util.Objectsのおさらいメモ] (https://qiita.com/rubytomato@github/items/ba38877ed5a00dd24f16)
* 2017年08月25日
* [パッケージ java.time.temporal のおさらいメモ] (https://qiita.com/rubytomato@github/items/e9325dd46aa11f1b8e2e)
* 2018年01月30日
* [クラス java.util.Optionalのおさらいメモ] (https://qiita.com/rubytomato@github/items/92ac7944c830e54aa03d)
* 2018年03月22日