🖥️ 객체 비교와 Integer 클래스
🔍 Integer.parseInt vs Integer.valueOf
Java에서 Integer.parseInt
와 Integer.valueOf
는 문자열을 정수로 변환하는 데 사용됩니다. 하지만 이 둘은 반환 타입과 동작 방식에서 차이가 있습니다.
Integer.parseInt(String s)
:- 반환 타입:
int
(기본형) - 설명: 주어진 문자열
s
를 기본형int
로 변환합니다. 이 메서드는 단순히 문자열을 파싱하여 정수로 반환할 뿐입니다. - 특징: 이 메서드는
int
타입을 반환하기 때문에, 객체가 아닌 기본형 값을 다루게 됩니다. 또한 null을 전달하면 예외가 발생합니다. - 사용 예시:
Integer.parseInt("123")
는int
타입의123
을 반환합니다.
- 반환 타입:
Integer.valueOf(String s)
:- 반환 타입:
Integer
(객체형) - 설명: 주어진 문자열
s
를Integer
객체로 변환합니다. 내부적으로는Integer.parseInt
를 호출하고, 그 결과를Integer
객체로 반환합니다. - 특징:
Integer
객체를 반환하며, 자바의 Integer 캐싱 메커니즘에 따라 -128에서 127 사이의 값은 캐싱되어 동일한 참조를 가지게 됩니다. 따라서 메모리와 성능 측면에서 이점이 있습니다. - 사용 예시:
Integer.valueOf("123")
는Integer
객체를 반환합니다.
- 반환 타입:
int num1 = Integer.parseInt("123");
Integer num2 = Integer.valueOf("123");
요약하면,
Integer.parseInt
는 기본형int
를,Integer.valueOf
는 객체형Integer
를 반환합니다. null 처리와 캐싱 메커니즘의 차이로 인해, 사용 목적에 따라 적합한 메서드를 선택하는 것이 중요합니다.
❓ == 연산자 vs equals 메서드
Java에서 객체 비교를 할 때, ==
연산자와 equals()
메서드의 차이는 매우 중요합니다. 특히 Integer
와 같은 객체형 데이터를 비교할 때, 이 차이를 이해하는 것이 필수적입니다.
1. == 연산자
- 설명:
==
연산자는 참조(메모리 주소)를 비교합니다. 즉, 두 객체가 같은 메모리 주소를 가리키고 있을 때만true
를 반환합니다. - 주의사항: 기본형
int
와 객체형Integer
간의 비교에서는 다르게 동작할 수 있습니다. 기본형int
는 단순히 값만을 비교하지만,Integer
객체 간 비교에서는 메모리 주소가 비교되므로, 같은 값을 가질지라도false
를 반환할 수 있습니다.
2. equals() 메서드
- 설명:
equals()
메서드는 값을 비교합니다.Integer
클래스의equals()
메서드는 내부적으로 두 객체가 같은 값을 가지는지를 비교하도록 오버라이드되어 있습니다. 즉, 같은 값을 가지는 두Integer
객체가 있다면,equals()
는true
를 반환합니다. - 예시:
Integer a = 128; Integer b = 128;
이 경우,a.equals(b)
는true
를 반환하지만,a == b
는false
를 반환할 수 있습니다. 이는Integer
객체가 128 이상의 값일 때 캐싱되지 않기 때문에 서로 다른 메모리 주소를 가지기 때문입니다.
Integer a = Integer.valueOf(128);
Integer b = Integer.valueOf(128);
System.out.println(a == b); // false: 서로 다른 객체를 참조
System.out.println(a.equals(b)); // true: 같은 값을 가짐
int c = 128;
System.out.println(a == c); // true (auto-unboxing)
Integer
와int
를 비교할 때는 자동 언박싱으로 인해 값이 비교되므로,==
연산자는 true를 반환할 수 있습니다. 하지만Integer
객체 간 비교에서는equals()
를 사용하는 것이 안전합니다.
🔄 Integer와 int의 비교
Integer
와 int
를 비교할 때는 자동 언박싱(auto-unboxing)이라는 개념이 중요합니다. Java는 Integer
객체를 int
기본형으로 자동 변환하는 기능을 제공합니다. 따라서 다음과 같은 상황에서 ==
연산자가 true
를 반환할 수 있습니다.
- 자동 언박싱 예시:
Integer a = 128; int b = 128;
이 경우,a == b
는true
를 반환합니다. 이는 Java가Integer
객체를 자동으로int
로 변환하여 값 비교를 수행하기 때문입니다.
🔍 캐싱 메커니즘과 참조 비교
- 설명: Java는 -128에서 127 사이의
Integer
값에 대해 캐싱을 제공합니다. 이 범위 내에서는 동일한 값을 가지는Integer
객체가 동일한 메모리 주소를 참조합니다. 따라서 이 범위 내에서는==
연산자도true
를 반환할 수 있습니다.
Integer x = Integer.valueOf(127);
Integer y = Integer.valueOf(127);
System.out.println(x == y); // true: 같은 객체를 참조
Integer
와int
를 비교할 때는 자동 언박싱과 캐싱 메커니즘을 이해하는 것이 중요합니다. 특히==
연산자와equals()
메서드를 적절히 사용하는 것이 핵심입니다.
2. 🚀 Stream API에서의 정렬과 데이터 처리
Java의 Stream API는 컬렉션 데이터를 효율적으로 처리하고, 정렬 작업을 간단하게 수행할 수 있도록 도와줍니다.
📊 Stream에서의 정렬
Stream API에서 정렬을 하려면 sorted()
메서드를 사용합니다. 기본적으로 sorted()
메서드는 자연 순서(natural order)로 정렬합니다. 이때 Integer
와 같은 객체를 정렬할 때도 자연 순서대로, 즉 오름차순으로 정렬됩니다. 여기서 int
와 Integer
간의 차이점을 이해하는 것이 중요합니다.
- 기본 정렬:
Integer
객체를 스트림에서 정렬할 때,sorted()
메서드는 객체 간의 비교를 위해compareTo()
메서드를 사용합니다. 이때Integer
는 내부적으로int
값으로 비교를 수행합니다.int
값은 기본형으로 단순히 값 자체를 비교하지만,Integer
객체는 자동 언박싱되어 비교됩니다.
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedNumbers); // [1, 1, 3, 4, 5, 9]
기본적으로
sorted()
는Integer
객체의 자연 순서에 따라 오름차순으로 정렬합니다. 이는 내부적으로int
값으로 자동 언박싱되어 비교가 이루어지기 때문입니다.
🔧 사용자 정의 정렬 방식 적용
만약 특정 조건에 따라 커스텀 정렬을 하고 싶다면, Comparator
를 사용할 수 있습니다. sorted(Comparator<? super T> comparator)
메서드를 활용하면, 다양한 기준으로 정렬할 수 있습니다.
- 예시:
- 다음은
Integer
를 내림차순으로 정렬하는 예제입니다. 이때도Integer
객체는int
로 자동 언박싱되어 비교가 이루어집니다.
- 다음은
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
List<Integer> sortedNumbersDesc = numbers.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
System.out.println(sortedNumbersDesc); // [9, 5, 4, 3, 1, 1]
- 예시:
Integer
를 숫자를 정수로 변환한 후, 홀수는 앞에, 짝수는 뒤에 오도록 정렬 하는 예제입니다.
// 숫자를 정수로 변환한 후, 홀수는 앞에, 짝수는 뒤에 오도록 정렬
List<Integer> customSortedNumbers = numbersAsStrings.stream()
.map(Integer::valueOf)
.sorted((a, b) -> {
// 홀수는 앞에, 짝수는 뒤에 오도록 정렬
if (a % 2 != 0 && b % 2 == 0) {
return -1; // a가 앞에, b가 뒤에
} else if (a % 2 == 0 && b % 2 != 0) {
return 1; // b가 앞에, a가 뒤에
} else {
return a.compareTo(b); // 같은 홀수끼리, 같은 짝수끼리는 오름차순 정렬
}
})
.collect(Collectors.toList());
Comparator.reverseOrder()
를 사용해 내림차순으로 정렬할 수 있습니다. 이 과정에서도Integer
는int
로 언박싱되어 값 비교가 수행됩니다.
🔗 메서드 참조와 Stream
Stream에서 메서드 참조(Method Reference)는 코드의 가독성을 높여줍니다. Integer::parseInt
와 같은 정적 메서드 참조를 활용하면, 보다 간결하고 직관적인 코드 작성을 할 수 있습니다. 여기서도 Integer
와 int
간의 차이를 이해하는 것이 중요합니다.
- 정적 메서드 참조 예시:
- 문자열 리스트를 정수 리스트로 변환할 때,
Integer::parseInt
를 메서드 참조로 사용할 수 있습니다. 이 경우,parseInt
는 기본형int
를 반환하기 때문에, 이후 연산에서도 기본형int
로 처리됩니다.
- 문자열 리스트를 정수 리스트로 변환할 때,
List<String> stringNumbers = Arrays.asList("1", "2", "3");
List<Integer> intNumbers = stringNumbers.stream()
.map(Integer::parseInt)
.collect(Collectors.toList());
System.out.println(intNumbers); // [1, 2, 3]
메서드 참조를 사용하면 코드가 더 간결해지며, 기본형
int
와 객체형Integer
간의 변환도 간편해집니다.
🗺️ 복잡한 데이터 구조의 처리
Stream API는 복잡한 데이터 구조를 처리할 때도 강력한 도구입니다. 예를 들어, Map<List<Map<String, Object>>, Object>
와 같은 복잡한 구조에서 데이터를 추출하고 정렬하는 작업도 가능합니다. 이때도 Integer
와 int
간의 차이점을 고려해야 합니다.
- 예시:
- 만약 리스트 내의 맵에서 특정 키의 값을 기준으로 정렬하려 한다면, 다음과 같이 구현할 수 있습니다. 이 경우에도
Integer
와int
간의 비교가 자동으로 이루어집니다.
- 만약 리스트 내의 맵에서 특정 키의 값을 기준으로 정렬하려 한다면, 다음과 같이 구현할 수 있습니다. 이 경우에도
List<Map<String, Object>> dataList = new ArrayList<>();
// 데이터 추가 작업 생략...
List<Map<String, Object>> sortedDataList = dataList.stream()
.sorted((map1, map2) -> {
Integer value1 = (Integer) map1.get("keyName");
Integer value2 = (Integer) map2.get("keyName");
return value1.compareTo(value2);
})
.collect(Collectors.toList());
이와 같이 Stream API를 사용하면 복잡한 데이터 구조도 간결하게 처리하고 정렬할 수 있습니다. 이 과정에서도
Integer
객체는 자동으로int
로 변환되어 값 비교가 수행됩니다.
📝 요약
- Stream의
sorted()
는 기본적으로 자연 순서로 정렬하며,Comparator
를 통해 사용자 정의 정렬을 적용할 수 있습니다. - 메서드 참조를 활용하면 코드의 가독성과 간결성을 높일 수 있으며, 기본형
int
와 객체형Integer
간의 자동 변환이 중요합니다. - 복잡한 데이터 구조에서도 Stream API는 효과적이며,
Integer
와int
간의 차이를 이해하고 사용해야 합니다.
'Java' 카테고리의 다른 글
[JAVA] Spring 돌아보기 Part.2 #AOP (0) | 2024.09.12 |
---|---|
[JAVA] Spring 돌아보기 Part.1 #IoC #DI #싱글톤 (0) | 2024.09.10 |
[JAVA] #Deque VS Queue #ArrayDeque VS LinkedList #Map (1) | 2024.09.06 |
[JAVA] Java 메서드 참조 (0) | 2024.09.04 |
[JAVA] Java Stream API 활용법 (0) | 2024.09.02 |