JavaRush /Java Blog /Random-KO /커피 브레이크 #108. Java 스트림의 12가지 일반적인 용도, Java에서 객체의 메모리 할당을 ...

커피 브레이크 #108. Java 스트림의 12가지 일반적인 용도, Java에서 객체의 메모리 할당을 평가하는 방법

Random-KO 그룹에 게시되었습니다

Java 스트림을 사용하는 12가지 일반적인 방법

출처: Dev.to Java Streams API는 Java 8에서 처음 등장했습니다. 그 목적은 객체 컬렉션에 대한 일반적인 작업을 수행하는 보다 간결한 방법을 제공하는 것입니다. 또한 Java Streams API를 사용하여 복잡한 알고리즘을 구현할 수 있습니다. 이 기사에서는 Java Streams의 일반적인 사용 사례에 대해 설명합니다. 커피 브레이크 #108.  12 Java 스트림의 일반적인 용도, Java에서 객체의 메모리 할당을 평가하는 방법 - 1먼저 몇 가지 기본 사항을 정리하겠습니다.
  • stream() - 컬렉션에서 스트림을 생성합니다.

  • Collect() - 스트림을 객체로 수집합니다. 객체는 컬렉션, 기본 클래스 또는 사용자 정의 클래스일 수 있습니다.

  • Collectors 는 스트림을 수집하기 위한 (많은) 정적 메서드를 제공하는 클래스입니다.

이제 Streams의 몇 가지 사용 사례를 살펴보겠습니다.

1. 필터링

  • 조건에 따라 컬렉션에서 값을 제거하는 데 사용됩니다.

  • 조건에 따라 컬렉션 요소를 필터링하려면 filter() 메서드를 사용하세요 . 일치하는 요소만 저장됩니다.

예: 목록에서 모든 홀수를 제거합니다.
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. 전처리

  • 컬렉션의 모든 값을 제자리에서 변경해야 할 때 유용합니다.

  • map() 메소드는 컬렉션의 각 요소에 함수를 적용하고 계산된 값의 새 컬렉션을 반환하는 데 사용됩니다.

예를 들어, 각 값을 제곱으로 변환해 보겠습니다.
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. 전환

  • 컬렉션을 다른 컬렉션으로 변환하고 싶을 때 유용합니다.

  • 이를 달성하는 방법에는 여러 가지가 있습니다.

위에서 언급한 것처럼 map()Collect() 메서드를 사용하여 컬렉션을 다른 컬렉션으로 변환할 수 있습니다.

예 1: 목록에서 지도 만들기

문자열 목록을 문자열과 길이의 맵으로 변환합니다.
Map<String, Integer> wordLengths = words.stream()
        .collect(Collectors.toMap(
                word -> word,
                word -> word.length()));

예 2. 목록을 집합으로 변환.

이는 중복 항목을 제거하는 일반적인 사용 사례입니다. 또한 요소를 다시 목록에 추가하려면 stream()Collect() 메서드를 두 번 사용할 수 있습니다 . 예를 들어 문자열 목록을 고유 문자열 목록으로 변환해 보겠습니다.
// if we want to collect to a set
Set<String> uniqueWords = words.stream()
        .collect(Collectors.toSet());

// OR

// if we want to start and end as a list
List<String> uniqueWords = words.stream()
        .collect(Collectors.toSet()).stream().collect(Collectors.toList());

예 3. 제품 목록을 제품 이름 목록으로 변환합니다. (평탄화 - 정렬)

List<String> productNames = products.stream()
        .map(product -> product.getName())
        .collect(Collectors.toList());

4. 감소

  • 컬렉션을 단일 값으로 줄입니다.

  • Reduce() 메서드는 컬렉션의 각 요소에 함수를 적용하고 단일 값을 반환하는 데 사용됩니다.

Reduce() 메서드는 단일 값을 반환하므로 컬렉션을 반환하는 데 사용할 수 없습니다. 예를 들어 목록의 모든 값을 요약합니다.
int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);

5. 그룹화

  • 주어진 조건에 따라 컬렉션의 요소를 그룹화합니다.

  • 조건별로 Collection 요소를 그룹화하려면 Collectors.groupingBy() 메서드를 사용하세요 .

예를 들어 모든 제품을 카테고리별로 제품 목록으로 그룹화해 보겠습니다.
Map<String, List<Product>> productsByCategory = products.stream()
        .collect(Collectors.groupingBy(product -> product.getCategory()));

6. 찾기

  • 조건과 일치하는 첫 번째 또는 임의의 Collection 요소를 검색합니다.

  • findFirst()findAny() 메소드는 검색에 사용됩니다 .

이는 일반적으로 선형 검색과 유사합니다. 예를 들어, 목록에서 길이가 5자를 초과하는 첫 번째 단어를 찾고 있습니다.
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. 정렬

  • 컬렉션의 요소를 정렬합니다.

  • sorted() 메소드는 정렬에 사용됩니다 .

일반적으로 Collections.sort()는 컬렉션을 정렬하는 데 충분합니다. 특히 다른 작업을 실행하려면 sorted()를 사용할 수 있습니다 . 예를 들어, 숫자 목록을 오름차순으로 정렬한 다음 처음 k개 요소를 반환해 보겠습니다.
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. 파티셔닝

  • 주어진 조건에 따라 컬렉션의 요소를 분리합니다.

  • Collectors.partitioningBy() 메서드는 요소를 구분하는 데 사용됩니다 .

분할은 두 개의 컬렉션(조건과 일치하는 요소에 대한 컬렉션과 조건과 일치하지 않는 요소에 대한 컬렉션)을 반환한다는 점을 제외하면 그룹과 유사합니다. 예를 들어, 시험에 합격한 사람과 불합격한 사람으로 학생을 나누어 봅시다.
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. 계산

  • 조건과 일치하는 요소의 수를 계산합니다.

  • count() 메소드는 조건과 일치하는 요소의 수를 계산하는 데 사용됩니다 .

예를 들어, 목록에서 길이가 5자를 초과하는 단어 수를 계산해 보겠습니다.
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. 범위

  • 값의 범위를 생성합니다.

  • 값의 범위를 생성하려면 range() 메서드를 사용하세요 .

IntStream , LongStream , DoubleStreamStream 과 같은 특정 유형의 스트림을 생성하기 위한 특수 클래스가 있습니다 . 이러한 클래스는 기본 숫자 유형으로 작업할 때 유용합니다. 배열을 스트림으로 변환하려면 Arrays.stream() 을 사용하세요 . 예를 들어 0부터 10까지의 숫자 배열을 만들어 보겠습니다.
int[] numbers = IntStream.range(0, 10).toArray();

11. 매칭

  • 컬렉션의 요소를 조건자(조건)와 일치시킵니다.

  • anyMatch() , allMatch()noneMatch() 와 같은 메서드는 컬렉션 요소를 조건자와 일치시키고 부울 값을 반환하는 데 사용됩니다 .

예를 들어 가격이 10보다 높은 제품을 확인해 보겠습니다.
// true when all elements match the predicate
boolean allMatch = products.stream()
        .allMatch(product -> product.getPrice() > 10);

// true when any element matches the predicate
boolean anyMatch = products.stream()
        .anyMatch(product -> product.getPrice() > 10);

// true when no elements match the predicate
boolean noneMatch = products.stream()
        .noneMatch(product -> product.getPrice() > 10);

12. 가입

  • 컬렉션의 요소를 문자열로 연결합니다.

  • 컬렉션 요소를 문자열로 결합하려면 Collectors.joining() 메서드를 사용합니다 .

예를 들어 목록의 모든 단어를 하나의 문자열로 연결해 보겠습니다.
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
이것이 일반적인 시나리오의 전부입니다. 직접 탐색할 수 있는 덜 일반적인 다른 시나리오도 있습니다.
  • 병렬 스트림;
  • 통계;
  • 맞춤형 수집가.

스레드의 이점

  • 더욱 컴팩트한 코드 - 컬렉션을 처리하는 데 필요한 코드 양이 줄어듭니다.

  • 중간 변수가 적습니다. 중간에 변수가 있으면 오류가 발생할 수 있습니다. 숫자가 적을수록 예상치 못한 실수를 피하기가 더 쉽습니다.

  • 직관적인 코드. 일부 개발자는 스레드가 다른 방법보다 더 직관적이라는 점에 동의하지 않습니다. 그러나 일단 익숙해지면 다른 방법보다 훨씬 더 직관적이 됩니다.

읽어 주셔서 감사합니다. 이 기사를 즐겼기를 바랍니다. 이 항목에서 다루지 않았지만 스레드를 사용할 수 있는 사례가 더 많이 있습니다. 제가 놓친 일반적인 시나리오를 자유롭게 추가하세요.

Java에서 객체의 메모리 할당을 평가하는 방법

출처: DZone 이 기사는 Java에서 객체의 메모리 할당을 평가하는 가장 잘 알려진 세 가지 방법을 보여줍니다.

Profiler를 사용한 메모리 평가

일부 객체의 메모리를 추정하는 가장 쉬운 방법은 Visual VM 과 같은 프로파일러를 사용하여 JVM 메모리를 직접 조사하는 것입니다 . 커피 브레이크 #108.  12 Java 스트림의 일반적인 용도, Java에서 객체의 메모리 할당을 평가하는 방법 - 2이 접근 방식의 문제점은 실행 중인 JVM에 연결해야 하는데 보안상의 이유로 프로덕션 환경에서는 연결이 불가능할 수 있다는 것입니다.

계측기를 사용한 메모리 평가

주어진 객체에 할당된 메모리를 추정하는 또 다른 방법은 계측기를 사용하는 것입니다. 간단히 말해서 클래스를 생성하고 이를 JAR로 컴파일해야 합니다. JAR을 생성한 후에는 해당 JAR과 함께 JVM을 실행해야 합니다. 이 방법에 대한 자세한 내용은 여기에서 확인할 수 있습니다 . 여기서의 단점은 특정 jar 파일을 JVM에 추가해야 한다는 것입니다. 이는 보안 또는 관련 문제로 인해 프로덕션에 허용되지 않을 수 있습니다.

JOL 라이브러리를 사용한 메모리 평가

또 다른 옵션으로 JOL Library 를 사용할 수 있습니다 . 이는 개체의 가중치와 개체 인스턴스에 의해 할당된 메모리에 대한 자세한 추정을 제공할 수 있는 매우 강력한 라이브러리입니다. 라이브러리를 사용하려면 종속성을 추가해야 합니다.
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
그 후에는 다음과 같이 사용할 수 있습니다.
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")

Twitter 아카이브의 ObjectSizeCalculator

Twitter의 공개 GitHub 저장소 에는 주어진 객체 인스턴스에 할당된 메모리를 추정할 수 있는 ObjectSizeCalculator라는 도구 클래스가 있습니다 . 사용하는데 많은 메모리나 시간이 소요되지 않습니다. 대형 객체의 경우에도 평가 프로세스는 몇 초 정도 걸립니다. 이 클래스를 사용하는 것은 매우 간단합니다.
ObjectSizeCalculator.getObjectSize(address)
이 방법을 권장하지만 Java Hotspot, OpenJDK 및 TwitterJDK에서만 지원된다는 점을 명심하세요.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION