Java 스트림을 사용하는 12가지 일반적인 방법
출처: Dev.to Java Streams API는 Java 8에서 처음 등장했습니다. 그 목적은 객체 컬렉션에 대한 일반적인 작업을 수행하는 보다 간결한 방법을 제공하는 것입니다. 또한 Java Streams API를 사용하여 복잡한 알고리즘을 구현할 수 있습니다. 이 기사에서는 Java Streams의 일반적인 사용 사례에 대해 설명합니다. 먼저 몇 가지 기본 사항을 정리하겠습니다.-
stream() - 컬렉션에서 스트림을 생성합니다.
-
Collect() - 스트림을 객체로 수집합니다. 객체는 컬렉션, 기본 클래스 또는 사용자 정의 클래스일 수 있습니다.
-
Collectors 는 스트림을 수집하기 위한 (많은) 정적 메서드를 제공하는 클래스입니다.
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. 전환
-
컬렉션을 다른 컬렉션으로 변환하고 싶을 때 유용합니다.
-
이를 달성하는 방법에는 여러 가지가 있습니다.
예 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() 메서드는 컬렉션의 각 요소에 함수를 적용하고 단일 값을 반환하는 데 사용됩니다.
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() 메소드는 검색에 사용됩니다 .
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. 정렬
-
컬렉션의 요소를 정렬합니다.
-
sorted() 메소드는 정렬에 사용됩니다 .
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() 메소드는 조건과 일치하는 요소의 수를 계산하는 데 사용됩니다 .
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. 범위
-
값의 범위를 생성합니다.
-
값의 범위를 생성하려면 range() 메서드를 사용하세요 .
int[] numbers = IntStream.range(0, 10).toArray();
11. 매칭
-
컬렉션의 요소를 조건자(조건)와 일치시킵니다.
-
anyMatch() , allMatch() 및 noneMatch() 와 같은 메서드는 컬렉션 요소를 조건자와 일치시키고 부울 값을 반환하는 데 사용됩니다 .
// 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 메모리를 직접 조사하는 것입니다 . 이 접근 방식의 문제점은 실행 중인 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에서만 지원된다는 점을 명심하세요.
GO TO FULL VERSION