Collections
Framework
JJUG CCC 2019 spring C1
2019-05-18
#ccc_c1
•
• twitter: @mike_neck
• github : mike-neck
• L is B direct
(Java/Golang)
• Java
( )
• Java
•
• Queue
• Dequeue
• Optional …
•
•
•
• Collections Framework
• API
•
•
Collections
Framework
Java
• Java
Java
java.lang.String
int
com.app.Course
•
Java
java.uti.Set<com.app. >
•
Coffee[] coffees = new Coffee[];
(1)
•
•
•
(Effective Java 3rd ed No.59)
•
String[] array = …
String[] current = array;
String[] array = new String[current.length + 1];
System.arraycopy(current, 0, array, 0, current.length);
array[current.length] = "foo";
List<E>
List<String> list = …
list.add("foo");
(2)
•
• Java
•
Coffee
CaffeMocha
Coffee[]
CaffeMocha[]
Java CaffeMocha Coffee
CaffeMocha Coffee
Coffee
CaffeMocha
Coffee[]
CaffeMocha[]
Java CaffeMocha
Coffee
Coffee
CaffeMocha
Coffee[]
CaffeMocha[]
CaffeMocha[] CaffeMocha
CaffeMocha
( Coffee )
CaffeMocha[] caffeMochaArray = new CaffeMocha[1];
Coffee[] coffeeArray = caffeMochaArray;
coffeeArray[0] = new American(); // ArrayStoreException
Coffee Coffee
American
List<E>
(Java 5 )
Coffee
CaffeMocha
List<Coffee>
List<CaffeMocha>
List<Coffee> List<CaffeMocha>
List<CaffeMocha> caffeMochaList = new ArrayList<>();
List<Coffee> coffeeList = caffeMochaList; // compile error
List<Coffee> List<CaffeMocha>
List<Coffee>
List<CaffeMocha>
Collections Framework
•
• Java
• Collections Framework
• Collections Framework
API
• API
•
Iterable<T>
Collection<E>
List<E> Set<E> Map<K,V>
SortedSet<E> SortedMap<K,V>
Set<E>
• ( )
• ( )
SortedSet<E>
•
• ( )
List<E>
• (
)
•
0 1 2 3 4 5
Map<K,V>
• K (Set) V
• ( -> )
350JPY
550JPY
450JPY
350JPY
Collection<E>
• ( )
• / / / /
•
•
• ( )
•
•
•
UnsupportedOperationException
( )
!
Iterable<T>
Iterable<T>
Collection<E>
List<E> Set<E> Map<K,V>
Iterable<E>
• Iterator<E> iterator()
• Iterator<E> ( )
Iterable<String> iterable = ...;
Iterator<String> iterator = iterable.iterator();
while(iterator.hasNext()) {
String string = iterator.next();
System.out.println(string);
}
Iterable<E> (1)
• Iterable<E> for
Iterable<String> iterable = ...;
for(String item : iterable) {
• forEach(Consumer<? extends E>)
Iterable<E> (2)
Iterable<String> iterable = ...;
iterable.forEach(string -> System.out.println(string));
Collection<E>
Iterable<E>
Collection<E>
List<E> Set<E> Map<K,V>
Collection<E>
•
• boolean isEmpty()
• int size()
•
• boolean contains(Object)
• boolean
containsAll(Collection<?>)
• /
• E[] toArray(E[])
• Stream<E> stream()
•
• boolean add(E)
• boolean addAll(Collection<E>)
•
• boolean remove(E)
• true
• boolean removeAll(Collection<?>)
• boolean retainAll(Collection<?>)
• boolean removeIf(Predicate<? super E>)
• 1 true
•
• void clear()
!
!
Collection<E>
• ID
Collection<E>
public Collection<CoffeeSale> findCoffeeSales(
Instant date, Collection<CoffeeId> coffeeIds) {
// cofeeIds 0 return
if (coffeeIds.isEmpty()) {
return Collections.emptyList();
}
//
}
removeAll(Collection)
collection.removeAll(parameter);
collection parametercollection
retainAll(Collection)
collection.retainAll(parameter);
parametercollection
Set<E>
Iterable<E>
Collection<E>
List<E> Set<E> Map<K,V>
SortedSet<E> SortedMap<K,V>
Collection<E>
Collection<E>
( ) Set<E>
List<E>
Iterable<E>
Collection<E>
List<E> Set<E> Map<K,V>
List<E>
•
• E get(int)
•
• int indexOf(Object)
• int lastIndexOf(Object)
• List
• List<E> subList(int, int)
• ( )
• void add(int, E)
• void addAll(int,
Collection<E>)
•
• void set(int, E)
• void
replaceAll(UnrayOperator<E>
)
•
• void sort(Comparator<E>)
•
• E remove(int)
!
!
List#remove(int)
List<Integer> list = new ArrayList<>(
List.of(1, 2, 3, 4, 5));
// remove(int)? remove(E)?
list.remove(1);
!
Map<K,V>
Iterable<E>
Collection<E>
List<E> Set<E> Map<K,V>
Map<K,V>
•
• V get(K)
• V getOrDefault(K,V)
•
• boolean
containsKey(Object)
• boolean
containsValue(Object)
•
• int size()
• boolean isEmpty()
• /
• Set<K> keySet()
• Collection<V> values()
• Set<Map.Entry<K,V>>
entrySet()
• void forEach(BiConsumer<?
super K, ? super T>)
Map<K,V>
get
•
Map<CoffeeName, CoffeeProduct> coffees;
CoffeeProduct findProduct(CoffeeName name) {
return coffees.get(name);
}
CoffeeProduct product = coffeeRepository
.findProduct(coffeeName(" "));
Order newOrder = product.createNewOrder(1); // NullPointerException
Map<K,V>
get
• Optional<T>
Map<CoffeeName, CoffeeProduct> coffees;
Optional<CoffeeProduct> findProduct(CoffeeName name) {
return Optional.ofNullable(coffees.get(name));
}
Optional<CoffeeProduct> product = coffeeRepository
.findProduct(coffeeName(" "));
Optional<Order> newOrder = product.map(p -> p.createNewOrder(1));
Map<K,V>
• Java8
• V put(K, V)
• void putAll(Map<? extends
K, ? extends V>)
• Java 8
• V putIfAbsent(K, V)
• V compute(K, BiFunction<?
super K, ? super V, ? extends
V>)
• V computeIfAbsent(K,
Function<? super K, ? extends
V>)
!
• Java 8
• V replace(K, V)
• boolean replace(K, V, V)
• void replaceAll(BiFunction<?
super K, ? super V, ?
extends V>)
• V computeIfPresent(K,
Function<? super K, ?
extends V>)
• V merge(K, V, BiFunction<?
super V, ? super V, ?
extends V>)
put(K,V)
put(K,V)
putIfAbsent(K,V) replace(K,V)
put(K,V)
putIfAbsent/replace
compute
•
• Stream
(10 ) DrinkProduct
DrinkName
DrinkCategory
Price
Map<DrinkCategory,List<DrinkProduct>> groupByCategory(
List<DrinkProduct> list) {
Map<DrinkCategory,List<DrinkProduct>> map = new HashMap<>();
for(DrinkProduct product: list) {
if(!map.containsKey(product.category)) {
map.put(product.category, new ArrayList<>());
}
map.get(product.category).add(product);
}
return Collections.unmodifiableMap(map);
}
Map<DrinkCategory,List<DrinkProduct>> groupByCategory(
List<DrinkProduct> list) {
Map<DrinkCategory,List<DrinkProduct>> map = new HashMap<>();
for(DrinkProduct product: list) {
map.computeIfAbsent(product.category, k -> new ArrayList<>())
.add(product);
}
return Collections.unmodifiableMap(map);
}
Map<K,V>
•
• V remove(Object)
• boolean remove(Object, Object)
•
• void clear()
!
•
• (Set/List/Map)
•
UnsupportedOperationException
List<E>
• … add/remove/sort
• ArrayList<E> -
List<E>
• LinkedList<E> -
List<E>
ArrayList<E> vs
LinkedList<E>
• pros
• ArrayList<E> -
• LinkedList<E> - /
• cons
• ArrayList<E> -
• LinkedList<E> -
LinkedList Queue
Dequeue(Stack)
ArrayList LinkedList
ArrayList
List<E>
• … add/remove/sort
UnsupportedOperationException
•
• List.of(E…)
• List.copyOf(Collection<? extends E>)
• Arrays.asList(E…)
• Collections.emptyList()
• Collections.singletonList(E)
• Collections.unmodifiableList(List<? extends E>)
Set<E>/SortedSet<E>
• … add/remove
• HashSet<E> - hashCode
Set<E>
• HashMap<E, Object>
• LinkedHashSet<E> - HashSet<E> ( )
Set<E>
• LinkedHashMap<E, Object>
• TreeSet<E> - SortedSet<E> /Comparator<E>
• TreeMap<E, Object>
Set<Coffee>
Set<E> Map<K,V>
Set<Price>
350 JPY
450 JPY
550 JPY
Set<Coffee>
Set<E> Map<K,V>
Set<Price>
350 JPY
450 JPY
550 JPY
Collection<Price>
IdentifiedBy<Coffee>
Set<E> Map<K,V>
350 JPY
350 JPY
450 JPY
550 JPY
Map<Coffee,Price>
Set<E> Map<K,V>
350 JPY
350 JPY
450 JPY
550 JPY
Set<E>
• … add/remove/sort
UnsupportedOperationException
•
• Set.of(E…)
• Set.copyOf(Collection<? extends E>)
• Collections.emptySet()
• Collections.singleton(E)
• Collections.unmodifiableSet(List<? extends E>)
Map<K,V>
• … put/remove
• HashMap<K,V> - hashCode
Map<K,V>
• LinkedHashMap<K,V> - HashMap<K,V>
( )
Map<K,V>
• TreeMap<K,V> - SortedMap<K,V>
HashMap<K,V>
Map<ProductId, DrinkProduct> toMap(SortedSet<DrinkProduct> set) {
Map<ProductId, DrinkProduct> map = new HashMap<>();
for(DrinkProduct product: set) {
map.put(product.id, product);
}
return Collections.unmodifiableMap(map);
}
Map<ProductId, DrinkProduct> map = toMap(products);
map.forEach((id, product) -> System.out.println(id));
HashMap<K,V>
Map<ProductId, DrinkProduct> toMap(SortedSet<DrinkProduct> set) {
Map<ProductId, DrinkProduct> map = new LinkedHashMap<>();
for(DrinkProduct product: set) {
map.put(product.id, product);
}
return Collections.unmodifiableMap(map);
}
Map<ProductId, DrinkProduct> map = toMap(products);
map.forEach((id, product) -> System.out.println(id));
LinkedHashMap<K,V>
Map<K,V>
• … put/remove/compute
UnsupportedOperationException
•
• Map.of(K,V)
• Map.copyOf(Map<? extends K,? extends V>)
• Collections.emptyMap()
• Collections.singletonMap(K,V)
• Collections.unmodifiableMap(Map<? extends K,?
extends V>)
•
•
6
6
•
• equals/hashCode
• ( )
• (
)
• null
• null
• Map<String, ?>
I. equals/hashCode
• equals
contains(containsKey)
• Set<E> add
• HashSet hashCode
hashCode
equals
• : x.equals(x) true (x ≠ null)
• : x.equals(y) true y.equals(x) true
(x ≠ null, y ≠ null)
• : x.equals(y) true y.equals(z) true
z.equals(x) true (x ≠ null, y ≠ null, z ≠ null)
• : x.equals(y)
• x.equals(null) false (x ≠ null)
• equals NullPointerException
hashCode
• equals hashCode
• x.equals(y) true x.hashCode()
y.hashCode()
• hashCode()
• x.equals(y) false x y hashCode()
equals/hashCode
•
• IDE
•
• Lombok
•
• google/auto AutoValue
• IDE
II.
• Java 1.4 Java 5
•
List<String> List
void unsafeAdd(List list, Object o) {
list.add(o);
}
List<String> list = new ArrayList<>(List.of("foo"));
unsafeAdd(list, 100L);
for(String string : list) { // ClassCastException
String.out.println(string);
}
!
<E, F extends E> void unsafeAdd(List<? super E> list, F o) {
list.add(o);
}
List<String> list = new ArrayList<>(List.of("foo"));
unsafeAdd(list, 100L); // compile error
III.
• List<E>
(ArrayList<E>/LinkedList<E>)
(List.of()/Arrays.asList())
• Collections Framework
(add/remove/clear)
void addSomeEntry(List<String> list) {
list.add("bar"); // UnsupportedOperationException
}
List<String> list = List.of("foo");
unsafeAdd(list);
!
•
UnsupportedOperationException
•
• ( )
• ArrayList<E>/
LinkedList<E>
•
List<String> someEntry() {
return List.of("bar"); //
}
List<String> list = new ArrayList<>(List.of(“foo"));
list.addAll(someEntry());
IV. null
• null
• ArrayList<E>/LinkedList<E>/Arrays.asList()/
HashSet<E>/HashMap<K,V>
• null
• List.of()/Set.of()/Map.of() /
TreeSet<E>/TreeMap<E>
• API
null
List<String> someEntry() {
List<String> list = new ArrayList<>();
list.add(null);
list.add("foo");
return list;
}
List<String> list = new ArrayList<>(List.of(“bar"));
list.addAll(someEntry());
return List.copyOf(list)); // NullPointerException
!
null
: null add
( )
List<String> someEntry() {
List<String> list = new ArrayList<>();
list.add("foo");
return list;
}
List<String> list = new ArrayList<>(List.of("bar"));
list.addAll(someEntry());
return List.copyOf(list));
null
: ArrayList
findbugs/spotbugs
class ListBuilder<E>{
final List<E> list = new ListBuilder<>();
final add(@Nonnull E e) {
list.add(e);
}
}
List<String> someEntry() {
ListBuilder<String> listBuilder = new ListBuilder<>();
listBuilder.add("foo");
return listBuilder.getList();
}
V.
null
• IV
•
null
List<String> someEntries(Key key) {
return map.get(key);
}
List<String> list = someEntries();
return list.size(); // NullPointerException
!
null
List<String> someEntries(Key key) {
return map.getOrDefault(key, Collections.emptyList());
}
List<String> list = someEntries();
return list.size(); // 0
VI.
Map<String,Object>
• Map<String,Object>
• Map<String,Object>
•
Map<String,Object>
PUT /users/1234
{“type":"image",
"file":"https://example.com/files/123"}
PUT /users/1234
{"type":"fields",
"name":" ",
"color":"#009933"}
Map<String,Object>
void updateProfile(UserId userId, Map<String,Object> newProfile) {
if(newProfile.get("type") != null &&
newProfile.get("type").equals("image")) {
String file = (String) newProfile.get("file");
if(file == null) {
throw new IllegalArgumentException("invalid parameter");
}
updateProfileImage(userId, newProfile);
} else if(newProfile.get("type") != null &&
newProfile.get(“type").equals("fields")) {
String name = (String) newProfile.get("name");
String color = (String) newProfile.get("color");
String url = (String) newProfile.get("url");
updateNameAndColor(userId, name, color, url);
!
Map<String,Object>
void updateProfileImage(UserId userId, NewProfileImage newProfileImage) {
if(newProfileImage.notHavingImageUrl()) {
throw new IllegalArgumentException("invalid parameter");
}
Optional<ProfileImageUrl> currentUrl = imageRepository.findProfileImageUrl(userId);
if(currentUrl.filter(url -> url.sameUrl(newProfileImage)).isPresent()) {
imageRepository.update(newProfileImage);
}
}
void updateProfileImage(UserId userId, NewProfileFields newProfileFields) {
if(newProfileFields.satisfiesCondition(satisfiesCondition())) {
throw new IllegalArgumentException("invalid parameter");
}
profileRepository.update(newProfileFields);
}
…
•
Acroquest Technology Java (
2017 )
• Joshua Bloch Effective Java 3
( 2018 )
• (Web) Dan Becker, HOW-TO Get started with the
Java Collections Framework(JAVA WORLD FROM IDG,
1998, https://www.javaworld.com/article/2076800/
get-started-with-the-java-collections-
framework.html)
1. ArrayList
ArrayList<E>
(Object[])
add(int, E)
ArrayList<E>
ArrayList<E>
ArrayList<E>
2. LinkedList
LinkedList<E>
previous
next
previous
next
previous
next
first last
Node<E>
LinkedList Node<E>
LinkedList<E>
previous
next
previous
next
previous
next
add(int, E)
LinkedList<E>
previous
next
previous
next
previous
next
Node<E>
previous
next
LinkedList<E>
previous
next
previous
next
previous
next
(next/previous)
previous
next
3. ArrayList vs
LinkedList
ArrayList vs LinkedList
add(E) - throughput/ms
ArrayList
LinkedList
JDK: oracle openjdk 12.0.1 / OS: Amazon Linux2 /
: m5a.large / : Xmx256M,Xms256M
ArrayList vs LinkedList
add(0,E) - throughput/ms
ArrayList
LinkedList
JDK: oracle openjdk 12.0.1 / OS: Amazon Linux2 /
: m5a.large / : Xmx256M,Xms256M
ArrayList vs LinkedList
get(int) - throughput/ms
ArrayList
LinkedList
JDK: oracle openjdk 12.0.1 / OS: Amazon Linux2 /
: m5a.large / : Xmx256M,Xms256M
ArrayList vs LinkedList
forEach(Consumer) - throughput/ms
ArrayList
LinkedList
JDK: oracle openjdk 12.0.1 / OS: Amazon Linux2 /
: m5a.large / : Xmx256M,Xms256M
4. HashMap
HashMap<E>
Node
K key
int hash/K key/V value Node
int hash
V value
next
HashMap<E>
Node (Node[])
length
HashMap<E>
Node index Node hash
mod
Node
hash
length
index
HashMap<E>
index LinkedList
next next
HashMap<E>
index LinkedList
next next
LinkedList
HashMap<E>
LinkedList
hashCode
B
R
left
right
R
5. TreeMap
TreeMap<K,V>
• TreeMap<K,V>
•
•
• K key V value
•
•
• ( )
TreeMap<K,V>
•
• ( )
•
•
•
•
TreeMap<K,V>
74
3
key:
value:
4
key:4 key:7
4 7
TreeMap<K,V>
7
3
key:
value:
4
key:3 key:7
key:3 key:4
3
TreeMap<K,V>
7
key:
value:
4
3
TreeMap<K,V>
7
4
3
← (4)
4
73

jjug-ccc 2019 Spring 発表資料 Collections Framework 入門 #jjug #jjug_ccc #ccc_c1