'2015/08/29'에 해당되는 글 3건

  1. 2015.08.29 List, Map, Set - Collection
  2. 2015.08.29 자바 8 특징
  3. 2015.08.29 volatile 키워드 vs synchronized 키워드

List, Map, Set - Collection

JAVA 2015. 8. 29. 16:00

리스트, 맵, 셋은 콜렉션 클래스를 상속받은 클래스들이다.

 

List 

- 수집 순서가 있음

- 동일한 데이터에 대한 중복 입력이 가능

- 순차적인 대량의 데이터를 액세스하거나 입력할 때 유리한 방식

List분류
 
ArrayList
 
- capacity는 수용할 수 있는 데이터의 개수를 의미
 
- 데이터가 늘어나게 되면 capacity가 동적으로 확장됨.

- 크기를 지정하지 않으면 capacity는 기본 10이다.
- 데이터를 10개 이상 사용한다면 무조건 10보다는 크게 잡아놔야 된다. 그래야
동적으로 capacity가 늘어나면서 수행되는 오버헤드를 줄일 수 있다.
- 데이터의 삽입, 삭제가 좋지 않다.(배열들을 뒤로 밀거나 당겨야 하므로)
 
Vector
- ArrayList와 거의 동일. 다만 StringBuilder와 StringBuffer의 
차이처럼 동기화를 지원하느냐 하지 않느냐의 차이
 
LinkedList
- capacity의 개념이 없다.
 
- 데이터를 삽입할 때는 주소값만 연결하면 되므로 고정된 크기의 연속된 집합인 
ArrayList에 비해 삽입 삭제가 용이
 
- 검색 할 때는 처음부터 순차적으로 접근해야 하므로 속도가 느리다.
 
 

cs


Map

Key & Value 형태의 자료구조

- 수집의 순서를 기억하지 않음

- 동일한 키값을 중복하여 입력 할 수 없음


Set

- 중복데이터의 입력을 불허

- 순서가 없다.

- 중복되지 않은 수(데이터)를 구할 때 용이하다.

- 집합의 개념

'JAVA' 카테고리의 다른 글

Java finalize  (0) 2015.10.26
Call By Value vs Call By Reference  (0) 2015.09.14
자바 8 특징  (0) 2015.08.29
volatile 키워드 vs synchronized 키워드  (0) 2015.08.29
인스턴스 메소드 vs 클래스(스태틱) 메소드  (0) 2015.08.25
Posted by slender ankles
,

자바 8 특징

JAVA 2015. 8. 29. 15:58

자바 8의 특징은 무엇인가?

1) 람다식의 출현

람다식을 간략히 정리하면 변수에 로직을 대입하는 것을 말한다.


2) foreach 메소드의 등장

foreach는 자바스크립트에서 보았듯이 객체를 전달하여 index를 지정하여 iteration하는 것이 아니라 array나 list등을 전달하여 자동적으로 순회하게끔 하는 것이다. 



[참고]JIT컴파일러란 무엇인가?

Just In Time 컴파일러라는 뜻으로 인터프리터의 장점과 컴파일러의 장점을 모두 활용하여 사용하는 것입니다. 일부는 컴파일된 기계어를 만들고, 일부는 바이트 코드를 해석하는 것을 통해 번역속도와 실행속도의 장점을 취하는 방법입니다.

[참고] 컴파일러 vs 인터프리터

컴파일러는 번역속도가 느린 대신에 실행 속도가 빠르고 (전체를 기계어로 번역해놓기 때문에 실행속도가 빠름)

인터프리터는 번역속도가 빠른 대신에 실행 속도가 느리다.(번역한 코드를 한줄한줄 해석하여 실행하기 때문)


람다식

람다식은 무엇인가? 

변수에 로직을 대입할 수 있는 문법을 말한다. 기존의 익명함수의 사용을 보완하여 더 간결하고 가독성 좋은 코드를 만들 수 있다. 

람다식을 이해해보자.

참조 : http://jinson.tistory.com/208

위의 참조에서 좋은 글귀를 보고 나름대로 이해하고 해석해서 다시 재작성해본다. 

람다식이 필요한 이유를 다음과 같이 설명해주고 있다. 

우선 리스트와 리스트의 모든 원소를 이터레이션하는 코드를 작성해보자.

1
2
3
4
5
List<Integer> numbers = Arrays.asList(123456); 
 
for (int number : numbers) {
    System.out.println(number);
}
cs

우리는 이러한 리스트를 순회할 때 간단히 for문을 통해서 로직을 수행하는데 여기에 숨겨진 깊은 뜻이 있다고 한다. 

딸과 함께 거실에 떨어져있는 장난감을 주울려고 한다. 

나: "소피아, 장난감 정리하자. 땅에 어떤 장난감이 있지?"

소피아: "어. 공이 있네"

나: "그래. 공을 박스에 넣자. 땅에 또 뭐가 있지?"

소피아: "어. 인형이 있지"

나: "그래. 인형을 박스에 넣자. 땅에 또 뭐가 있지?"

소피아: "어. 책이 있네"

나: "그래. 책을 박스에 넣자. 땅에 또 뭐가 있지?"

소피아: "아니. 아무것도 없어"

나: "잘했네. 이제 다 했다"

사실 바닥에 있는 장난감을 주워라고 한 마디로도 이해하고 실행할 수 있는 것이 사람이지만 실제로 다음과 같은 과정이 가지고 오는 이점 또한 있다. 소피아는 양손에 장난감을 들어 박스에 넣을 수도 있고, 박스로부터 가벼운 것부터 나를 수도 있을 것이라는 것이다. 즉 내부 이터레이션을 수행 할 수 있다는 것이다. 즉 JIT컴파일러가 내부적으로 병렬화하여 원소 처리를 최적화해서 처리할 수도 있다는 말이다. 


다음의 예를 보자.

자바 8 이전에는 내부이터레이션을 사용하기 위해서는 이름 없는 내부클래스를 만들어야 했다. 

1
2
3
4
5
numbers.forEach(new Consumer<Integer>() {
    public void accept(Integer value) {
        System.out.println(value);
    }
});
cs

반복문을 순회하면서 새로이 만들어진 consumer객체의 accept를 정의하여 호출하고 있다.

위의 코드를 자바 8에서의 람다식을 이용해서는 다음과 같이 처리할 수 있다. 


1
numbers.forEach((Integer value) -> System.out.println(value));
cs


화살표의 왼쪽은 매개 변수 목록이고, 오른쪽은 몸체이다. 컴파일러는 내부적으로 람다식을 분석하여 Consumer클래스의 미구현된 메소드(즉, accept 메소드)와 동일한 타입인지 검사하여 람다식을 마치 consumer인터페이스를 구현한 클래스인 것처럼 활용한다. 

내부적으로 accept인지를 분석한다고 했으므로 컴파일러는 분석능력이 있는 것이다. 다음과 같이 인자를 생략해도 가능하다고 한다. 

1
numbers.forEach(value -> System.out.println(value));    // 식(1)
cs

이 문장 역시도 더 줄일 수 있다. 자바 8에서 새로이 등장할 메소드 참조(method reference)를 활용하면

더 간단하게 만들 수도 있다. 자바 8에서 도입될 :: 구문을 활용하여 다음과 같이 정적 메소드나 인스턴스 메소드를 참조할 수 있다. 

1
numbers.forEach(System.out::println);  // 식(2)

cs


람다식은 왜 필요한가?

간단히 말하면 익명함수를 사용할 것이라면, 복잡하지 않게 간결함을 제공해주겠다는 것이 그 필요 이유라고 할 수 있다.


Map의 HashCollision 처리 변화

Java 8에서도 역시 해시맵의 충돌을 Seperate Chaining 방식을 통해 해결한다. 하지만 이전과 다르게 해시충돌이 일어난 리스트의 개수가 8개 이상이 되면 링크드 리스트가 아닌 트리로 바꾼다. 그리고 6개까지 줄어들면 다시 링크드 리스트로 바꾼다.

왜 하나의 수를 경계로 삼지 않고 해시충돌의 수를 8개, 6개로 하는가 하면 데이터의 수가 하나를 경계로 왔다갔다할 때는 리스트에서 트리로 바꾸거나 트리에서 리스트로 바꾸는 오버헤드가 증가하기 때문에 이렇게 로직을 구성한다.








Posted by slender ankles
,

volatile과 synchronized 키워드. 무엇을 하는 녀석들인가?


volatile과 synchronized 키워드 멀티스레드 환경에서 읽고, 쓰기에 대해서 원자성을 보장해주는 동기화 도구입니다. 


그렇다면 두 키워드의 차이는 무엇인가?


차이점을 간략히 한 줄로 설명하자면, volatile은 변수에 한해서만 동기화를 해주는 도구이며, synchronized는 작업에 대해서 동기화를 지원해주는 도구입니다.

한줄만으로는 이해하기 힘들것이므로 가볍게 예를 하나 들어보겠습니다. 

long stat = 324L;

위와 같은 변수 선언에서의 stat에 대한 volatile키워드는 stat에 대해서 서로 다른 스레드로부터 읽고 쓰기에 대한 원자성을 보장해줍니다. 스레드 A, 스레드 B가 읽고 쓰면서 같은 변수에 대해서 다른 값을 읽어가는 것을 방지해주죠.

int value = stat + 10;

위와 같은 경우가 조금 다릅니다. 

내부적으로 JVM은 value 변수를 읽어오고, stat 변수를 읽어오며, 10을 더하는 동작이 분리되어 있습니다. 이 같은 경우 어떤 스레드가 stat에 10이 더해진 변수 value를 읽어 갈 수도 있고, 그렇지 않을 수도 있다는 것입니다. 


하지만 synchronized키워드는 작업 자체에 대해 원자성을 보장해주는 도구이므로 이 같은 문제를 해결 할 수 있습니다. 

이 것이 synchronized와 volatile키워드의 차이인 것입니다. 


'JAVA' 카테고리의 다른 글

List, Map, Set - Collection  (0) 2015.08.29
자바 8 특징  (0) 2015.08.29
인스턴스 메소드 vs 클래스(스태틱) 메소드  (0) 2015.08.25
자바 Null Pointer Exception막는 방법  (0) 2015.08.18
자바 제네릭(Generic)이란?  (0) 2015.08.06
Posted by slender ankles
,