[JAVA] Interger와 int의 차이점, == 연산과 equals()의 차이점, Array 와 Array List 차이점 정리

SUN·2022년 11월 3일
0

JAVA

목록 보기
1/2

자바 언어로 우테코 5기 프리코스 1주차 미션을 진행하면서
여러 궁금증이 생겨서 공부하다가 새로 알게 된 점을 공유하고자 한다.
위 포스팅에서도 아래 내용을 정리했지만, 배운점만 따로 깔끔하게 보고 싶어서 새로 포스팅도 작성한다.

1. Integer VS int


int는 null값을 가질 수 없고 Integer는 null값을 가질 수도 있다.
그래서 Integer는 언박싱을 안하면 연산을 할 수 없다. (자바에선 대부분 자동으로 해준다)
그리고 int는 4바이트고 Integer는 16바이트라서 메모리를 더 사용한다.

2. == VS equals()


쉽게 말하면 == 연산은 주소를 비교하고 equals()는 주소도 비교하고 다르면 값도 비교한다.

좀 더 자세하게 말하면
== 연산은 int,boolean primitive type에 대해서는 값을 비교하고 reference type에 대해서는 주소값을 비교한다.
String은 객체니까 reference type이므로 ==를 사용하면 주소를 비교하게 된다.

String 객체의 equals()는 변수로 들어온 객체가 자기 자신과 주소값이 같으면 true를 리턴한다.
주소값이 다르다면 내부의 Char를 하나씩 비교해 보면서 끝까지 같다면 true, 다르면 false를 리턴한다.
참고로, equals()는 Object타입에서는 ==연산을 사용하는데 String객체에서만 이렇게 오버라이딩한 것이다.

그래서 코드로 설명하면 아래와 같다.

	public static void main(String[] args){
    	Stirng A = "Java"; // 리터럴(literal)       	주소값 : 1000 
        Stirng B = "Java"; // 리터럴(literal)			주소값 : 1000
    	Stirng C = new Stirng("Java"); // new 연산자	주소값 : 2000
        Stirng D = new Stirng("Java"); // new 연산자	주소값 : 3000
	}

리터럴(literal)을 사용해서 String을 생성하면 객체가 String Constant Pool 영역에 만들어지고,
new 연산자를 통해 String을 생성하면 Heap 영역에 만들어진다.

그래서 A와 B는 String Constant Pool 영역에 만들어진 하나의 객체를 참조하고,
C와 D는 Heap 영역에 각각 개별의 객체가 생성된다.

즉, 객체 개수는 A와 B 합쳐서 1개 + C 1개 + D 1개 = 총 3개가 나온다.

그림으로 표현하면 이렇게 된다.

System.out.println( A == B );  // true        주소값 : 1000 == 1000
System.out.println( B == C );  // false       주소값 : 1000 == 2000
System.out.println( C == D );  // false       주소값 : 2000 == 3000

그래서 == 연산을 사용하면 결과가 이렇게 나오게 되는 것이다.
하지만 equals()같은 경우에는 값도 비교하기 때문에 모두 true를 반환한다.

3. Array VS Array List


Array

  • 고정된 크기를 갖는 같은 자료형의 원소들이 연속적인 형태로 저장된 자료구조
  • 메모리에 연속되어 저장된다.
  • 데이터 갯수가 확실하게 정해져 있고, 접근이 빈번한 경우 효율적
  • Compile time에 할당되는 정적 메모리 할당
  • cache hit 가능성이 커져 성능에 큰 도움이 된다.
    • cache hit : CPU가 참조하고자 하는 메모리가 캐시에 존재하고 있는 경우
    • 왜냐하면 메모리에 연속적인 주소에 저장돼 있기 때문이다.
  • 특정위치에 있는 값에 접근하거나, 수정하는 연산은 O(1)이다.
  • 중간에 삽입과 삭제의 경우 연속적인 형태 유지를 위해 shift 연산을 해야하므로 O(n)이 된다.
    • 삽입하면 그 뒤에 있는 요소들을 뒤로 한칸 씩 밀고 삭제하면 앞으로 땡기는 식으로 동작
    • 끝에 삽입/삭제 시에는 O(1)이다.
    • 삽입/삭제가 빈번하다면 링크드 리스트를 사용하는 게 좋다.

List

  • 빈틈없는 데이터의 적재를 위한 자료구조
  • 메모리에 분산되어 저장된다.
  • 특정위치에 있는 값에 접근하거나, 수정하는 연산은 O(n)이다.
  • 삽입/삭제의 경우 O(1)이다.
    • 그 값을 찾으러 가는데는 최악의 경우에 O(n)이 걸릴 수도 있다.
  • 새로운 Node가 추가되는 runtime에 할당되는 동적 메모리 할당
  • 빈 엘리먼트는 허용하지 않는다.
  • 순차성을 보장하지 못하기 때문에 spacial locality 보장이 되지 않아 cash hit가 어렵다.
    • spacial locality : 이후 접근할 메모리 영역은 이미 접근이 이루어진 영역의 근처일 확률이 높다는 특성

Array List

  • 쉽게 말하면 크기가 가변적인 배열
  • 배열과 인덱스의 특징을 모두 가진다.
    • 인덱스를 사용할 수 있고(배열 특징) 가변적인 크기(리스트 특징)를 가질 수도 있다.
  • 배열을 통해 리스트를 구현한 것
    • 용량이 꽉 차면 기존 용량의 1.5배를 늘린 새로운 배열에 기존 배열을 copy하는 식으로 동작
    • Default 저장용량은 10
  • List 인터페이스를 상속받은 클래스로 크기가 가변적으로 변하는 선형리스트
  • 중간에 삽입과 삭제의 경우 연속적인 형태 유지를 위해 shift 연산을 해야하므로 O(n)이 된다.
    • 삽입하면 그 뒤에 있는 요소들을 뒤로 한칸 씩 밀고 삭제하면 앞으로 땡기는 식으로 동작
    • 끝에 삽입/삭제 시에는 O(1)이다.
    • 삽입/삭제가 빈번하다면 링크드 리스트를 사용하는 게 좋다.
  • 특정위치에 있는 값에 접근하거나, 수정하는 연산은 O(1)이다.
  • 배열에 비해 살짝 느리다.
    • 새로운 요소를 추가할 때, 여유 공간이 있는 경우엔 O(1)이지만, 여유공간이 없는 경우엔 O(n)이므로

참고로 링크드 리스트와 배열의 차이점에 대해 이전에 포스팅한 적이 있으니 이걸 참고해도 좋을 것 같다.

profile
개발자

0개의 댓글