[Java] Know your java

2025. 5. 9. 19:37·Language/Java
반응형
  • 유튜브의 알고리즘에 나와서 봤던 영상을 보고 정리 유튜브 링크
  • 자바 코드를 작성할 때 주의하지 않으면 발생할 수 있는 문제들을 예시코드로 보여주고 설명해준다.
  • 이런걸 stub toe problem이라고 표현하는게 재미있다.
  • 예시 코드를 보여주고 결과를 예측해보라고 할 때 나도 풀어봤는데 그래도 얼추 맞추긴 했다.
  • 그래도 평소 신경쓰지 않았던 부분들을 다시 공부할 수 있었다.

Remove 메서드

// List 예제
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
System.out.println(numbers); // 출력: [1, 2, 3]
numbers.remove(1); // 인덱스 1의 요소(2)를 제거
System.out.println(numbers); // 출력: [1, 3]

// 타입을 Collection으로 변경
Collection<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
System.out.println(numbers); // 출력: [1, 2, 3]
numbers.remove(1); // 값이 1인 요소를 제거
System.out.println(numbers); // 출력: [2, 3]
  • List와 Collection의 API 차이로 발생한 출력값 변경
    • List에서 remove(1)을 호출하면 인덱스 1의 원소 제거
    • 하지만 Collection에서 remove(1)을 호출하면 값이 1인 원소를 제거한다.

타입추론

// Collection 타입
Collection<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
System.out.println(numbers); // 출력: [1, 2, 3]
numbers.remove(1); // 값이 1인 요소를 제거
System.out.println(numbers); // 출력: [2, 3]

// var
var numbers = new ArrayList<>(List.of(1, 2, 3));
System.out.println(numbers); // 출력: [1, 2, 3]
numbers.remove(1);  // ??
System.out.println(numbers); // 출력: [1, 3]
  • 타입 추론을 쓸 때는 실제로 어떤 타입으로 추론될지 확인해야 한다.
    • var로 추론한 타입이 ArrayList 라서 remove(1)은 인덱스 1의 원소를 제거했다.

Arrays.asList()

List<Integer> numbers = Arrays.asList(1, 2, 3);
try {
    numbers.add(4); // UnsupportedOperationException 발생
} catch (UnsupportedOperationException e) {
    System.out.println("add unsupported");
}

try {
    numbers.set(2, 2); // 작동함 - 요소 변경은 가능
} catch (UnsupportedOperationException e) {
    System.out.println("set unsupported");
}
  • Arrays.asList()로 만든 리스트는 크기가 고정되어 있어 새 원소를 추가할 수 없다.
  • 하지만 기존 요소의 값은 변경 가능
  • 불변 리스트를 만들려는 의도로 사용할 수 없다.
List<Integer> numbers = List.of(1, 2, 3);
try {
    numbers.add(4); // UnsupportedOperationException 발생
} catch (UnsupportedOperationException e) {
    System.out.println("add unsupported");
}

try {
    numbers.set(2, 2); // UnsupportedOperationException 발생
} catch (UnsupportedOperationException e) {
    System.out.println("set unsupported");
}
  • Java 9부터 도입된 List.of(), Set.of(), Map.of()와 같은 팩토리 메서드들은 완전히 불변 컬렉션을 생성한다.

Stream side effect

List<String> names = List.of("Dory", "Gill", "Bruce", "Nemo", "Darla", "Marlin", "Jacques");
List<String> inUpperCase = new ArrayList<>();

names.stream()
     .map(String::toUpperCase)
     .forEach(name -> inUpperCase.add(name));

System.out.println("Size before: " + names.size()); // 7
System.out.println("Size after: " + inUpperCase.size()); // 7

names.parallelStream() // 병렬 스트림으로 변경할 경우 예측 불가능한 결과 발생
     .map(String::toUpperCase)
     .forEach(name -> inUpperCase.add(name));
  • Stream 람다는 순수 함수(Pure Function)로 구성해야한다.(외부 상태 변경 X, 외부 변경 가능 상태에 의존 X)

Stream lazy evaluation

int[] factor = new int[] { 2 };
List<Integer> numbers = List.of(1, 2, 3);

var stream = numbers.stream()
                                        .map(n -> n * factors[0]);

// 스트림이 실행되기 전에 외부 상태 변경
factors[0] = 0;

// 스트림이 실행 - 변경된 factor 값 사용
stream.forEach(System.out::print)

// 올바른 방식 - 외부 상태에 의존하지 않음
int factor = 2; // 로컬 변수로 값 고정
List<Integer> betterResult = numbers.stream()
                                   .map(n -> n * factor)
                                   .toList();
  • 스트림은 최종 연산이 호출될 때까지 실제로 실행되지 않는다.
    • 그 전에 외부 상태를 변경하면 의도하지 않은 결과가 발생할 수 있다.

  • 불변 컬렉션 팩토리 메서드나 스트림의 toList() 같은 새로운 기능들을 별 생각 없이 사용하고 있었는데, 단순히 편의성이 아니라 안전성을 위해 중요하다는 것을 새삼 배웠다.
  • 마찬가지로 스트림을 사용할 때 순수함수 여부와 사이드 이펙트를 크게 생각하지 않았었다.
  • 코드 작성할 때 내가 의도한 대로 동작하는지 늘 확인하고, 정말 보장하는지 알 수 있도록 꾸준한 학습이 필요할 것 같다.
반응형
저작자표시 비영리 변경금지 (새창열림)
'Language/Java' 카테고리의 다른 글
  • [Java] 표준 예외를 사용하자
  • [Java] 동등성, 동일성
  • [Java] Enum 비교를 equals() 로 하지않고 == 로 해야 하는 이유
  • [Java] Exception
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (121)
      • Spring Framework (7)
        • Spring (3)
        • JPA (2)
        • Spring Security (0)
      • Language (51)
        • Java (11)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (3)
      • 프로젝트 (2)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바
    PS
    NUXT
    C++
    게임 개발
    파이썬
    Unreal Engine
    map
    게임
    mscoco
    redis
    MySQL
    JS
    JavaScript
    C
    CPP
    php
    select
    Python
    언리얼엔진4
    memcached
    FPS
    딥러닝
    알고리즘
    블루프린트
    pytorch
    Unreal
    웹
    프로그래머스
    클래스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
[Java] Know your java
상단으로

티스토리툴바