Java - int vs Integer 비교

StrayCat·2026년 2월 19일

CS지식

목록 보기
1/32

1. int vs Integer

  • Java에는 같은 숫자를 표현하는 두 가지 타입이 존재합니다.
int a = 5;          // 원시 타입 (primitive) - 값 자체를 저장
Integer b = 5;      // 객체 타입 (wrapper) - 값을 객체로 감싸서 저장
구분intInteger
분류원시타입 (Primitive)참조타입(객체)(Reference)
메모리스택에 값 직접 저장힙에 객체 저장, 스택엔 주소
null 가능불가능가능
메서드 사용불가능가능 (Integer.parseInt() 등)
성능빠름상대적으로 느림
int a = null;       // ❌ 컴파일 에러
Integer b = null;   // ✅ 가능

// Integer는 메서드를 가진 객체
Integer.parseInt("123");    // ✅
Integer.MAX_VALUE;          // ✅
  • Integer는 '메서드를 가진' ' 객체'라는 점을 기억할 것

2. 박싱(Boxing) & 언박싱(Unboxing)

  • int <-> Integer 간 변환을 의미합니다.
// 박싱 (int -> Integer) : 원시타입을 객체로 포장
Integer boxed = Integer.valueOf(5);  // 명시적
Integer autoBoxed = 5;               // 자동 (오토박싱)

// 언박싱 (Integer -> int) : 객체에서 값을 꺼냄
int unboxed = boxed.intValue();      // 명시적
int autoUnboxed = boxed;             // 자동 (오토언박싱)

3. IntStream vs Stream<Integer>

  • 같은 맥락으로, Java의 제네릭 (<T>)은 객체 타입만 받을 수 있으므로, Stream<int>는 존재하지 않습니다.
Stream<int> x;      // ❌ 불가능 - 제네릭은 원시타입 못 받음
Stream<Integer> o;  // ✅ Integer는 객체이므로 가능
IntStream s;        // ✅ int 전용 스트림 (별도 제공)
  • Java는 이를 위해 원시타입 전용 스트림을 따로 만들어둠

int -> IntStream
long -> LongStream
double -> DoubleStream

// IntStream - int 전용, 성능 좋음, Comparator 못 씀
IntStream.of(1, 2, 3)
    .sorted()           // 오름차순만 가능
    .toArray();         // int[] 반환

// Stream<Integer> - 객체라 Comparator 사용 가능
Stream.of(1, 2, 3)
    .sorted(Comparator.reverseOrder())  // ✅ 내림차순 가능
    .toList();
  • 원시타입 int의 Stream은 내림차순을 지원하지 않으므로, Comparator를 지원하는 객체타입 Integer Stream으로의 변환이 필요한 것 (boxed)
IntStream.of(arr)               // int 스트림 (원시타입)
    .filter(n -> n % 2 == 0)
    .boxed()                    // int -> Integer 로 박싱 (객체로 변환)
    .sorted(Comparator.reverseOrder())  // 이제 Comparator 사용 가능
    .mapToInt(Integer::intValue)        // Integer -> int 언박싱
    .toArray();                         // int[] 반환
  • 또한 IntStream 자체도 고유의 메서드를 보유하고 있음
// 스트림 전체에 대한 연산
IntStream.of(1, 2, 3, 4, 5)
    .sum();      // 스트림 전체 합계 -> 15
    .max();      // 스트림 전체 최댓값 -> 5
    .min();      // 스트림 전체 최솟값 -> 1
    .average();  // 스트림 전체 평균 -> 3.0

4. Integer 객체 타입의 주요 메서드

1. 변환 메서드

// String -> int 변환 (가장 자주 사용됨)
int a = Integer.parseInt("123");       // 123
int b = Integer.parseInt("FF", 16);    // 255 (16진수를 10진수로)

// int -> String 변환
String s = Integer.toString(123);      // "123"
String hex = Integer.toHexString(255); // "ff"
String bin = Integer.toBinaryString(10); // "1010"
String oct = Integer.toOctalString(8);   // "10"

2. 비교 메서드

// 두 값 비교 (-1, 0, 1 반환)
Integer.compare(3, 5);   // -1 (3 < 5)
Integer.compare(5, 5);   //  0 (같음)
Integer.compare(5, 3);   //  1 (5 > 3)

// 객체 비교
Integer a = 127;
Integer b = 127;
a == b;          // ✅ true  (-128~127은 캐싱됨 - 주의!)
a.equals(b);     // ✅ true  (값 비교 - 항상 이걸 쓰세요)

Integer c = 200;
Integer d = 200;
c == d;          // ❌ false (캐시 범위 초과 - 다른 객체)
c.equals(d);     // ✅ true

⚠️Integer 객체끼리 == 비교는 String과 동일하게 주소 비교라 위험함. 항상 equals() 사용할 것

3. 최댓값 / 최솟값 / 합계

Integer.max(10, 20);   // 20
Integer.min(10, 20);   // 10
Integer.sum(10, 20);   // 30

// 상수
Integer.MAX_VALUE;  // 2147483647  ( 2^31 - 1 )
Integer.MIN_VALUE;  // -2147483648 ( -2^31 )

4. Stream에서 자주 쓰이는 패턴

List<String> strList = List.of("3", "1", "2");

// String 리스트를 int 스트림으로 변환할 때
strList.stream()
    .mapToInt(Integer::parseInt)  // "3" -> 3 변환
    .sorted()
    .toArray();                   // [1, 2, 3]

5. 박싱은 언제 필요할까?

박싱이 필요한 대표적인 상황들

1. 컬렉션에 담을 때 (가장 흔한 이유)

// 컬렉션은 객체만 담을 수 있음
List<int> list = new ArrayList<>();     // ❌ 불가능
List<Integer> list = new ArrayList<>(); // ✅

list.add(5);  // 오토박싱으로 자동 변환

2. 제네릭 사용시

// 제네릭 타입 파라미터는 객체만 가능
Map<String, int> map;     // ❌
Map<String, Integer> map; // ✅

3. null을 표현해야 할 때

// DB 조회 결과가 없을 수도 있는 경우
Integer age = null;  // ✅ "나이 정보 없음"을 표현 가능
int age = null;      // ❌

4. 메서드 사용 목적

Integer.parseInt("123");   // 변환
Integer.MAX_VALUE;         // 상수 활용
profile
알면 좋은 것보단 잊어버리기 싫은 것들을 기록합니다.

0개의 댓글