728x90

프로세스 쓰레드

프로세스 : 실행 중인 프로그램. 데이터와 메모리 등 프로그램을 수행하는데 필요한 자원과 쓰레드로 구성.

쓰레드 : 프로세스의 자원을 이용하여 실제로 작업을 수행하는 것

 

모든 프로세스는 하나 이사으이 쓰레드가 존재하며, 하나의 쓰레드를 가진 프로그램을 '싱글 쓰레드 프로세스', 두개이상의 쓰레드를 가진 프로세스를 '멀티쓰레드 프로세스'라고 한다.

 

쓰레드는 각각 쓰레드별로 작업공간을 가지며 프로세스의 자원에 따라 최대 생성할 수 있는 쓰레드가 결정된다. 그러나 일반적으로 프로세스 자원의 한계에 다다를 만큼 쓰레드를 생성하는 일은 거의 없다.

 

멀티태스킹과 멀티쓰레딩

멀티 태스킹(multi-tasking) : 여러개의 프로세스가 동시에 실행되는것.

멀티 쓰레드(multi-thread) : 하나의 프로세스 내에서 여러 쓰레드가 동시에 작업을 수행하는 것. 

 

멀티쓰레딩의 장점

-자원을 효율적으로 사용할 수 있다.

-CPU의 사용률을 향상시킨다.

-사용자에 대한 응답성이 향상된다.

-작업이 분리되어 코드가 간결해진다.

 

서버 프로세스의 경우 여러개의 쓰레드로 클라이언트와의 연결시 각각 클라이언트와 쓰레드가 일대일로 처리되야한다.

싱글스레드로 서버프로그래밍을 할경우 클라이언트의 연결요청시마다 프로세스를 생성해야하는데 이때 자원이 많이 사용되기 때문에 많은 클라이언트에게 원활한 서비스를 제공하는것이 어려울 수 있다.

 

멀티쓰레드의 경우 프로세스의 자원을 공유하면서 작업을 하기 때문에 다양한 문제들을 고려하여 프로그래밍해야한다.

 

쓰레드의 구현과 실행

쓰레드를 구현하는 방법은 두가지가 있다.

1.Thread클래스를 상속받는 방법

2.Runnable인터페이스를 구현하는 방법

 

일반적으로 다중상속을 사용하기 위해 Runnable인터페이스를 구현하는 방법을 많이 사용한다.

Runnable인터페이스는 쓰레드의 작업을 작성하는 run()만 정의되어있다.

 

쓰레드를 구현하는 두가지 방법

ThreadEx1_1의 경우 Thread클래스를 상속받아 쓰레드를 구현한 방식이고 ThreadEx1_2의 경우 Runnable인터페이스를 상속받아 인스턴스를 구현한 후 Thread클래스의 생성자의 매개변수로 Thread를 구현한 방식이다.

Runnable인터페이스를 상속받아 구현하는 경우 해당 클래스의 인스턴스를 생성하여 Thread클래스의 생성자 매개변수로 넣어 Thread를 생성해주어야한다.

main메서드에서 처럼 생성된 인스턴스 객체의 start()메서드를 호출하면 해당 쓰레드 클래스의 run()메서드에 정의된 작업이 실행된다.

위예제의 실행결과이다. Thread이름을 가져와서 출력하는것인데 Thread클래스를 상속받은경우 getName()을 호출할경우 쓰레드의 이름을 얻을 수 있다. Runnable을 구현한 경우 run()밖에 없기 때문에 Thread.currentThread().getName()과 같이 Thread클래스의 currentThread()메서드를 호출한 후 getName()을 호출 해야한다.

 

쓰레드의 이름은 생성자나 메서드를 통해 지정 및 변경이 가능하다.

ex)

Thread(Runnable target, String name)

Thread(String name)

void setName(String name)

 

쓰레드의 실행 - start()

쓰레드를 실행시키는 것은 start()이다.

start()가 호출되면 쓰레드를 생성하여 실행대기 상태로 만든다. 이후 OS의 스케줄러에 의해 실행이 결정된다.

 

*Java 프로그램의 경우 JVM위에서 실행되기 때문에 보통 OS에 종속적이지 않지만 쓰레드는 JVM 과 관계없이 OS에 종속적이며 쓰레드의 실행순서는 OS스케줄러에 의해 결정된다.

 

java의 경우 실행후 종료된 쓰레드는 다시 실행시킬 수 없다. 즉 하나의 쓰레드에 대해 start()는 한번만 호출이 된다.

쓰레드의 작업 종료후 추가적으로 같은 작업을 위해 쓰레드를 생성해야 한다면 new 를 통해 새로운 쓰레드를 생성하여 같은작업을 실행시켜야 한다.

 

start()와 run()

쓰레드의 작업을 정의하는것은 run()이다. 그러나 쓰레드를 생성하고 실행시킬떄는 start()를 호출한다.

run()을 호출할 경우 Thread를 생성하는것이 아닌 단순히 해당 메서드를 호출하는 것 뿐이다.

 

start()는 새로운 쓰레드가 작업을 실행하는데 필요한 호출스택(call stack : 메모리상 작업공간)을 생성한 후 해당 호출스택에 run()을 호출하여 run()이 실행되도록 한다.

모든 쓰레드는 독립적인 작업을 수행하기 위해 자신만의 호출스택을 필요로 하기 때문에 새로운 쓰레드를 생성하고 실행시킬 때마다 새로 호출스택을 생성하고 쓰레드가 종료되면 호출스택을 반환(소멸)한다.

 

호출스택을 그림으로 나타낸 것이다. 호출스택에서 가장 위에있는 메서드가 현재 실행중인 메서드이다. 그리고 맨위(실행중)가 아닌 아래에있는 메서드들은 현재 대기상태에 있는 것이다.

멀티쓰레드 환경 즉 호출스택이 두개 이상인 경우 최상위 메서드라고 하더라도 대기상태일 수 있다.

실행중과 대기상태는 스케줄러가 결정하며 쓰레드들 우선순위에 따라 실행순서와 실행 시간을 스케줄러가 결정한다.

주어진시간동안 완료하지 못한 작업의 경우 해당 쓰레드는 대기상태로 전환되며 다시 자신의 실행차례가 오는것을 기다린다. run()에 정의된 작업을 완료한 쓰레드의경우 호출스택이 비워지며 호출스택을 반환한다.

 

main쓰레드

main메서드의 작업을 시작으로 다른 쓰레드들을 생성하거나 작업을 수행하는데 이떄 main메서드의 작업을 수행하는것을 main쓰레드라고 한다.

 

이때까지 해온 싱글 스레드 프로그래밍에서는 main메서드가 수행을 마치면 프로그램이 종료되었으나, 멀티 쓰레드 프로그래밍에서는 main메서드가 수행을 마치더라도 다른 쓰레드가 작업을 끝마치지 않았다면 프로그램은 종료되지 않는다.

 

프로세스는 실행중은 사용자 쓰레드가 하나도 없을 때 프로세스가 종료된다.

 

쓰레드는 '사용자 쓰레드(user thread)'와 '데몬 쓰레드(daemon thread)' 두개의 종류가 있다.

데몬 쓰레드의 경우 실행일지라도 사용자 쓰레드가 모두 작업을 종료하면 프로세스는 종료한다.

 

싱글쓰레드와 멀티쓰레드

왼쪽의 그림의경우 싱글스레드로 두개의 작업을 한경우이고 오른쪽의 경우 두개의 쓰레드로 두개의 작업을 한경우이다.

보통 두개의 쓰레드로 작업한시간이 한개의 쓰레드로 작업을 한경우보다 시간이 더걸린다. 그 이유는 각 쓰레드간 작업 전환(context switching)에 시간이 걸리기 떄문이다.

단순한 계산이나 하나의 자원을 사용하는경우 싱글 스레드가 더효율적이다.

 

여러개의 쓰레드가 서로 다른 자원을 사용하는경우 싱글쓰레드보다 멀티쓰레드가 더 효율적이다.

일반적으로 I/O 작업을 하는경우인데 네트워크로 데이터를 송수신하는경우, 사용자로부터 데이터를 입력받고 사용자에게 데이터를 출력하는경우, 프린터 출력과 같이 외부기기와의 입출력을 하는경우 등 I/O작업이 동반되는 경우 멀티쓰레드가 더 효율적이다.

하나의 쓰레드가 I/O를 진행하는동안 다른쓰레드는 작업이 가능하기 때문이다.

 

 

 

 

 

728x90

'Programming > JAVA' 카테고리의 다른 글

데몬 쓰레드(daemon thread)  (0) 2021.08.13
쓰레드 우선순위와 쓰레드 그룹  (0) 2021.08.13
에너테이션(annotation)  (0) 2021.08.11
열거형(Enums)  (0) 2021.08.10
지네릭스(Generics)  (0) 2021.08.07
728x90

에너테이션

에너테이션 : 프로그램의 영향을 미치지않으며, 유용한 정보를 제공하는것.

JDK에서 제공하는 표준 에너테이션은 주로 컴파일러에게 유용한 정보를 제공하며, 새로운 에너테이션을 정의할때 사용할 수 있는 메타 에너테이션을 제공한다.

 

에너테이션 목록

표준 에너테이션

@Override : 컴파일러에게 오버라이딩 메서드라는 것을 알린다.

@Deprecated : 앞으로 사용하지 않을것을 권장하는 대상에 사용한다.

@SuppressWarnings : 컴파일러에 지정한 경고메시지가 나타나지않게해준다.

@SafeVarargs : 지네릭스 타입의 가변인자에 사용한다.

@FunctionalInterface : 함수형 인터페이스라는 것을 알릴때 사용한다.

@Native : native 메서드에서 참조되는 상수 앞에 사용한다.

 

메타에너테이션

@Target : 에너테이션이 적용가능한 대상을 지정할때 사용한다.

@Documented : 애너테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다.

@Inherited : 에너테이션이 자손클래스에도 상속되도록 할때 사용하낟.

@Retention : 에너테이션이 유지되는 범위를 지정하는데 사용한다.

@Repeatable : 애너테이션이 반복해서 적용될 수 있도록 할 때 사용한다.

 

표준 에너테이션

@Override

메서드 앞에만 붙일 수 있으며, 조상의 메서드를 오버라이딩 한 메서드라는 것을 컴파일러에게 알려준다.

필수는 아니지만 사용할경우 실수를 줄일 수 있다.

오버라이딩하는 메서드의 이름을 잘못적는 경우를 방지해준다.

 

@Deprecated

JDK버전에 따라 기존의 기능을 대체하는것들이 나오기도한다. 이미 여러 곳에서 사용되고 있는 기능이라면 함부로 교체할 수 없기 때문에 더이상 사용을 권장하지 않는것을 알리는 @Deprecated가 생겼다.

추가적인 사용을 권장하지 않는 필드나 메서드에 @Deprecated를 사용한다.

@Deprecated가 되어있을 경우 IntelliJ에서 줄이 쳐져있다.

 

@FunctionalInterface

함수형 인터페이스(functional interface)를 선언할 때, @FunctionalInterface를 붙이면 컴파일러가 '함수형 인터페이스'를 올바르게 선언했는지 확인하고 잘못 선언되었는 경우 에러를 발생시킨다. 필수 에너테이션은 아니며, 사용시 오류를 줄일 수 있다.

ex)

@FunctionalInterface

public interface Runnalbe{

      public abstract void run();

}

 

함수형 인터페이스는 추상메서드가 하나만 있어야 한다.

 

@SuppressWarnings

컴파일러가 출력해주는 경고메세지가 출력되지않도록 억제해준다. 

@SuppressWarnings가 억제할 수 있는 메시지 종류는 여러가지가 있다 그중 'deprecation', 'unchecked', 'rawtypes', 'varargs' 가 주로 억제하는 메세지로 사용된다.

'deprecation'은 @Deprecated가 붙은 대상에 대한 경고를, 'unchecked'는 지네릭스 타입을 지정하지 않았을경우 발생하는 경고를, 'rawtypes'는 지네릭스를 사용하지 않아서 발생하는 경고를, 'varargs'는 가변인자의 타입이 지네릭 타입일 때 발생하는 경고를 억제할 때 각각 사용된다.

main메서드 앞에 붙임으로써 main메서드 내부에서 발생하는 deprecation과 관련된 모든 경고를 억제한다. 

ArrayList객체를 생성하는곳 바로앞에 @SuppressWarnings("unchecked")를 작성함으로써 타입에 따른 경고를 억제한다.

 

메타 애너테이션

메타 에너테이션은 에너테이션을 위한 에너테이션이다. 에너테이션의 적용대상(target) 또는 유지기간(retention)등을 지정하는데 사용한다.

 

@Target

에너테이션이 적용가능한 대상을 지정하는데 사용된다.

ex)

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

@Retention(RetentionPolicy.SOURCE)

public @interface SuppressWarnins{

      String[] value();

}

@SupressWarnings를 정의한 것이다.

@Target으로 지정할 수 있는 애너테이션 적용 종류

ANNOTATION_TYPE : 애너테이션

CONSTRUCTOR : 생성자

FIELD : 필드

LOCAL_VARIABLE : 지역변수

METHOD : 메서드

PACKAGE : 패키지

PARAMETER : 매개변수

TYPE : 타입(클래스, 인터페이스, enum)

TYPE_PARAMETER : 타입 매개변수

TYPE_USE : 타입이 사용되는 모든곳

 

위처럼 에너테이션을 정의할때 에너테이션의 적용 대상을 지정할 수 있다.

 

@Retention

에너테이션이 유지(retention)되는 기간을 지정하는데 사용된다.

 

에너테이션의 유지 정책의 종류

SOURCE : 소스 파일에만 존재. 클래스 파일에는 존재하지 않는다.

CLASS : 클래스 파일에 존재. 실행시 사용불가

RUNTIME : 클래스 파일에 존재. 실행시 사용가능

 

@Override나 @SuppressWarnings 같이 컴파일러가 사용하는 애너테이션은 유지 정책이 'SOURCE'이다. 

ex)

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.SOURCE)

public @interface Override{}

 

@FunctionalInterface의 경우 실행시에도 사용되기 때문에 유지 정책이 'RUNTIME'으로 되어있다.

ex)

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

public @interface FunctionalInterface{}

 

@Documented

에너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다. 자바에서 제공하는 기본 에너테이션 중 @Override, @SuppressWarnings를 제외하고는 모두 이 메타 에너테이션이 붙어 있다.

 

@Inherited

에너테이션이 자손 클래스에 상속되도록 한다.  @Inherited가 붙은 에너테이션을 조상 클래스에 붙이면 자손클래스도 이 에너테이션이 적용된다.

ex)

@Inherited

@interface SupperAnno{}

 

@SuperAnno

class Parent{ }

 

class Child extends Parent{ }

위와 같은경우 Child에도 @SupperAnno가 붙은것으로 인식된다. 자식클래스에도 해당 에너테이션이 상속되는것이다.

 

 

 

 

728x90

'Programming > JAVA' 카테고리의 다른 글

쓰레드 우선순위와 쓰레드 그룹  (0) 2021.08.13
쓰레드(Thread)  (0) 2021.08.13
열거형(Enums)  (0) 2021.08.10
지네릭스(Generics)  (0) 2021.08.07
Collection 정리  (0) 2021.08.07
728x90

열거형 : 관련된 상수들을 편하게 선언하기 위한 것. 여러 상수를 정의할때 사용하면 유용하다.

 

열거형의 정의

열거형을 정의 하는 방법

enum 열거형이름 {상수명1, 상수명2, ...}

ex)

enum Direction {EAST, SOUTH, WEST, NORTH}

 

열거형의 상수 사용법

열거형이름.상수명

ex)

class Unit{

 int x, y;

 Direction dir;

 

 void init(){

      dir = Direction.EAST;

 }

}

 

열거형 상수간의 비교 <, >와 같은 비교연산자는 사용이 불가능하다. 그러나 == 연산과 compareTo()는 사용가능하다.

 

모든 열거형의 조상 : java.lang.Enum

열거형의 모든 상수 출력

ex)

Direction[] dArr = Direction.values();

for(Direction d : dArr)

     System.out.printf("%s = %d%n", d.name(), d.ordinal());

 

values() 메서드는 열거형의 모든 상수를 배열에 담아 반환하는 메서드이다. 이 메서드는 모든 열거형이 가지고있다.

 

Enum클래스 메서드

Class<E> getDeclaringClass) : 열거형의 class 객체를 반환

String name() : 열거형 상수의 이름을 문자열로 반환한다.

int ordinal() : 열거형 상수가 저장된 순서를 반환한다.

T valueOf(Class<T> enumType, String name) : 지정된 열거형 name과 일치하는 열거형 상수를 반환한다.

compareTo를 통해 대소비교가 가능하다.

values()메소드로 열거형을 열거형 배열로 반환할 수 있다.

 

열거형의 멤버

상수의 값을 지정해주고 싶을 때에는 열거형 상수의 이름 옆에 지정하고 싶은 값을 괄호()와 함께 적어주면된다.

그리고 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자를 추가해준다. 이때 열거형 상수를 모두 정의한 후에 다른 멤버들(생성자, 인스턴스 변수, 메서드)을 추가해주어야 한다.

 

ex)

enum Direction{

     EAST(1),  SOUTH(5),  WEST(-1), NORTH(10);

 

     private final int value;

     Direction(int value) {this.value = value;}

     public int getValue() {return value;}

}

 

예제

열거형 멤버추가

Enum의 메서드를 정의하여 사용가능하다. 

EAST, WEST, SOUTH, NORTH 등은 객체의 주소이자 name이 된다.

728x90

'Programming > JAVA' 카테고리의 다른 글

쓰레드(Thread)  (0) 2021.08.13
에너테이션(annotation)  (0) 2021.08.11
지네릭스(Generics)  (0) 2021.08.07
Collection 정리  (0) 2021.08.07
Map  (0) 2021.08.07
728x90

지네릭스 : 다양한 타입의 객체들을 다루는 메서드나 컬렉션에 컴파일시 타입체크를 해주는 기능이다.

->객체타입을 컴파일 시에 체크하여 타입 안정성을 높히며 형변환을 줄일 수 있다.

 

지네릭스 장점

1.타입 안정성을 제공한다.

2.타입체크와 형변환을 생략할 수 있어 코드가 줄어든다.

 

지네릭스 클래스 선언

클래스 옆에 <T>를 붙이면된다.

ex)

class Box<T>{

    T item;

    void setItem(T item){this.item = item;}

    T getItem(){return item;}

}

 

Box<T>에서 T는 타입 변수(type variable)이라 한다. 임의의 참조형 타입을 의미한다. 

Box클래스의 객체를 생성할 때는 참조변수와 생성자에 타입T대신 실제 타입을 지정해주어야한다.

ex)

Box<String> b = new Box<String>();

 

T자리에 String을 넣어줬으므로 Box클래스의 모든 T는 String으로 변환되어 인식된다.

 

지네릭스 용어

class Box<T> {}

Box<T> : 지네릭 클래스. T의 Box 또는 T Box라고 읽는다.

T : 타입변수 또는 타입 매개변수라고 한다.

Box : 원시 타입(raw type)

 

지네릭스 생성

지네릭 클래스를 생성할때는 참조변수와 생성자에 대입된 타입이 일치해야한다.

Box<T>의 경우

ex)

Box<Apple> appleBox = new Box<Apple>();

Box<Apple> appleBox = new Box<Grape>(); // 에러

참조변수의 타입변수와 생성자의 타입변수가 다르면 에러가 발생한다.

 

지네릭스 제한

일반적으로 하나의 종류만 지네릭클래스의 타입변수로 가능하지만 지정타입의 종류에 제한을 걸 수 있다.

extends를 사용하는 방법이다.

지네릭 타입에 extends를 사용할경우 해당 클래스와 자식클래스들까지 가능하다.

Apple클래스와 Grape클래스가 Fruit 클래스의 자손일때

ex)

class FruitBox<T extends Fruit>{

...

}

 

FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();

fruitBox.add(new Apple());

fruitBox.add(new Grape());

위의 예문이 가능하다.

 

인터페이스 또한 제한설정이 가능하다.

Eatable인터페이스가 존재할때

class FruitBox<T extends Fruit & Eatable>{...}의 경우 

FruitBox에는 Fruit의 자손이면서 Eatable을 구현한 클래스만 타입 매개변수 T에 대입될 수 있다.

 

와일드 카드

<? extends T> 와일드 카드의 상한제한 T와 그 자손들만 가능

<? super T> 와일드 카드의 하한제한. T와 그 조상들만 가능

<?> 제한 없음. 모든 타입이 가능. <? extends Object>와 동일하다.

makeJuice 메서드에서 타입변수 와일드카드가 사용되었다. 그렇기 때문에 매개변수로 fruitBox와 appleBox모두 사용이 가능하다.

 

지네릭 메서드

메서드 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라고한다.

메서드에 선언된 제네릭 타입은 지역변수를 선언한 것과 같다. 메서드 내에서만 지역적으로 사용된다.

static Juice makeJuice(FruitBox<? extends Fruit> box){

 ...

}

->

static <T extends Fruit> Juice makeJuice(FruitBox box){ 

...

}

로 지네릭 메서드로 변형가능하다.

지네릭 메서드를 호출할경우 타입변수를 적어주어야한다.

ex)

System.out.println(Juicer.<Fruit>makeJuice(fruitBox));

대부분의 경우 컴파일러가 타입을 추정가능하여 생략해도 되는 경우가 많다.

 

지네릭 타입의 형변환

지네릭 타입과 넌지네릭(non-generic)타입간의 형변환은 항상 가능하다.

그러나 다른 지네릭 타입간 형변환은 불가능하다.

ex)

Box box = null;

Box<Object> objBox = null;

box = (Box)objBox;

objBox = (Box<Object>)box;

 

위의 경우엔 모두 가능하다.

다른 지네릭 타입간의 형변환

ex)

Box<Object> objBox = null;

Box<String> strBox = null;

objBox = (Box<Object>)strBox; //에러

strBox = (Box<String>)objBox; //에러

Box<Object> objBox = new Box<String>(); //에러

위의 경우 에러가 발생한다.

 

다른 지네릭 타입간의 가능한 경우는 와일드 카드인경우이다.

ex)

Box<? extends Object> wBox = new Box<String>();

위의 경우는 가능하다.

 

728x90

'Programming > JAVA' 카테고리의 다른 글

에너테이션(annotation)  (0) 2021.08.11
열거형(Enums)  (0) 2021.08.10
Collection 정리  (0) 2021.08.07
Map  (0) 2021.08.07
HashSet & TreeSet  (0) 2021.08.03
728x90

컬렉션 프레임워크의 핵심 인터페이스

1.List : 순서가 있는 데이터 집합. 데이터 중복 허용

구현 클래스 - ArrayList, LinkedList, Stack, Vector 등

2.Set : 순서가 없는 데이터 집합. 데이터 중복 허용하지않는다.

구현 클래스 - HashSet, TreeSet 등

3.Map : 키(key)와 값(value)의 쌍으로 이루어진 데이터 집합. 순서가 없고, 키의 중복은 허용하지않으며, 값의 중복은 허용한다.

구현 클래스 - HashMap, TreeMap 등

 

List와 Set의 공통부분을 뽑아 새로운 인터페이스 Collection을 추가로 정의했다.

 

구현클래스의 특징

List

1.ArrayList : 배열 기반. 데이터의 추가 삭제의 성능이 좋지않다. 임의의 요소에 대한 접근성이 뛰어나다.

2.LinkedList : 연결기반. 데이터의 추가와 삭제에 성능이 좋다. 접근성(탐색)이 좋지않다.

3.Stack : LIFO(Last In First Out) 후입 선출의 특성을 가진다.

4.Queue : LinkedList기반으로 만들어 졌으며 FIFO(First In First Out)의 특성을 가진다.

 

Set

1.HashSet : HashMap을 이용해서 구현했으며 해싱기법에 의해 데이터가 저장된다.

2.TreeSet :  TreeMap을 이용해서 구현했으며 이진

 

Map

1.HashMap : 배열과 연결(LinkedList)의 결합된 형태이다. 데이터의 추가, 삭제, 검색 등 모두 띄어나다.

2.TreeMap : 연결(LinkedList)기반으로 만들어졌다. 정렬과 탐색에 적합하다. 기본적으로 데이터들의 key들이 오름차순으로 정렬된다.

 

 

 

 

 

 

 

 

 

 

728x90

'Programming > JAVA' 카테고리의 다른 글

열거형(Enums)  (0) 2021.08.10
지네릭스(Generics)  (0) 2021.08.07
Map  (0) 2021.08.07
HashSet & TreeSet  (0) 2021.08.03
Arrays & Comparator  (0) 2021.08.02
728x90

Map

Map : 인터페이스로 키(key)와 값(value)을 한쌍으로 가지는 데이터를 저장하는 특징이있다.

         키(key)는 중복을 허용하지 않으며, 값(value)의 경우 중복이 가능하다.

 

HashMap의 경우 해싱(hasing)기법을 이용하여 데이터를 저장하기 때문에 많은 양의 데이터를 저장하고 있는 경우 검색기능에서 뛰어난 성능을 가진다. 

HashMap은 키(key)와 값(value)를 가지는 Entery 내부클래스를 정의하고 Entry 배열을 선언하여 사용한다.

HashMap에서 key와 value는 모두 Object타입으로 선언되어있다. 그러므로 어떤 객체도 HashMap컬렉션에 저장될 수 있다.

 

메서드

HashMap() : HashMap객체를 생성

HashMap(int initialcapacity) : initialCapacity크기 만큼의 HashMap을 생성한다.

void clear() : HashMap의 모든 객체 제거

Object clone() : HashMap을 복제해서 반환

boolean containsKey(Object key) : HashMap에 key가 존재하는지 확인

boolean containsValue(Object value) : HashMap에 value가 존재하는지 확인

Set entrySet() : HashMap에 저장된 키와 값을 엔트리(키와 값의 결합)형태로 Set에 저장하여 반환

Object get(Object key) : key에 해당하는 value 반환

boolean isEmpty() : HashMap이 비어있는지 알려준다.

Set keySet() : HashMap의 모든 key를 Set으로 반환

Object put(Object key, Object value) : 지정된 키와 값을 HashMap에 저장

void pushAll(Map m) : Map에 저장된 모든 요소를 HashMap에 저장한다.

Object remove(Object key) : HashMap에서 지정된 키로 저장된 객체를 삭제

Object replace(Object key, Object value) : key에 해당하는 value를 매개변수 value로 교체한다.

boolean replace(Object key, Object oldvalue, Object newvalue) : key와 oldvalue가 일치하는 객체를 새로운 객체 Object newvalue로 교체한다.

int siez() : HashMAp에 저장된 요소의 개수를 반환

Collection values() : HashMap에 저장된 모든 값을 컬렉션 형태로 반환

 

key를 id, value를 비밀번호로 가정하여 데이터를 저장하고 탐색하였다.

HashMap.put()에서 key가 중복되는 경우 뒤에 저장한값이 덮어쓴다.

 

Map의 모든 요소들을 출력할때는 HashMap.entrySet()을 통해 Set으로 반환하고 Iterator를 통해 각 요소들에 접근한다.

위 예제는 HashMap의 value가 HashMap인 형태인 경우이다.

 

해싱과 해시함수

해싱 : 해시함수(hash function)를 이용해서 데이터를 해시테이블(hash table)에 저장하고 검색하는 기법

해싱을 구현한 컬렉션 클래스에는 HashSet, HashMap, Hashtable 등잉 있다.

해싱에서는 일반적으로 배열과 링크드 리스트의 자료구조 조합을 사용한다.

 

TreeMap

TreeMap은 이진검색트리의 형태로 키와 값의 쌍으로 만들어진 데이터를 저장한다.HashMap보다 TreeMap이 검색성능은 더 뛰어나지만 다른 기능들은 대부분 HashMap을 사용하는것이 좋다. 정렬이 필요한경우 TreeMap이 좋다.

 

TreeMap에 data의 문자들을 저장한다. 해당 문자를 Key로하고 문자의 중복수를 value로 TreeMap에 저장한다.

TreeMap에 의해 Key가 오름차순으로 자동정렬되는것을 볼 수 있다. 이후 TreeMap을 Set으로 변환하고 정렬 기준을 새롭게 주어 중복수가 많은 순으로 저장되게 하였다.

 

Collections

동기화 컬렉션

멀티 쓰레드 프로그래밍에서 하나의 컬렉션에대해 여러 쓰레드가 동시에 접근하는 경우가 생길 수 있다. 이러한 경우 사용하면 좋은것이 동기화 컬렉션이다. 동기화 컬렉션을 통해 멀티쓰레드 환경에서 컬렉션 동시접근 충돌을 방지할 수 있다.

static Collection synchronizedCollection(Collection c)

static List synchronizedList(List list)

static Set synchronizedSet(Set s)

static Map synchronizedMap(Map m)

static SortedSet synchronizedSortedSet(SortedSet s)

static SortedMap synchronizedSortedMap(SortedMap m)

 

ex)

List syncList = Collections.synchronizedList(new ArrayList(...));

 

변경불가 컬렉션(상수 컬렉션)

컬렉션을 변경할 수 없도록 생성할 수 있다. 해당 컬렉션은 읽기전용인 컬렉션이다.

static Collection unmodifiableCollection(Collection c)

static List unmodifiableList(List list)

static Set unmodifiableSet(Set s)

static Map unmodifiableMap(Map m)

static NavigableSet unmodifiableNavigableSet(NavigableSet s)

static SortedSet unmodifiableSortedSet(SortedSet s)

static NavigableMap unmodifiableNavigableMap(NavigableMap m)

static SortedMap unmodifiableSortedMap(SortedMap m)

 

싱글톤 컬렉션(객체 하나만 저장하는 컬렉션)

static List singletonList(Object o)

static Set singleton(Object o)

static Map singletonMap(Object key, Object value)

 

한종류의 객체만 저장하는 컬렉션

static Collection checkedCollection(Collection c, Class type)

static List checkedList(List list, Class type)

static Set checkedSet(Set s, Class type)

static Map checkedMap(Map m, Class keyType, Class valueType)

static Queue checked Queue(Queue queue, Class type)

static NavigableSet checkedNavigableSet(NavigableSet s, Class type)

static SortedSet checkedsortedSet(SortedSet s, Class type)

static NavigableMap checkedNavigableMap(NavigableMap m, Class keyType, Class valueType)

static SortedMap checkedSortedMap(SortedMap m, Class keyType, Class valueType)

 

 한종류의 객체만 저장하는 컬렉션의 경우 제네릭스(Generics)로 충분히 가능할것 같다.

 

728x90

'Programming > JAVA' 카테고리의 다른 글

지네릭스(Generics)  (0) 2021.08.07
Collection 정리  (0) 2021.08.07
HashSet & TreeSet  (0) 2021.08.03
Arrays & Comparator  (0) 2021.08.02
Iterator & ListIterator & Enumeration  (0) 2021.07.30
728x90

HashSet

HashSet은 Set인터페이스를 구현한 가장 대표적인 컬렉션이다.

Set의 특징은 중복을 허용하지않으며 순서가 없다는 것이다.

HashSet을 이용하여 컬렉션 내의 중복 요소들을 제거할 수 있다.

 

메서드

hashSet() :  HashSet객체를 생성하는 생성자이다.

HashSet(Collection c) : 컬렉션 c를 포함하는 HashSet을 생성하는 생성자이다.

HashSet(int initialCapacity) : 주어진 값을 초기 용량으로하는 HashSet객체를 생성한다.

HashSet(int initialCapacity, float loadFactor) : 초기 용량과 load factor를 지정하는 생성자.

load factor는 저장공간을 늘리는 기준 같은것이다. 0.8로 지정하면 기존 저장공간의 80%가 채워졌을 때 해당 저장공간을 두배로 늘린다.

 

boolean add(Object o ) : 새로운 객체 o를 hashset에 추가한다.

boolean addAll(Collection c) : 주어진 컬렉션 c를 hashset에 추가한다. 컬렉션을 추가할때는 addAll, 객체를 추가할 때는 add 를 사용한다.

 

void clear() : hashset에 존재하는 모든 요소들을 삭제한다.

Object clone() : HashSet의 복제를 반환한다. 주소복사가 아닌 값복사이다.(얕은 복사)

boolean contains(Object o) : 지정된 객체를 포함하고 있는지 확인한다.

boolean containsAll(Collection c) : 컬렉션 c가 가지고있는 요소들을 hashset이 가지고있는지 확인한다.

객체의 탐색은 contains 컬렉션의 탐색은 containsAll로 가능하다.

 

boolean isEmpty() : HashSet이 비어있는지 확인한다.

Iterator iterator() : Iterator 객체를 반환한다.

boolean remove(Object o) : HashSet에서 객체  o를 찾아 삭제한다. 성공하면 true, 실패하면 flase

boolean removeAll(Collection c) : HashSet에 존재하는 요소중 모든 Collection c에 존재하는 요소와 일치하는 요소들을 삭제한다.

boolean retainAll(Collection c) : 주어진 컬렉션에 저장된 객체와 동일한 것만 남기고 모두 삭제한다.

int size() : 지정된 객체의 수를 반환한다.

Object[] toArray() : 객체들을 객체배열 형태로 반환한다.

Obect[] toArray(Object[] a) : 저장된 객체들을 주어진 객체배열 a에 넣는다.

 

Set의 add예시이다. add메소드 사용시 중복된 값들은 false가 리턴되며 Set에 저장되지 않는다.

Interger 1과 String 1은 다르기 때문에 해당 Set에 저장될 수 있다.

 

 

사용자 정의클래스의 객체를 Set에 저장할 경우 equals()와 hashCode()를 적절하게 오버라이딩 해주어야 한다. 오버라이딩 해주지 않을경우 같은 속성값을 갖는 객체가 Set에 함께(중복) 저장될 수 있다.

 

중복된 값은 저장되지 않는 특징을 이용하여 각 합집합, 교집합, 차집합 등을 만들수 있다.

 

TreeSet

TreeSet은 이진 탐색 트리(Binary Search tree)라는 자료구조 형태로 데이터를 저장하는 컬렉션이다.

Set인터페이스 기반으로 구현했으며 중복 저장은 되지않으며 저장순서를 유지하지 않습니다. 이진 탐색트리 구조형태로 저장되기 때문에 객체 추가 및 저장시 자동으로 정렬됩니다.

 

메서든 대부분 HashSet메서드와 유사하며 별도로 사용하는 메서드들이 존재합니다.

메서드

 

Object ceiling(Object o) : 지정된 객체와 같은 객체를 반환. 없는 경우 큰값중 Object o와 가장 가까운 값을 반환

Object floor(Object o) : 지정된 객체와 같은 객체를 반환. 없는 경우 작은값중 Object o와 가장 가까운 값을 반환

Comparator comparator() : TreeSet의 정렬기준(Comparator)를 반환한다.

NavigableSet descendingSet() : TreeSet에 저장된 요소들을 역순으로 정렬하여 반환한다.

SortedSet headSet(Object toElement) : 지정된 객체보다 작은 값의 객체들을 반환한다.

SortedSet tailSet(Object fromElement) : 지정된 객체보다 큰 값의 객체들을 반환한다.

SortedSet subSet(Object fromElement, Object toElement) : 범위검색(fromElement와 toElement 사이)의 결과를 Set형태로 반환한다.

 

Object first() : 정렬된 순서에서 첫번째 객체를 반환한다. 일반적으로 가장 작은 객체이다.  

Object last() : 정렬된 순서에서 가장 큰값을 반환한다. 일반적으로 가장 큰 객체이다.

Object pollFirst() : TreeSet의 첫번째 요소

Object pollLast() : TreeSet의 마지막 번째 요소

 

TreeSet()의 경우 이진탐색 트리 자료구조를 가지기 때문에 값 삽입과 동시에 정렬이 된다.

 

문자열 TreeSet

subSet메서드를 통해 정렬된 Set을 잘라서 반환할수 있습니다.

 

 

 

 

728x90

'Programming > JAVA' 카테고리의 다른 글

Collection 정리  (0) 2021.08.07
Map  (0) 2021.08.07
Arrays & Comparator  (0) 2021.08.02
Iterator & ListIterator & Enumeration  (0) 2021.07.30
Stack과 Queue  (0) 2021.07.29
728x90

Arrays

Java에서 제공하는 Arrays클래스에는 배열을 다루는데 유용한 많은 메서드들을 정의하고 있다.

 

메서드

copyOf(), copyOfRange() : 배열 전체 또는 일부를 복사하여 새로운 배열을 만든후 반환한다.

fill(), setAll() : 배열의 모든 공간을 지정한 값으로 채운다. setAll 의경우 배열을 채우는데 사용할 인터페이스 또는 람다식 식을 지정해 줄 수 있다.

sort() : sort는 배열을 정렬할 때 사용한다. 

binarySearch() : 정렬된 배열에서 특정 값을 검색할때 사용한다.

equals(),deepEquals() : 배열에 저장된 요소를 비교할때 사용한다. 다차원 배열에서는 deepEquals()를 사용한다. 

toString(), deepToString() : 배열에 저장된 요소들을 출력해줄때 사용한다. 다차원배열의 경우 deepToString()을 사용한다.

asList(Object... a) : 배열을 List로 반환한다. asList가 반환한 List의 크기는 변경이 불가능하고 크기를 변경해야한다면

                          List list = new ArrayList(Arrays.asList(1,2,3,4,5)) 등으로 생성하는것이 좋다.

 

Comparator & Comparable

comparator와 Comparable은 모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있다.

 

Comparable : 기본 정렬기준을 구현하는데 사용.

Comparator : 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용

 

상속받은 클래스에서 Comparartor 인터페이스의 compare() 또는 Comparable인터페이스의 compareTo() 메소드를 구현하여 정렬기준을 만든다. 

 

역순으로 정렬할 경우  *-1을 해주면된다.

 

 

 

 

 

728x90

'Programming > JAVA' 카테고리의 다른 글

Map  (0) 2021.08.07
HashSet & TreeSet  (0) 2021.08.03
Iterator & ListIterator & Enumeration  (0) 2021.07.30
Stack과 Queue  (0) 2021.07.29
ArrayList LinkedList  (0) 2021.07.29

+ Recent posts