CodeGym/Java Blog/무작위의/Java.lang.Integer 클래스
John Squirrels
레벨 41
San Francisco

Java.lang.Integer 클래스

무작위의 그룹에 게시되었습니다
회원
Java 데이터 유형은 조건에 따라 기본 블록과 참조 블록(클래스)의 두 블록으로 나눌 수 있습니다. Java에는 정수( byte , short , int , long ), 부동 소수점 숫자( float , double ), 논리 데이터 유형( boolean ) 및 문자 데이터 유형( char ) 과 같은 여러 기본 데이터 유형이 있습니다 . 아마도 각 기본 데이터 유형에는 자체 래퍼 클래스가 있다는 것을 이미 알고 계실 것입니다. Java 객체에서 원시적인 동생을 "래핑"하거나 변환하는 참조 데이터 유형입니다. Integer는 int라는 기본 bro에 대한 래퍼 클래스입니다. Integer는 영어로 정수를 의미합니다. 양수, 음수 또는 0일 수 있습니다. 불행하게도 Java의 정수는 정수를 의미하지 않습니다. Java의 정수는 32비트에 맞는 정수입니다. 더 큰 숫자를 원할 경우 Java Long 숫자를 사용할 수 있습니다 . 64비트를 사용할 수 있습니다. 운이 좋지 않아 훨씬 더 많은 수의 Java가 BigInteger 로 처리되었습니다 .

정수 작업

래퍼 클래스로서 Integer는 int를 사용하여 작업하기 위한 다양한 메서드 뿐만 아니라 int를 String 으로 , String 을 int 로 변환하는 여러 메서드를 제공합니다 . 클래스에는 두 개의 생성자가 있습니다.
  • public Integer(int i) , 여기서 i는 초기화할 기본 값입니다. 이것은 int 값 으로 초기화되는 Integer 객체를 생성합니다 .

  • public Integer(String s)는 NumberFormatException을 발생시킵니다 . 여기서 s 는 int 값 의 문자열 표현입니다 . 이 생성자는 문자열 표현에서 제공하는 int 값 으로 초기화된 Integer 개체를 만듭니다 .

정수 객체 생성

다양한 정수 객체 생성 옵션이 있습니다 . 가장 일반적으로 사용되는 것 중 하나는 가장 쉬운 것입니다. 예는 다음과 같습니다.
Integer myInteger = 5;
이 경우 Integer 변수 의 초기화는 기본 int 변수 의 초기화와 유사합니다 . 그런데 int 값으로 Integer 변수를 초기화할 수 있습니다 . 예는 다음과 같습니다.
int myInt = 5;
Integer myInteger = myInt;
System.out.println(myInteger);
여기서의 출력은 다음과 같습니다.
5
실제로 여기서는 자동 패킹을 관찰할 수 있습니다. 또한 생성자와 new 키워드를 사용하여 다른 객체와 마찬가지로 Integer 객체를 만들 수 있습니다 .
Integer myInteger = new Integer(5);
int 변수와 동일하게 Integer 변수를 사용할 수 있습니다 (더하기, 빼기, 곱하기, 나누기, 증가, 감소). 그러나 Integer 는 참조 데이터 유형이며 이 유형의 변수는 null일 수 있다는 점을 기억하는 것이 중요합니다. 이런 경우에는 그러한 작업을 자제하는 것이 좋습니다.
Integer myInteger1  = null;
Integer myInteger2 = myInteger1 + 5;
여기서는 예외가 발생합니다.
스레드 "main" java.lang.NullPointerException에서 예외가 발생했습니다.

정수 클래스 상수

Integer 클래스 정수 작업을 위한 다양한 상수와 메서드를 제공합니다. 여기 있습니다:
  • SIZE는 int 유형이 차지하는 두 자리 숫자 시스템의 비트 수를 의미합니다.

  • BYTES 는 int 유형이 차지하는 두 자리 숫자 체계의 바이트 수입니다.

  • MAX_VALUE 는 int 유형이 보유할 수 있는 최대값입니다.

  • MIN_VALUE 는 int 유형이 보유할 수 있는 최소값입니다.

  • TYPE은 int 유형에서 Class 유형의 객체를 반환합니다.

정수 클래스 가장 유용한 메소드

이제 Integer 클래스 에서 가장 많이 사용되는 메소드를 살펴보겠습니다 . 그 중 가장 인기 있는 방법은 숫자를 String 에서 변환 하거나 그 반대로 변환하는 방법인 것 같습니다 .
  • static int parseInt(String s) 이 메소드는 String을 int 로 변환합니다 . 변환이 불가능하면 NumberFormatException이 발생합니다.

  • static int parseInt(String s, int radix) 이 메소드는 s 매개변수를 int 로 변환합니다 . 기수 매개 변수는 시스템 원래 작성되었음을 나타냅니다.

parsInt 외에도 여러 변형에서 매우 유사한 valueOf 메서드 가 있습니다 . 그러나 valueOf 의 결과는 Integer 이고 , parseInt 는 int 입니다 .
  • static Integer valueOf(int i) 는 값이 i정수를 반환합니다 .

  • static Integer valueOf(String s) 는 parseInt(String s) 처럼 작동 하지만 결과는 int 가 아닌 Integer 입니다 .

  • static Integer valueOf(String s, int radix) 는 parseInt(String s, int radix) 와 동일하게 작동 하지만 결과는 int 가 아니라 Integer 입니다 .

Integer 클래스에 문제가 있나요? 아, 그렇죠…

따라서 Java에는 intInteger 라는 두 가지 정수 유형(32비트에 적합)이 있습니다 . 각각의 세부 사항을 이해하려면 JVM 메모리 모델에 대해 다음 사항을 알아야 합니다. 선언하는 모든 것은 스택 메모리(각 스레드에 특정한 JVM 스택) 또는 힙 공간에 저장됩니다. 기본 유형( int , long , float , boolean , double , char , byte 등)은 스택 메모리에 저장됩니다. 모든 객체와 배열은 힙 공간에 저장됩니다. 메소드에 필요한 이러한 객체 및 배열에 대한 참조는 Stack에 저장됩니다. 그래서. 우리는 왜 관심을 갖나요? 글쎄요, Stack은 Heap보다 작지만(단점) Heap(프로)보다 Stack에 값을 할당하는 것이 훨씬 빠릅니다. 기본 유형 int 부터 시작하겠습니다 . 정확히 32비트를 차지합니다. 32/8=4바이트입니다. 원시적인 유형이기 때문입니다. 이제 Integer 를 고려해 봅시다 . 추가 오버헤드와 정렬이 포함된 개체입니다. 크기를 측정하기 위해 jol 라이브러리를 사용했습니다.
public static void main(String[] args) {
 	System.out.println(ClassLayout.parseInstance(Integer.valueOf(1)).toPrintable());
}
그리고 16바이트를 차지하는 것으로 나타났습니다.
java.lang.Integer 객체 내부: OFF SZ TYPE DESCRIPTION VALUE 0 8(객체 헤더: 마크) 0x000000748c90e301(해시: 0x748c90e3; 연령: 0) 8 4(객체 헤더: 클래스) 0x000492a0 12 4 int Integer.value 1 인스턴스 크기: 16바이트
무엇?! 4배 더 많은 메모리입니다! 그러나 거기서 멈추지 말자. Java 개발자로서 우리는 일반적으로 단일 정수 사용을 중단하지 않습니다. 우리가 정말로 원하는 것은 그것들을 많이 사용하는 것입니다. 순서대로. 예를 들어 배열에 있습니다. 아니면 목록. 배열은 목록과 마찬가지로 힙에 저장됩니다. 따라서 할당에는 대략 동일한 시간이 소요됩니다. 오른쪽? 하지만 더 많은 메모리를 할당해야 한다면 어떻게 될까요? 1000개의 기본 int 값 배열이 차지하는 공간이 얼마나 되는지 확인해 보겠습니다.
public static void main(String[] args) {
    	int[] array = new int[1000];
    	for (int i = 0; i < 1000; i++) array[i] = i;                System.out.println(ClassLayout.parseInstance(array).toPrintable());
}
결과는 4016바이트입니다.
OFF SZ 유형 설명 값 0 8(객체 헤더: 마크) 0x0000000000000001(편향 불가능, 연령: 0) 8 4(객체 헤더: 클래스) 0x00006c38 12 4(배열 길이) 1000 12 4(정렬/패딩 간격) 16 4000 int [I.<elements> 해당 없음 인스턴스 크기: 4016바이트 공간 손실: 내부 4바이트 + 외부 0바이트 = 총 4바이트
좋아, 단일 int가 4바이트를 차지한다는 점을 고려하면 그것은 일종의 의미가 있습니다. 1000개의 정수 로 구성된 ArrayList<Integer> 는 어떻습니까 ? 살펴보자:
public static void main(String[] args) {
	List<Integer> list = new ArrayList<>(1000);
	for (int i = 0; i < 1000; i++) list.add(i);
      System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
결과는 20040바이트입니다(역시 4배 더 많습니다!).
java.util.ArrayList@66d3c617d 공간: COUNT AVG SUM 설명 1 4016 4016 [Ljava.lang.Object; 1000 16 16000 java.lang.Integer 1 24 24 java.util.ArrayList 1002 20040 (전체)
따라서 ArrayList<Integer>는 4배 더 많은 메모리 공간을 차지합니다. 그 좋지 않다. 하지만 여전히 요소를 추가하고 삭제할 수 있기 때문에 목록이 더 쉽습니다! 아 자바... 왜 모든 것을 상자에 넣어야 하는 걸까요?! 하지만 Java는 훌륭하고 그 위대함은 우리가 사용할 수 있는 오픈 소스 라이브러리가 풍부하다는 사실을 잊고 있습니다! Trove4j도 그 중 하나입니다. 내부적으로 int[] 데이터가 있는 TIntArrayList 가 있습니다 . 크기를 측정해 보겠습니다.
public static void main(String[] args) {
	TIntList list = new TIntArrayList(1000);
	for (int i = 0; i < 1000; i++) list.add(i);
	System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
결과는 4040바이트입니다( int[] 와 거의 동일합니다 !).
gnu.trove.list.array.TIntArrayList@7440e464d 공간: COUNT AVG SUM 설명 1 4016 4016 [I 1 24 24 gnu.trove.list.array.TIntArrayList 2 4040(총계)
따라서 결국 우리는 두 세계의 장점을 모두 누릴 수 있습니다! 공간을 4배 적게 차지하는 정수 목록입니다. 그리고 여기에는 Integer 인스턴스가 포함되지 않습니다 . int 만 . 우리 Java 개발자는 메모리에 관심이 많습니다. 하지만 성능에도 관심이 있습니다. 코드 성능을 측정할 수 있는 jmh라는 이름의 멋진 마이크로벤치마킹 라이브러리가 있습니다. 먼저 박스형 여부에 관계없이 두 개의 임의 정수의 합을 계산하는 성능을 비교해 보겠습니다. jmh의 구성은 다음과 같습니다.
benchmark {
	configurations {
    	main {
        	warmups = 5 // number of warmup iterations
        	iterations = 50 // number of iterations
        	iterationTime = 500 // time in seconds per iteration
        	iterationTimeUnit = "ns" // time unit for iterationTime
벤치마크:
private static final Random random = new Random();

@Benchmark
public int testPrimitiveIntegersSum() {
	int a = random.nextInt();
	int b = random.nextInt();
	return a + b;
}

@Benchmark
public Integer testBoxedIntegersSum() {
	Integer a = random.nextInt();
	Integer b = random.nextInt();
	return a + b;
}
결과:
메인: test.SampleJavaBenchmark.testBoxedIntegersSum 5693337.344 ±(99.9%) 1198774.178 ops/s [평균] (최소, 평균, 최대) = (1092314.989, 5693337.344, 12001683.428), stdev = 2421 583.144 CI (99.9%): [4494563.166, 6892111.522] (정규 분포 가정) main: test.SampleJavaBenchmark.testPrimitiveIntegersSum 15295010.959 ±(99.9%) 2555447.456 ops/s [평균] (최소, 평균, 최대) = (4560097.059, 15295010.959, 24283809.447) , 표준 편차 = 5162130.283 CI(99.9%): [12739563.502, 17850458.415] (정규 분포 가정)
따라서 평균적으로 기본 정수의 할당 및 합계는 박스형 정수보다 두 배 이상 빠릅니다. 이제 생성 성능과 컬렉션 합계(또는 1000 정수형 배열) 계산을 비교해 보겠습니다.
@Benchmark
public int testPrimitiveArray() {
	int[] array = new int[1000];
	for (int i = 0; i < 1000; i++) array[i] = i;
	int sum = 0;
	for (int x : array) sum += x;
	return sum;
}
11933.545 ops/s [Average]


@Benchmark
public int testBoxesArray() {
	Integer[] array = new Integer[1000];
	for (int i = 0; i < 1000; i++) array[i] = i;
	int sum = 0;
	for (int x : array) sum += x;
	return sum;
}
2733.312 ops/s [Average]


@Benchmark
public int testList() {
	List<Integer> list = new ArrayList<>(1000);
	for (int i = 0; i < 1000; i++) list.add(i);
	int sum = 0;
	for (int x : list) sum += x;
	return sum;
}
2086.379 ops/s [Average]


@Benchmark
public int testTroveIntList() {
	TIntList list = new TIntArrayList(1000);
	for (int i = 0; i < 1000; i++) list.add(i);
	int sum = 0;
	for (int i = 0; i < 1000; i++) sum += list.get(i);
	return sum;
}
5727.979 ops/s [Average]
결과: 기본 배열은 박스형 값 배열( Integers )보다 4배 이상 빠릅니다. 박스형 값의 ArrayList ( Integers ) 보다 거의 6배 빠릅니다 . TIntArrayList (실제로 기본 정수 배열을 장식함) 보다 두 배 빠릅니다 . 따라서 정수 값 모음을 저장하기 위해 데이터 구조가 필요하고 크기가 변경되지 않는 경우 int [] 를 사용하세요 . 크기가 변경될 예정이라면 TIntArrayList 와 함께 tove4j 라이브러리를 사용하는 것이 좋습니다 . 그리고 여기에서 Integer 유형 사용의 단점을 설명하는 에세이가 끝납니다 . Integer 의 몇 가지 흥미로운 정적 메서드가 있는데 , 끝내기 전에 이에 대해 이야기해야 합니다. public static Integer getInteger(String nm, int val)는 생각하는 대로 수행하지 않지만 시스템 속성의 Integer 값을 검색합니다. 이 속성이 설정되지 않은 경우 Val 이 기본값입니다. public static String toBinaryString(int i)는 숫자를 이진으로 표현한 문자열을 반환합니다 . 기반 16( toHexString ) 및 기반 8( toOctalString ) 표현을 검색하는 방법이 있습니다. String을 int 로 구문 분석하는 방법이 있습니다 . 문자열이 10진수가 아닌 표현인 경우에도 마찬가지입니다. 다음은 몇 가지 예입니다. Integer.parseInt("-FF", 16) 는 -255를 반환합니다 . Integer.parseInt("+42", 10) 는 42를 반환합니다 . Integer.parseInt("1100110", 2)는 102를 반환합니다 .
코멘트
  • 인기
  • 신규
  • 이전
코멘트를 남기려면 로그인 해야 합니다
이 페이지에는 아직 코멘트가 없습니다