Java SE 9๋ถํฐ Collection ๊ฐ์ฒด๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์๋ Collection Factory Method๋ฅผ ์ง์ํ๋ค.
Immutable(๋ถ๋ณ์) List๋ฅผ ๋ง๋ค์ด์ ์์ ์ด๋ ์ถ๊ฐ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
List<String> friends = List.of("Raphael", "Olivia", "Thibaut");
-- java.lang.UnsupportedOperationException ๋ฐ์
friends.add("Chih-Chun");
Immutable Set์ ๋ง๋ค๋ฉฐ ์ค๋ณต๋ ์์๊ฐ ์์ผ๋ฉด IllegalArgumentException์ด ๋ฐ์ํ๋ค.
Set<String> friends = Set.of("Raphael", "Olivia", "Thibaut");
Immutable Map์ ๋ง๋ ๋ค.
-- ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ
Map<String, Integer> ageOfFriends = Map.of("Rahael", 30, "Olivia", 25, "Thibaut", 26);
-- ๋๋ฒ์งธ ๋ฐฉ๋ฒ
Map<String, Integer> ageOfFriends =
Map.ofEntries(
Map.entry("Raphael", 30),
Map.entry("Olivia", 25),
Map.entry("Thibaut", 26));
๋ค์์ Java SE 8์์ List, Set Interface์ ์ถ๊ฐ๋ ๋ฉ์๋์ด๋ค.
List/Set์์ Predicate๋ฅผ ๋ง์กฑํ๋ ์์๋ฅผ ์ ๊ฑฐํ๋ค.
transactions.removeIf(transaction -> transaction.getVale() < 500);
List์์ UnaryOperator ํจ์๋ฅผ ์ด์ฉํด ์์๋ฅผ ๋ฐ๊พผ๋ค.
referenceCodes.replaceAll(code -> Character.toUpperCase(code.charAt(0)) + code.substring(1));
List์์ ์์๋ค์ ์ ๋ ฌํ๋ค.
referenceCodes.sort(Comparator.comparing(String::toString));
Java SE 8์์ Map Interface์ ์ฌ๋ฌ Default Method๊ฐ ์ถ๊ฐ๋์๋ค.
BiConsumer(Key, Value)๋ฅผ ์ธ์๋ก ๋ฐ์ ๋ฐ๋ณตํ๋ค.
ageOfFriends.forEach((name, age) -> {
System.out.println(name + " is " + age + " years old");
});
Map์ ํญ๋ชฉ์ ๊ฐ ๋๋ ํค๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ ์ ์๋ค.
Map<String, String> favouriteMovies =
Map.ofEntries(
Map.entry("Raphael", "Star Wars"),
Map.entry("Cristina", "Matrix"),
Map.entry("Olivia", "James Bond"));
favouriteMovies
.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(System.out::println);
ํค๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด Null์ ๋ฐํํ๋ฏ๋ก NullPointerException์ ๋ฐฉ์งํ๊ธฐ ์ํด Null Check๋ฅผ ํด์ผ๋ง ํ๋ค. getOrDefault() ๋ฉ์๋๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ํค๋ฅผ ๋ ๋ฒ์งธ ์ธ์๋ก ๊ธฐ๋ณธ๊ฐ์ ๋ฐ์, Map์ ํค๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ ๋ฐํํ๋ค.
favouriteMovies.getOrDefault("Olivia", "Matrix");
favouriteMovies.getOrDefault("Thibaut", "Matrix");
์ ๊ณต๋ ํค์ ํด๋นํ๋ ๊ฐ์ด ์์ผ๋ฉด, ํค๋ฅผ ์ด์ฉํด ์ ๊ฐ์ ๊ณ์ฐํ๊ณ ๋งต์ ์ถ๊ฐํ๋ค.
Map<String, List<String>> friendsToMovies = new HashMap<>();
String friend = "Raphael";
friendsToMovies.computeIfAbsent(friend, name -> new ArrayList<>()).add("Star Wars");
์ ๊ณต๋ ํค๊ฐ ์กด์ฌํ๋ฉด ์ ๊ฐ์ ๊ณ์ฐํ๊ณ ๋งต์ ์ถ๊ฐํ๋ค.
friendsToMovies.computeIfPresent(friend, (s, strings) -> {
strings.add("Matrix");
return strings;
});
ํค๊ฐ ํน์ ํ ๊ฐ๊ณผ ์ฐ๊ด๋์์ ๋๋ง ํญ๋ชฉ์ ์ ๊ฑฐํ๋ overload ๋ฒ์ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
favouriteMovies.remove(key, value)
BiFunction์ ์ ์ฉํ ๊ฒฐ๊ณผ๋ก ๊ฐ ํญ๋ชฉ์ ๊ฐ์ ๊ต์ฒดํ๋ค.
Map<String, String> favouriteMovies = new HashMap<>();
favouriteMovies.put("Raphael", "Star Wars");
favouriteMovies.put("Olivia", "james bond");
favouriteMovies.replaceAll((name, movie) -> movie.toUpperCase());
ํค๊ฐ ์กด์ฌํ๋ฉด ๋งต์ ๊ฐ์ ๋ฐ๊พธ๋ฉฐ, ํค๊ฐ ํน์ ๊ฐ์ผ๋ก ๋งคํ๋์์ ๋๋ง ๊ฐ์ ๊ต์ฒดํ๋ overload ๋ฒ์ ๋ ์๋ค.
favouriteMovies.replace("Olivia", "JAMES BOND", "TOTORO");
๋ ๊ฐ์ ๋งต์ ํฉ์น๋ฉฐ, ์ค๋ณต๋ ํค๋ ๋ฎ์ด์ด๋ค.
Map<String, String> family = Map.ofEntries(
Map.entry("Teo", "Star Wars"),
Map.entry("Cristina", "James Bond")
);
Map<String, String> friends = Map.ofEntries(
Map.entry("Raphael", "Star Wars"),
Map.entry("Cristina", "Matrix")
);
Map<String, String> everyone = new HashMap<>(family);
everyone.putAll(friends);
๋ ๊ฐ์ ๋งต์ ํฉ์น๋ฉฐ, ์ค๋ณต๋ ํค๋ฅผ ์ด๋ป๊ฒ ํฉ์น ์ง BiFunction์ ์ธ์๋ก ๋ฐ๋๋ค.
friends.forEach((k, v) -> everyone.merge(k, v, (movie1, movie2) -> movie1 + " & " + movie2));
-- ์ํ ์์ฒญ ๊ธฐ๋ก
Map<String, Long> moviesToCount = new HashMap<>();
String movieName= "James Bond";
moviesToCount.merge(movieName, 1L, (key, count) -> count + 1L);
ConcurrentHashMap์ ๋์์ฑ ์นํ์ ์ด๋ฉฐ, ํน์ ๋ถ๋ถ๋ง ์ ๊ถ ๋์ ์ถ๊ฐ/๊ฐฑ์ ์์ ์ ํ์ฉํ๋ค. ๋๊ธฐํ๋ Hashtable ๋ฒ์ ์ ๋นํด ์ฝ๊ธฐ ์ฐ๊ธฐ ์ฐ์ฐ ์ฑ๋ฅ์ด ์๋ฑํ๋ฉฐ, HashMap๊ณผ ๋ฌ๋ฆฌ Multi-Thread ํ๊ฒฝ์์ ์ฌ์ฉ๊ฐ๋ฅํ๋ค.
ConcurrentHashMap์ ์ธ ๊ฐ์ง ์๋ก์ด ์ฐ์ฐ์ ์ง์ํ๋ฉฐ, ์๋์ ๊ฐ์ด ๋ค ๊ฐ์ง ์ฐ์ฐ ํํ๋ฅผ ์ง์ํ๋ค.
(ํค, ๊ฐ) | ํค | ๊ฐ | Map.Entry |
---|---|---|---|
forEach | forEachKey | forEachValue | forEachEntry |
reduce | reduceKeys | reduceValues | reduceEntries |
search | searchKeys | searchValues | searchEntries |
์ ์ฐ์ฐ๋ค์ ConcurrentHashMap์ ์ํ ์ ๊ธ์ ํ์ง ์๊ณ ์ํ๋๋ฉฐ, ์ธ์๋ก ์ ๊ณต๋ ํจ์๋ ๊ฐ์ฒด, ๊ฐ, ์์ ๋ฑ์ ์์กดํด์๋ ์๋๋ค.
๋ํ ๋ณ๋ ฌ์ฑ ๊ธฐ์ค๊ฐ์ ์ง์ ํ ์ ์์ผ๋ฉฐ, ๊ธฐ์ค๊ฐ์ 1๋ก ์ง์ ํ๋ฉด ๊ณตํต Thread Pool์ ์ด์ฉํด ๋ณ๋ ฌ์ฑ์ ๊ทน๋ํํ๋ค.
ConcurrentHashMap<String, Long> map = new ConcurrentHashMap<>();
long parallelismThreshold = 1;
Optional<Long> maxValue = Optional.ofNullable(map.reduceValues(parallelismThreshold, Long::max));
int ๋ฒ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๊ธฐ์กด์ size ๋ฉ์๋ ๋์ , long ๋ฒ์์ ConcurrentHashMap์ ๋งคํ ๊ฐ์๋ฅผ ๋ฐํํ๋ mappingCount ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
ConcurrentHashMap์ ์งํฉ ๋ทฐ๋ก ๋ฐํํ๋ keySet ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.