Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[모던 자바 인 액션] 4주차 #6

Open
jeongminkyo opened this issue Jul 20, 2023 · 3 comments
Open

[모던 자바 인 액션] 4주차 #6

jeongminkyo opened this issue Jul 20, 2023 · 3 comments
Assignees
Labels
SummerCoding 땅울림 여름코딩 스터디 모던 자바 인 액션

Comments

@jeongminkyo
Copy link

jeongminkyo commented Jul 20, 2023

@jeongminkyo jeongminkyo self-assigned this Jul 20, 2023
@jeongminkyo jeongminkyo added SummerCoding 땅울림 여름코딩 스터디 모던 자바 인 액션 labels Jul 20, 2023
@jeongminkyo
Copy link
Author

자바 8, 9 - 컬렉션 API 개선

1. 컬렉션 팩토리

1-1. List 팩토리

List.of(E e, ..)

@DisplayName("List 팩토리 사용")
@Test
void list_factory_test() {
    List<String> coffeeList = List.of("메가커피", "스타벅스", "빽다방");
    System.out.println("coffeeList = " + coffeeList);
}

// 결과
coffeeList = [메가커피, 스타벅스, 빽다방]

1-2. Set 팩토리

Set.of(E e, ..)

@DisplayName("Set 팩토리 사용")
@Test
void set_factory_test() {
    Set<String> coffeeSet = Set.of("메가커피", "스타벅스", "빽다방");
    System.out.println("coffeeSet = " + coffeeSet);
}

// 결과
coffeeSet = [메가커피, 빽다방, 스타벅스]

1-3. Map 팩토리

Map.of(key, value, ..)Map.ofEntries(Entry<? extends K, ? extends V>... entries)

@DisplayName("Map 팩토리 사용")
@Test
void map_factory_test() {
    Map<String, Integer> coffeeOfMap = Map.of("메가커리", 1500, "스타벅스", 3500, "백다방", 2000);
    Map<String, Integer> coffeOfEntiriesMap = Map.ofEntries(
            Map.entry("메가커리", 1500),
            Map.entry("스타벅스", 3500),
            Map.entry("백다방", 2000)
    );
    System.out.println("coffeeOfMap = " + coffeeOfMap);
    System.out.println("coffeOfEntiriesMap = " + coffeOfEntiriesMap);
}

// 결과
coffeeOfMap = {스타벅스=3500, 백다방=2000, 메가커리=1500}
coffeOfEntiriesMap = {스타벅스=3500, 백다방=2000, 메가커리=1500}

 열 개 이하의 key와 value를 가진 작은 크기의 Map을 만들 때는 Map.of가 유용하고, 그 이상의 Map을 만들 때는 가변 인수로 Map.Entry<K, V> 객체를 인수로 받는 Map.ofEntries를 사용하는 것이 좋다.

1-4. 주의사항

  • 생성된 Collection에 추가, 삭제, 수정이 불가하다.
  • 파라미터로 전달한 요소(Element)들은 null이면 안된다.
  • Collection에서 지원하는 메서드 파라미터로 전달한 요소들 또한 null이면 안된다.

컬렉션 팩토리로 만들어진 컬렉션에 추가, 삭제, 변경 시 UnsupportedOperationException 예외가 발생한다.

@DisplayName("팩토리로 만들어진 컬렉션에 추가 시 예외")
@Test
void list_factory_ex_test1() {
    List<String> coffeeList = List.of("메가커피", "스타벅스", "빽다방");
    assertThrows(UnsupportedOperationException.class, () -> coffeeList.add("이디야"));
}

@DisplayName("팩토리로 만들어진 컬렉션에 요소 삭제 시 예외")
@Test
void list_factory_ex_test2() {
    List<String> coffeeList = List.of("메가커피", "스타벅스", "빽다방");
    assertThrows(UnsupportedOperationException.class, () -> coffeeList.remove("스타벅스"));
}

@DisplayName("팩토리로 만들어진 컬렉션에 요소 수정 시 예외")
@Test
void list_factory_ex_test3() {
    List<String> coffeeList = List.of("메가커피", "스타벅스", "빽다방");
    assertThrows(UnsupportedOperationException.class, () -> coffeeList.set(1, "이디야"));
}

두 번째로 컬렉션 팩토리의 파라미터로 전달한 요소들이 null이면 NullPointerException 예외가 발생한다.

@DisplayName("팩토리의 파라미터로 null을 전달 시 예외")
@Test
void list_factory_ex_test4() {
    assertThrows(NullPointerException.class, () -> List.of("메가커피", "스타벅스", "빽다방", null));
}

세 번째로는 컬렉션에서 제공하는 메서들 또한 파라미터의 값이 null 일 경우 NullPointerException 예외가 발생한다.

@DisplayName("컬렉션에서 제공하는 메서드의 파라미터로 null을 전달 시 예외")
@Test
void list_factory_ex_test5() {
    List<String> coffeeList = List.of("메가커피", "스타벅스", "빽다방");
    assertThrows(NullPointerException.class, () -> coffeeList.contains(null));
}

2. List와 Set에 추가된 메서드

2-1. removeIf(Predicate<? super E> filter)

 Predicate에 만족하는 요소들을 제거하며 List나 Set을 상속받은 모든 클래스에서 사용할 수 있다. removeIf 메서드가 추가가 되어 코드의 가독성이 향상되었다.

아래 예시 코드는 자바 9 이전에는 어떻게 제거했는지와 현재 자바 9 버전 이상에서 사용되는 removeIf를 이용한 예제 코드이다.

@DisplayName("리스트 컬렉션의 removeIf")
@Test
void list_removeIf() {
    // ** 자바 9 이전 코드 **
    // List의 특정 요소 제거
    List<String> coffeeList1 = new ArrayList<>();
    coffeeList1.add("메거커피");
    coffeeList1.add("스타벅스");
    coffeeList1.add("빽다방");

    for (String s : coffeeList1) {
        if (s.equals("스타벅스")) {
            coffeeList1.remove("스타벅스");
        }
    }

    assertThat(coffeeList1.size()).isEqualTo(2);
    assertThat(coffeeList1).isNotEqualTo("스타벅스");


    // ** 자바 9 이후 코드 **
    // List의 특정 요소 제거
    List<String> coffeeList2 = new ArrayList<>();
    coffeeList2.add("메거커피");
    coffeeList2.add("스타벅스");
    coffeeList2.add("빽다방");

    coffeeList2.removeIf(name -> name.equals("스타벅스"));

    assertThat(coffeeList2.size()).isEqualTo(2);
    assertThat(coffeeList2).isNotEqualTo("스타벅스");
}

2-2. replaceAll(UnaryOperator operator)

 List에서 추가된 기능으로 UnaryOperator 함수를 이용해 요소를 변경해 준다.

@Test
void list_replaceAll() {
    List<String> coffeeList = new ArrayList<>();
    coffeeList.add("메가커피");
    coffeeList.add("스타벅스");
    coffeeList.add("빽다방");

    coffeeList.replaceAll(coffee -> coffee + " 가맹점");
    System.out.println("coffeeList = " + coffeeList);
}

// 결과
coffeeList = [메가커피 가맹점, 스타벅스 가맹점, 빽다방 가맹점]

 Stream을 이용해도 각 요소를 새로운 요소로 변경할 수 있지만 Stream은 새로운 컬렉션을 만들기 때문에 불필요한 자원낭비의 원인이 된다. 따라서 Stream을 사용해야 될 이유가 없으면 replaceAll을 사용하는 것을 추천한다.

3. Map 관련 메서드

3-1. forEach(BiConsumer<? super K, ? super V> action)

 Map에서도 forEach 메서드를 사용하여 코드의 가독성을 높일 수 있다.

@DisplayName("Map forEach 메서드 사용하기 이전 코드")
@Test
void map_for_each() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2000);

    for (Map.Entry<String, Integer> entry : coffeeMap.entrySet()) {
        String coffee = entry.getKey();
        Integer price = entry.getValue();
        System.out.println("coffeeMap = " + coffee + ":" + price);
    }
}

@DisplayName("Map forEach 메서드를 사용한 코드")
@Test
void map_forEach() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2000);

    coffeeMap.forEach((coffee, price) -> System.out.println("coffeeMap = " + coffee + ":" + price));
}

// 결과
coffeeMap = 빽다방:2000
coffeeMap = 메가커피:2000
coffeeMap = 스타벅스:3500

3-2. 정렬 메서드

 Map에서는 두 개의 새로운 유틸리티를 사용하여 key 또는 value를 기준으로 정렬할 수 있다.

Entry.comparingByKey

@DisplayName("Map key, value 중심으로 정렬")
@Test
void map_comparing_by_key() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    // 기존 정렬 순서
    System.out.println("coffeeMap = " + coffeeMap);

    // key 기준으로 정렬
    coffeeMap.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .forEachOrdered(System.out::println);
}

// 결과
메가커피=2000
빽다방=2100
스타벅스=3500

Entry.comparingByValue

@DisplayName("Map key, value 중심으로 정렬")
@Test
void map_comparing_by_key() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    // 기존 정렬 순서
    System.out.println("coffeeMap = " + coffeeMap);

    // value 기준으로 정렬
    coffeeMap.entrySet().stream()
            .sorted(Map.Entry.comparingByValue())
            .forEachOrdered(System.out::println);
}

// 결과
메가커피=2000
빽다방=2100
스타벅스=3500

3-3. getOrDefault 메서드

 이전에는 Map에 해당하는 key가 존재하지 않으면 null이 반환되므로 NullpointerException을 방지하기 위한 코드가 필요했지만 현재는 getOrDefault 메서드를 사용하여 Key가 없을 경우 Default 값을 반환하여 NullpointerException을 방지하는 코드를 작성하지 않아도 된다.

 첫 번째 인수를 key값을 받고, 두 번째는 Map에 해당 key가 없을 경우 반환하는 인수를 받는다.

@DisplayName("Map - getOrDefault 메서드")
@Test
void map_getOrDefault_test() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    // Map key에 메가커피가 있으므로 2000이 반환된다.
    Integer megaCoffePrice = coffeeMap.getOrDefault("메가커피", 1500);
    System.out.println("megaCoffePrice = " + megaCoffePrice);

    // Map key에 이디야가 없으므로 두 번째 인수로 받은 값인 3200이 반환된다.
    Integer ediyaPrice = coffeeMap.getOrDefault("이디야", 3200);
    System.out.println("ediyaPrice = " + ediyaPrice);

    // getOrDefault 를 사용하지 않은 코드는 다음과 같다.
    Integer ediyaPriceByGet = coffeeMap.get("이디야");
    if (ObjectUtils.isEmpty(ediyaPriceByGet)) {
        ediyaPriceByGet = 3200;
    }
    System.out.println("ediyaPriceByGet = " + ediyaPriceByGet);
}

// 결과
megaCoffePrice = 2000
ediyaPrice = 3200
ediyaPriceByGet = 3200

3-4. 계산 관련 메서드

 Map에 키가 존재하지는 여부에 따라 특정 동작을 실행하고 결과를 저장해야 하는 상황이 필요한 경우가 많다. Map에는 이러한 연산을 도와주는 세 가지 메서드가 존재한다.

computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)

 key에 해당되는 값이 없으면 Map에 추가해 주는 메서드이다. 첫 번째 인자로 key를 받고, 두 번째 인자로는 첫 번째 인자로 받은 key에 해당되는 값이 Map에 없을 경우 value 값을 생성하여 추가해 준다.

@DisplayName("Map - 계산 관련 메서드")
@Test
void map_computeIfAbsent() {
    Map<String, Integer> coffeeMap = new HahMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    // key(이디야)가 Map에 없으므로 Map에 추가해준다.
    // coffeeMap.put("이디야", 3200) 실행
    coffeeMap.computeIfAbsent("이디야", coffee -> 3200);

    System.out.println("coffeeMap = " + coffeeMap);
}

// 결과
coffeeMap = {빽다방=2100, 메가커피=2000, 스타벅스=3500, 이디야=3200}

computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

 key에 해당되는 값이 Map 존재하며 value 값이 null이 아닌 경우에만 새로운 value를 넣어주는 메서드이다. 

@DisplayName("Map - 계산 관련 메서드3")
@Test
void map_computeIfPresent1() {
    Map<String, List<Integer>> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", new ArrayList<>());
    coffeeMap.put("스타벅스", null);
    coffeeMap.put("빽다방", new ArrayList<>());

    List<Integer> addList = new ArrayList<>();
    addList.add(2000);
    addList.add(3000);

    // 메가커피의 value가 null이 아니므로 addList가 추가된다.
    coffeeMap.computeIfPresent("메가커피", (coffee, price) -> addList);
    // 스타벅스의 value가 null이므로 해당 메서드는 실행되지 않는다.
    coffeeMap.computeIfPresent("스타벅스", (coffee, price) -> addList);

    System.out.println("coffeeMap = " + coffeeMap);
}

// 결과
coffeeMap = {빽다방=[], 메가커피=[2000, 3000], 스타벅스=null}

compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

 computeIfPresent와는 달리 key에 해당되는 value의 값이 null이어도 실행된다. 즉, value가 null이든 아니든 상관없이 실행되는 메서드이다.

@DisplayName("Map - 계산 관련 메서드4")
@Test
void map_compute1() {
    Map<String, List<Integer>> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", new ArrayList<>());
    coffeeMap.put("스타벅스", null);
    coffeeMap.put("빽다방", new ArrayList<>());

    List<Integer> addList = new ArrayList<>();
    addList.add(2000);
    addList.add(3000);

    // 실행 된다.
    coffeeMap.compute("메가커피", (coffee, price) -> addList);
    // 실행 된다.
    coffeeMap.compute("스타벅스", (coffee, price) -> addList);

    System.out.println("coffeeMap = " + coffeeMap);
}

// 결과
coffeeMap = {빽다방=[], 메가커피=[2000, 3000], 스타벅스=[2000, 3000]}

3-5. remove(key), remove(key, value)

 Map 역시 remove 메서드를 통해 해당되는 값을 Map에서 제거할 수 있다. 인자로 key만 받는 remove(key) 메서드는 key값이 동일할 경우 제거하는 메서드이고, 인자로 key, value 모두 받는 remove(key, value) 메서드는 key와 value 값이 모두 동일할 경우 제거하는 메서드이다.

@DisplayName("Map - remove")
@Test
void map_remove() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    // 메가커피 key가 존재하므로 제거
    coffeeMap.remove("메가커피");
    // 스타벅스 key가 존재하고, value 값이 동일하므로 제거
    coffeeMap.remove("스타벅스", 3500);
    // 빽다방 key가 존재하지만 value 값이 동일하지 않으므로 제거되지 않는다.
    coffeeMap.remove("빽다방", 2200);

    System.out.println("coffeeMap = " + coffeeMap);
}

// 결과
coffeeMap = {빽다방=2100}

3-6. replaceAll(BiFunction<? super K, ? super V, ? extends V> function)

 List에서 사용했던 메서드와 비슷하다. BiFunction에 적용된 결과로 각 항목의 값을 변경한다.

@DisplayName("Map - replaceAll")
@Test
void map_replaceAll() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    coffeeMap.replaceAll((coffee, price) -> price + 500);
    System.out.println("coffeeMap = " + coffeeMap);
}

// 결과
coffeeMap = {빽다방=2600, 메가커피=2500, 스타벅스=4000}

3-7. replace(K key, V value), replace(K key, V oldValue, V newValue)

 키가 존재하면 해당되는 값을 변경한다. replace(K key, V oldValue, V newValue)의 경우는 key와 oldValue 값이 모두 일치할 경우 newValue 값으로 변경한다.

@DisplayName("Map - replace")
@Test
void map_replace() {
    Map<String, Integer> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", 2000);
    coffeeMap.put("스타벅스", 3500);
    coffeeMap.put("빽다방", 2100);

    // 메가커피인 key를 찾아 value를 2500으로 변경
    coffeeMap.replace("메가커피", 2500);
    System.out.println("coffeeMap = " + coffeeMap);

    // 스타벅스인 key를 찾아 value가 3000인 경우 4000으로 변경
    // oldValue가 3000이기 때문에 실행되지 않는다.
    coffeeMap.replace("스타벅스", 3000, 4000);
    System.out.println("coffeeMap = " + coffeeMap);

    // 스타벅스인 key를 찾아 value가 3000인 경우 4000으로 변경
    // value가 3500이기 때문에 실행된다.
    coffeeMap.replace("스타벅스", 3500, 4000);
    System.out.println("coffeeMap = " + coffeeMap);
}

// 결과
coffeeMap = {빽다방=2100, 메가커피=2500, 스타벅스=3500}
coffeeMap = {빽다방=2100, 메가커피=2500, 스타벅스=3500}
coffeeMap = {빽다방=2100, 메가커피=2500, 스타벅스=4000}

3-8. merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

 merge 메서드는 2개의 Map을 합칠 때, 중복된 key가 있을 경우 처리하는 메서드이다.

@DisplayName("Map - merge")
@Test
void map_merge() {
    Map<String, List<Integer>> coffeeMap = new HashMap<>();
    coffeeMap.put("메가커피", new ArrayList<>());
    coffeeMap.get("메가커피").add(2000);
    coffeeMap.put("스타벅스", new ArrayList<>());
    coffeeMap.get("스타벅스").add(3500);
    coffeeMap.put("빽다방", new ArrayList<>());
    coffeeMap.get("빽다방").add(2100);

    Map<String, List<Integer>> coffeeMap2 = new HashMap<>();
    coffeeMap2.put("메가커피", new ArrayList<>());
    coffeeMap2.get("메가커피").add(3000);
    coffeeMap2.put("스타벅스", new ArrayList<>());
    coffeeMap2.get("스타벅스").add(4500);

    coffeeMap.forEach((k, v) -> {
        coffeeMap2.merge(k, v, (price1, price2) -> {
            System.out.println("price1 = " + price1);
            System.out.println("price2 = " + price2);
            price1.addAll(price2);
            return price1;
        });
    });

    System.out.println("coffeeMap2 = " + coffeeMap2);
}

// 결과
price1 = [3000]
price2 = [2000]
price1 = [4500]
price2 = [3500]
coffeeMap2 = {빽다방=[2100], 메가커피=[3000, 2000], 스타벅스=[4500, 3500]}

@so3500
Copy link
Contributor

so3500 commented Jul 20, 2023

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class CollectionApiTest {

	@DisplayName("computeIfAbsent 가 없을 때")
	@Test
	void mapTest1() {
		//given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";

		//when
		List<String> movies = friendsToMovies.get(friend);
		if (movies == null) {
			movies = new ArrayList<>();
			friendsToMovies.put(friend, movies);
		}
		movies.add("Star Wars");

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).contains("Star Wars");

	}

	@DisplayName("computeIfAbsent 사용 시")
	@Test
	void mapTest2() {
		// given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";

		//when
		friendsToMovies.computeIfAbsent(friend, k -> new ArrayList<>()).add("Star Wars");

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).contains("Star Wars");
	}

	@DisplayName("computeIfPresent 가 없을 때")
	@Test
	void mapTest3() {
		//given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";
		friendsToMovies.put(friend, new ArrayList<>());

		//when
		List<String> movies = friendsToMovies.get(friend);
		if (movies != null) {
			movies.add("Star Wars");
		}

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).contains("Star Wars");
	}

	@DisplayName("computeIfPresent 사용 시")
	@Test
	void mapTest4() {
		//given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";
		friendsToMovies.put(friend, new ArrayList<>());

		//when
		friendsToMovies.computeIfPresent(friend, (k, v) -> {
			v.add("Star Wars");
			return v;
		});

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).contains("Star Wars");
	}

	@DisplayName("computeIfPresent 사용 시 - null")
	@Test
	void mapTest5() {
		//given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";

		//when
		friendsToMovies.computeIfPresent(friend, (k, v) -> {
			v.add("Star Wars");
			return v;
		});

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).isNull();
	}

	@DisplayName("compute 가 없을 때")
	@Test
	void mapTest6() {
		//given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";
		friendsToMovies.put(friend, new ArrayList<>());

		//when
		List<String> movies = friendsToMovies.get(friend);
		movies.add("Star Wars");

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).contains("Star Wars");
	}

	@DisplayName("compute 사용시")
	@Test
	void mapTest7() {
		//given
		Map<String, List<String>> friendsToMovies = new HashMap<>();
		String friend = "Tom";
		friendsToMovies.put(friend, new ArrayList<>());

		//when
		friendsToMovies.compute(friend, (k, v) -> {
			v.add("Star Wars");
			return v;
		});

		//then
		Assertions.assertThat(friendsToMovies.get("Tom")).contains("Star Wars");
	}
}

@s5646s
Copy link
Contributor

s5646s commented Jul 21, 2023


marp: true
theme: gaia
class: invert
paginate: true

Modern Java in Action

Week 4
발표자: 최승위


#이번 주 범위

  • 7장: 병렬 데이터 처리와 성능
  • 8장: 컬렉션 API 개선

7장에서 인상 깊게 본 문장들

  • 올바른 자료구조를 선택해야 병렬 실행도 최적의 성능을 발휘할 수 있다. (p.250)

7장에서 인상 깊게 본 문장들

  • 병렬화는 완전 공짜가 아니다. 멀티코어 간의 데이터 이동은 생각보다 비싸다 (p.251)

7장에서 인상 깊게 본 문장들

  • 병럴 스트림이 올바르게 동작하려면 공유된 가변 상태를 피해야만 한다. (p.252)

7장에서 인상 깊게 본 문장들

  • 포크/조인 프레임워크를 사용할 때 각 서브태스크의 실행시간은 새로운 태스크를 포킹하는 데 드는 시간보다 길어야 한다. (p.260)

7장에서 인상 깊게 본 문장들

  • Spliterator는 스트림을 어떻게 병렬화할 것인지 정의한다. (p.263)

8장에서 인상 깊게 본 문장들

  • 컬렉션 API의 부가적인 기능들을 통해 List, Set, Map을 간단히 생성할 수 있다. (p. 276)
  • 이들 컬렉션 팩토리가 반환한 객체는 만들어진 다음 바꿀 수 없다.

8장에서 인상 깊게 본 문장들

  • 컬렉션 인터페이스에서 removeIf, replaceAll, sort 와 같은 기능이 추가되었다. (p.280)

8장에서 인상 깊게 본 문장들

  • 싱글 쓰레드 환경이면 HashMap을, 멀티 쓰레드 환경이면 HashTable이 아닌 ConcurrentHashMap을 쓰자
  • HashTable보다 ConcurrentHashMap이 성능적으로 우수하기 때문이다

week4.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SummerCoding 땅울림 여름코딩 스터디 모던 자바 인 액션
Projects
None yet
Development

No branches or pull requests

3 participants