Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- Linux
- DBMS
- java
- PostgreSQL
- pandas
- 인터페이스
- Javascript
- spring
- 명령어
- Python
- MariaDB
- 넥사크로
- 후기
- github
- git
- IntelliJ
- oracle
- docker
- JAVA8
- 오블완
- 네트워크
- 책
- mssql
- SQL
- 책추천
- 티스토리챌린지
- mysql
- 리눅스
- springboot
- 독서
Archives
- Today
- Total
hanker
[Java] filter() 메서드 (조건에 맞는 데이터만 출력) 본문
반응형
Java 8에서 도입된 Java Stream의 filter 기능에 대해서 알아보자.
filter() 메서드는 주어진 조건을 만족하는 요소들만 통과시키는 중간 연산자이다.
1. filter() 기본 사용법
public class Main {
public static void main(String[] args) throws Exception {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 짝수만 필터링
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("원본 리스트: " + numbers);
System.out.println("짝수만: " + evenNumbers);
}
}
- numbers.stream(): 컬렉션을 스트림으로 변환
- filter(n -> n % 2 == 0): 람다 표현식으로 짝수 조건 정의
- collect(Collectors.toList()): 필터링된 결과를 새로운 List로 수집
- 원본 리스트는 변경되지 않고, 새로운 리스트가 생성됨
2. 다양한 데이터 타입 필터링
2-1. 문자열 필터링
public class Main {
public static void main(String[] args) throws Exception {
List<String> names = Arrays.asList("Ada", "C++", "Java", "C#", "Python");
// 길이가 4 이상인 이름만 필터링
List<String> longNames = names.stream()
.filter(name -> name.length() >= 4) // 문자열 길이가 4 이상인지 체크
.collect(Collectors.toList());
System.out.println("길이 4 이상: " + longNames);
// 'A'로 시작하는 이름만 필터링
List<String> aNames = names.stream()
.filter(name -> name.startsWith("A")) // 'A'로 시작하는지 체크
.collect(Collectors.toList());
System.out.println("A로 시작: " + aNames);
// 대소문자 무시하고 'a'가 포함된 이름 필터링
List<String> containsA = names.stream()
.filter(name -> name.toLowerCase().contains("a")) // 소문자로 변환 후 'a' 포함 여부 체크
.collect(Collectors.toList());
System.out.println("'a' 포함: " + containsA);
}
}
- name.length() >= 4: 문자열의 길이를 반환하여 4 이상인지 확인
- name.startsWith("A"): 문자열이 특정 문자로 시작하는지 확인
- name.toLowerCase().contains("a"): 대소문자를 통일한 후 특정 문자 포함 여부 확인
- 각 filter는 boolean 값을 반환하는 조건식을 사용
2-2. 객체 필터링
class Employee {
private String name;
private int age;
private String department;
private double salary;
public Employee(String name, int age, String department, double salary) {
this.name = name;
this.age = age;
this.department = department;
this.salary = salary;
}
// getter 메서드들 - 객체의 필드에 접근하기 위해 필요
public String getName() { return name; }
public int getAge() { return age; }
public String getDepartment() { return department; }
public double getSalary() { return salary; }
@Override
public String toString() {
return String.format("%s(%d세, %s, %.0f만원)", name, age, department, salary);
}
}
public class Main {
public static void main(String[] args) throws Exception {
// Employee 객체들의 리스트 생성
List<Employee> employees = Arrays.asList(
new Employee("김철수", 28, "개발팀", 4500),
new Employee("이영희", 32, "마케팅팀", 4000),
new Employee("박민수", 35, "개발팀", 5500),
new Employee("최지은", 29, "디자인팀", 4200),
new Employee("정우진", 40, "개발팀", 6000)
);
// 개발팀 직원만 필터링
List<Employee> developers = employees.stream()
.filter(emp -> emp.getDepartment().equals("개발팀")) // 부서명이 "개발팀"인지 확인
.collect(Collectors.toList());
System.out.println("개발팀 직원들:");
developers.forEach(System.out::println); // 메서드 참조로 각 요소 출력
// 30세 이상이면서 연봉 5000만원 이상인 직원 (AND 조건)
List<Employee> seniorHighPaid = employees.stream()
.filter(emp -> emp.getAge() >= 30 && emp.getSalary() >= 5000) // 두 조건을 모두 만족
.collect(Collectors.toList());
System.out.println("\n30세 이상 & 연봉 5000만원 이상:");
seniorHighPaid.forEach(System.out::println);
}
}
- Employee 클래스: 직원 정보를 담는 사용자 정의 객체
- emp.getDepartment().equals("개발팀"): 객체의 getter 메서드를 통해 필드 값 비교
- emp.getAge() >= 30 && emp.getSalary() >= 5000: AND 연산자로 여러 조건 결합
- forEach(System.out::println): 메서드 참조를 사용한 간결한 출력 방식
3. 복합 조건 필터링
public class Main {
public static void main(String[] args) throws Exception {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
// 5보다 크고 10보다 작은 수 (두 조건을 모두 만족해야 함)
List<Integer> filtered = numbers.stream()
.filter(n -> n > 5 && n < 10) // && 연산자로 두 조건 결합
.collect(Collectors.toList());
System.out.println("5 < n < 10: " + filtered);
// 3의 배수이거나 5의 배수인 수 (둘 중 하나만 만족해도 됨)
List<Integer> multipleOf3Or5 = numbers.stream()
.filter(n -> n % 3 == 0 || n % 5 == 0) // || 연산자로 두 조건 중 하나만 만족하면 통과
.collect(Collectors.toList());
System.out.println("3의 배수 또는 5의 배수: " + multipleOf3Or5);
}
}
- n > 5 && n < 10: 논리 AND 연산자로 두 조건을 모두 만족하는 경우만 통과
- 5보다 크면서 동시에 10보다 작은 수만 필터링됨
- n % 3 == 0 || n % 5 == 0: 논리 OR 연산자로 둘 중 하나의 조건만 만족해도 통과
- n % 3 == 0: 3으로 나눈 나머지가 0 (3의 배수)
- n % 5 == 0: 5로 나눈 나머지가 0 (5의 배수)
4. Predicate를 변수로 분리
class Employee {
private String name;
private int age;
private String department;
private double salary;
public Employee(String name, int age, String department, double salary) {
this.name = name;
this.age = age;
this.department = department;
this.salary = salary;
}
// getter 메서드들 - 객체의 필드에 접근하기 위해 필요
public String getName() { return name; }
public int getAge() { return age; }
public String getDepartment() { return department; }
public double getSalary() { return salary; }
@Override
public String toString() {
return String.format("%s(%d세, %s, %.0f만원)", name, age, department, salary);
}
}
public class Main {
public static void main(String[] args) throws Exception {
// Employee 객체들의 리스트 생성
List<Employee> employees = Arrays.asList(
new Employee("김철수", 28, "개발팀", 4500),
new Employee("이영희", 32, "마케팅팀", 4000),
new Employee("박민수", 35, "개발팀", 5500),
new Employee("최지은", 29, "디자인팀", 4200),
new Employee("정우진", 40, "개발팀", 6000)
);
// Predicate를 변수로 정의 - 재사용 가능한 조건들
Predicate<Employee> isDeveloper = emp -> emp.getDepartment().equals("개발팀");
Predicate<Employee> isHighPaid = emp -> emp.getSalary() >= 5000;
Predicate<Employee> isYoung = emp -> emp.getAge() < 35;
// Predicate 조합 사용
List<Employee> youngDevelopers = employees.stream()
.filter(isDeveloper.and(isYoung)) // AND 조합: 개발팀이면서 젊은 직원
.collect(Collectors.toList());
List<Employee> highPaidOrDeveloper = employees.stream()
.filter(isHighPaid.or(isDeveloper)) // OR 조합: 고연봉자이거나 개발자
.collect(Collectors.toList());
List<Employee> notDeveloper = employees.stream()
.filter(isDeveloper.negate()) // NOT 조합: 개발자가 아닌 직원
.collect(Collectors.toList());
System.out.println("젊은 개발자: " + youngDevelopers);
System.out.println("고연봉자 또는 개발자: " + highPaidOrDeveloper);
System.out.println("개발자가 아닌 직원: " + notDeveloper);
}
}
- Employee 클래스: 직원 정보를 담는 사용자 정의 객체
- emp.getDepartment().equals("개발팀"): 객체의 getter 메서드를 통해 필드 값 비교
- emp.getAge() >= 30 && emp.getSalary() >= 5000: AND 연산자로 여러 조건 결합
- forEach(System.out::println): 메서드 참조를 사용한 간결한 출력 방식
정리
Java Stream의 filter() 메서드는 단순한 조건부터 복잡한 비즈니스 로직까지 다양한 상황에서 활용할 수 있으며, 코드의 가독성과 유지보수성을 크게 향상시켜준다.
- 간단한 조건은 람다 표현식으로, 복잡한 조건은 Predicate 변수로 분리
- 성능을 위해 간단한 조건을 먼저 필터링
- 대용량 데이터는 parallel stream 고려
- 다른 Stream 연산과 조합하여 강력한 데이터 처리 파이프라인 구축
반응형
'JAVA' 카테고리의 다른 글
[Java] 배열 안에 데이터 정렬하기 (Arrays.sort) (4) | 2025.06.28 |
---|---|
[JAVA] Cookie Control (쿠키 추가 및 삭제하는 방법) (2) | 2025.06.21 |
[Java] javax.servlet.http.HttpSession (웹 사용자 세션 관리) (4) | 2025.06.15 |
[JAVA] java 11 버전과 java 17 버전의 핵심 차이점 (3) | 2025.05.29 |
[JAVA] Java 11 이상에서 sun.misc.BASE64Encoder 대체하기 (1) | 2025.05.28 |