반응형

자바에서 열거형이 무엇인지 알려드릴게요.


먼저 열거란 무엇인지 사전을 볼까요???



열거 : 여러 가지 예나 사실을 낱낱이 죽 늘어놓음.



죽~ 늘어놓음.


열거형마찬가지예요.




관련된 상수들을 죽 늘어놓은 거예요.


여기서 중요한 것은 모두 상수!!라는 점~





어쩔 때 쓰이냐면


달력을 만든다고 할 때


월요일 화요일 수요일 목요일 ...


이렇게 쓰는 것보다




월요일 = 1

화요일 = 2

수요일 = 3

...



 

이런 식으로 코드화해 놓는 게 효과적일 거예요.




이런 상수들을 모아놓아서 활용하기 쉽게 해주는 것이 열거형이에요.


열거형이라고 하니 자료형과 비슷한 것 같죠?


맞아요!!


자료형처럼 열거형 안에 있는 상수들은 열거형으로 선언돼요!


int a;와 같이


열거형명 데이터;표현돼요.


먼저 열거형을 살펴보기 전에


열거형이 없을 때 어떻게 상수들을 선언했을지 살펴볼게요.



우선 변수로 상수를 선언!!



private final static int MONDAY = 1;

private final static int TUESDAY = 2;

private final static int WEDNESDAY = 3;

private final static int THURSDAY = 4;

private final static int FRIDAY = 5;

private final static int SATURDAY = 6;

private final static int SUNDAY = 7;


이런 식으로 사용하기도 해요.


이때의 문제점은 한번 선언된 변수명을 중복 사용할 수 없다는 것과


상수를 추가해야 할 경우 내용이 많아지며 메모리 공간을 많이 차지한다는 점이에요.



그래서


public final static이 생략되어있는


인터페이스를 이용하거나 class를 이용해요.



interface Day{

    int MONDAY = 1;

    int TUESDAY = 2;

    int WEDNESDAY = 3;

    int THURSDAY = 4;

    int FRIDAY = 5;

    int SATURDAY = 6;

    int SUNDAY = 7;

}


여기서 interface를 이용할 경우에 문제가 있어요.


A1과 A2라는 인터페이스를 만들었을 때


두 인터페이스는 서로 다른 타입이기 때문에 비교가 불가능해야 해요.


그런데 if(A1 == A2) 를 했을 경우 경고 메시지를 볼 수 없다는 것이 문제에요.



그래서


Class를 정의해 사용합니다.



class Day{

   public final static Day MONDAY = new Day();

   public final static Day TUESDAY = new Day();

   public final static Day WEDNESDAY = new Day();

   public final static Day THURSDAY = new Day();

   public final static Day FRIDAY = new Day();

   public final static Day SATURDAY = new Day();

   public final static Day SUNDAY = new Day();

}


마찬가지로 class를 이용할 때도 문제가 있는데


switch 문에서 사용이 불가능하다는 것이에요.


switch(조건)


여기서 조건에 들어가는 데이터 타입이 제한적이라


class를 정의해서 사용할 경우 에러가 발생해요.




이런 문제점을 해결해 주는 것이 enum이에요.



enum Day{

           MONDAY,TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;

}


public class EnumStudy {


           public static void main(String[] args) {

                     // TODO Auto-generated method stub

                     System.out.println("월요일 : " + Day.MONDAY);

                     System.out.println("화요일 : " + Day.TUESDAY);

                     System.out.println("수요일 : " + Day.WEDNESDAY);

                     System.out.println("목요일 : " + Day.THURSDAY);

                     System.out.println("금요일 : " + Day.FRIDAY);

                     System.out.println("토요일 : " + Day.SATURDAY);

                     System.out.println("일요일 : " + Day.SUNDAY);

           }

}




또한 숫자를 사용하고 싶다면 아래처럼 해주면 됩니다.




enum Code{

           ONE(1), TWO(2), THREE(3);

          

           Code(int num){//생성자

                     CodeNum = num;

           }


           int CodeNum;

           public int getCodeNum(){

                     return CodeNum;

           }

}


public class EnumStudy {


           public static void main(String[] args) {

                     // TODO Auto-generated method stub

                     System.out.println(Code.ONE + " : " + Code.valueOf("ONE").getCodeNum());

                     System.out.println(Code.TWO + " : " + Code.valueOf("TWO").getCodeNum());

                     System.out.println(Code.THREE + " : " + Code.valueOf("THREE").getCodeNum());

           }

}





enum을 이용할 때 생성자는 자동으로 private선언돼요.


그래서 타입의 안정성이 보장돼요.


외부에서 접근이 불가능하며 new 키워드로 생성할 수도 없어요.


물론 clone(복사)도 하지 못한답니다~ 

[출처] 자바 :: 열거형 (enum)|작성자 프로

 

 

1.열거형이란?

열거형은 C와 C++에서도 썼던타입으로 특정의 정수와 그 정수를 의미하는 단어로 되어 자료형이였죠.

저의 C언어 12강에서 1번째로 소개했던게 열거형인데요 C와 C++의형태는 뭐 다음과 같습니다.


 

enum은 각각 순서대로 0부터 시작해서 배정되며 원한다면 자기가 다른 숫자를 배정할 수 있습니다.

그리고 enum형에서 정의된 토큰들은 전부 상수이며 값의 수정은 불가능합니다.


원래는 자바에서도 없던 기능이였으나 JDK1.5부터 열거형이 사용이 가능합니다.

사용방식은 C와 유사하게 사용할 수 있으나 자바의 열거형은 이미 하나로 훌륭한 객체입니다.

따라서 C와는 차원이 다르게 높은 레벨로 프로그래밍을 할 수 있습니다.


사용방식은 기존의 Class를 사용하는것 처럼 쓸수도 있고 따로 Enum전용으로 만들 수 있습니다.

뭐 차이라면 public class를 쓰냐 package class를 쓰냐의 차이 처럼 public enum을 쓰고싶으면

전용으로 만들어서 쓰고 package enum을 써도 상관없다면 그냥 아무 class,intefrface,enum등에 같이써도 됩니다.


2.열거형의 사용

java에서 열거형은 기본적인 스탠다드한 형식은 다음과 같습니다.

 

public enum이므로 소스파일을 따로 만들어줘야합니다.

위의 구문의 의미는 Trump라는 열거형은 그 값으로 SPADE,HEART,CLUB,DIAMOND밖에 가지지 못함을 의미합니다.

즉 제일 윗줄에 쓰는 토큰의 나열은 그 열거형이 가질수 있는 값의 전부라고 보시면됩니다.


이번에는 main메소드를 보도록하죠.

 

같은 패키지내에있는 TestMain클래스의 main함수에서 Trump형으로 t를 선언하고 그 값으로 Trump.CLUB을 넣은 모습입니다.

Trump enum은 이미 그 하나로도 interface나 class, abstract class의 객체이지만 생성자를 호출하진 않습니다.

정확히 말하면 생성자를 호출하지 않는건 아니지만 저희가 호출할 일은 없습니다.

enum은 이미 제가 정의해 놓은 값만 소유하는게 가능하며 다른 값을 소유하는건 불가능합니다.

따라서 Tump t형은 CLUB과 SPADE,HEART,DIAMOND만 가지는게 가능합니다.


enum 상수의 호출은 enum_name.enum_const 와 같은 형태로만 접근할 수 있습니다.

위 처럼 Trump.CLUB;같은 형태만 쓸 수 있다는 것이죠.


그리고 위의 예를 봐서 알겠지만 enum형을 그 이름으로 출력할경우에는 문자열로 출력이 됩니다.

따라서 System.out.println(Trump.CLUB);의 구문은 Trump.CLUB은 문자열로 취급되서 출력하게 되는 것이죠.


이미 이 정도만해도 enum의 존재가치는 충분하지만 enum은 여기서 더더욱 나아가서

훨씬 클래스에 근접하게 사용할 수 있습니다. 이는 C와 C++은 누리지 못했던 특권이죠.


 

이 코드는 일반적인 클래스구조와 굉장히 유사합니다. 이 코드하나로 enum의 성질을 대부분알 수 있습니다.

각각의 상수 토큰에는 그 의미를 부여할 수 있습니다.

위의 예시는 SPADE에는 3을 HEART에는 7을 같은 방식으로 나머지에도 값을 부여했습니다.


이렇게 사용하려면

Token(value)

와 같은 형태로 사용해야 합니다.


만약 이런식으로 사용한다면 이제는 명시적으로 생성자를 지정해저야합니다.

위의 SPADE(3)이라는 구문은 생성자의 매개변수가 1개짜리은 생성자를 호출해야만 하겠다 라는 뜻입니다.

따라서 이제는 생성자를 명시적으로 선언해줄 필요가 생깁니다.

단 이 생성자는 저희가 직접쓰는건 아니라 자바가 알아서 적절한 타이밍에서 사용하게 됩니다.

애당초 사용하고싶어도 사용하는것도 불가능 합니다. 이게 불가능한 이유는


보시면 아시겠지만 생성자는 private가 디폴트로 설정되며 이 디폴트를 바꾸는건 불가능합니다.

즉 enum의 생성자는 모두 private입니다.


 

생성자의 호출타이밍은 우리가 정확하게 예측하기는 힘들지만 확실한건

저희가 호출하는건 불가능하고 이미 Trump가 필요한 순간에 생성자가 자동으로 호출하게됩니다.


 

생성자의 호출타이밍을 알기위해서 한줄의 코드를 추가했습니다.

main메소드는 위의 클럽을 출력하는 메소드를 그대로 토시하나 바꾸지 않고 사용했습니다.

저희가 사용한건 클럽 하나였지만 이미 생성자는 4번 호출이되고 더이상 호출되지 않습니다.


저 생성자가 값으로 정수를 받았지만 사실 정수를 받았다고 끝이 난게 아닙니다.

이 정수를 식별자중 하나로 쓰고싶다면 그 정수를 각각의 enum이 가지고 있어야합니다.

그러기 위해서 존재하는게 int val입니다.

각각의 생성자는 정수를 받으며 그 정수를 멤버로 사용할 수 있습니다.

또한 set과 get을 사용해서 실행시간동안 바꾸거나 값을 확인하는것 역시 가능합니다.


여기서 궁금한점이 만약 실행시간에서 값을 변경하게 되면 어떻게 될까요?

그 궁금증을 풀기위해서 아래의 예제를 한번 실행해보도록합시다.

보시면 처음에는 CLUB이 15였지만  한번 2로 수정하면 어디에서 접근을 하던 새로만들던 간에

무조건 값이 2로 고정이 됩니다.



 


enum은 더 나아가서 각각의 토큰마다 파라메터 갯수를 다르게 줄 수도 있습니다.

그 경우 생성자를 그 파라메터 수에 맞게 늘려주면 장땡입니다.

전부다 두개씩을 줄 수도 있지만 한개만 두개를 줄 수도 있고 한개만 3개를 줄 수도 있는 것이죠.


 

또한 enum은 class와 interface등과는 다르게 ==연산자를 사용해서 비교할 수 있습니다.

equals만 써야하는 다른 객체형들과달리 enum객체는 ==연산을 사용할 수 있는 것이죠.


3.java.lang.Enum

이 패키지는 모든 enum의 조상입니다.

모든 class의 조상이 java.lang.Object이듯이 모든 enum의 조상은 java.lang.Enum이죠.

또 신기하게도 Enum은 abastract class로 구현되어 있으므로 Enum클래스는 Object의 후손이기도 합니다.

모든 enum의 조상은 Object이며 또한 Enum이므로 Obeject클래스가 지원하는 메소드들을 모조리 사용가능하며

또한 Enum이 지원해주는 메소드 역시 사용기 가능합니다. 그 목록은 아래와 같습니다.


3-1.getDeclaringClass

 

이 메소드는 열거형의 클래스 자체를 반환하는 메소드입니다.

Class 클래스로 반환하는데 아직 Class 클래스는 하지 않았으므로 이런 기능이 있다만 알아 두시면 됩니다.


3-2.name()

 

이 메소드는 상수의 토큰 그 자체를 반환합니다. 즉 Trump.CLUB이 있다면 CLUB을 반환하는거죠.

보통 name 메소드를 안쓰고 토큰만써도 name이 반환되기에 잘 사용되진 않습니다/


3-3.ordinal()

 

이 메소드는 사용하면 지금 사용중인 토큰이 몇번째 토큰인지를 알아낼 수 있습니다.


3-4.valueOf(String name)

 

이 메소드는 열거형을 쓰게된다면 굉장히 많이 쓰는 메소드인데 토큰의 이름으로 해당 상수를 추적할 수 있습니다.


 

보시다시피 Trump형 enum에서 CLUB에 해당하는 값의 숫자를 알고싶을경우 다음과 같은 방법을 사용할 수 있습니다.


4.열거형 추상 메소드

열거형에도 추상메소드를 적용할 수 있습니다. 또한 열거형에도 익명 enum을 사용할 수 있습니다.

이 방식은 조금만 생각해보면 어떻게 할지 쉽게 감을 잡을 수 있습니다.


 

보시면 마지막으로 PrintTrump를 추상메소드로 선언한것을 알 수 있습니다.

추상메소드로 선언즉시 모든 열거형 토큰들에 빨간줄이 끄입니다.

왜냐하면 추상메소드를 구현해줘야하기 때문이죠.

따라서 이들은 모두 익명클래스를 써서 구현해줘야합니다.


 

이런식으로 모두 구현해주면 되겠습니다.


5.마치며

이번엔 열거형을 했는데요, 자바에서 열거형있으면 좋겠다고 빼애액거려서

JDK1.5버전에서 기껏해서 만들어줬는데 이미 사람들은 class로만드는게 익숙한지

사실 코드 보다보면 잘 보이진 않습니다.

그러나 enum도 써보면 많은 도움이 될것 같애요.

반응형

'Study > Java' 카테고리의 다른 글

열거형 enums  (0) 2018.03.19
Collection Framwork 1.3 LinkedList  (0) 2018.03.05
Collection Framework 1.2 ArrayList  (0) 2018.03.05
java.time 패키지를 이용하여 달력 만들기  (0) 2018.03.05
Collection Framework 1.7 Comparator, Comparable  (0) 2018.02.26
반응형

2.1 열거형 이란?

 - 실제 값이 같아도 타입이 다르면 조건식의 결과가 false가 된다.

 

예)

class Card{

static final int CLOVER = 0;

static final int HEART = 1;

static final int DIAMOND = 2;

static final int SPADE = 3;

 

static final int TWO = 0;

static final int THREE = 1;

static final int FOUR = 2;

 

final int kind;

final int num;

}

=>

class Card {

enum Kind { CLOVER, HEART, DIAMOND, SPADE }

enum Value { TWO, THREE, FOUT }

 

final Kind kind;

final Value value;

}

 

if (Card.CLOVER == Card.TWO) // true 지만 false이어야 의미상 맞음

if (Card.kind.CLOVER == Card.Value.TWO) // false. 값은 같지만 타입이 다름

 

2.2 열거형의 정의와 사용

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

 

enum Direction {EAST , SOUTH, WEST, NORTH}

 

class Unit{

int x,y; // 유닛의 위치

Direction dir; // 열거형을 인스턴스 변수로 선언

 

void init(){

dir = Direction.EAST; // 유닛의 방향을 EAST로 초기화

}

}

 

- 상수간 비교에는 '=='를 사용할 수 있다.

'<','>' 처럼비교연산자는 사용할 수 없고 compareTo()는 사용가능 하다. compareTo()는 두 비교대상이 같으면 0, 왼쪽이 크면 양수, 오른쪽이 크면 음수를 반환한다.

 

if (dir ==Direction.EAST){

x++;

}

else if (dir>Direction.WEST){ // 비교연산자 사용불가.

}

 

else if (dir.compareTo(Direction.WEST) >0){

}

 

- switch문의 조건식에도 열거형을 사용할 수 있다.

void move(){

switch(dir){

case EAST: x++; // Direction.EAST라고 쓰면안됨.

break;

case WEST: x--;

break;

case SOUTH: y++;

break;

case NORTH: y--;

break;

}

}

 

 // case문에 열거형의 이름은 적지 않고 상수의 이름만 적어야 한다는 제약이 있다.

 

- 열거형의 조상 java.lang.Enum

열거형 Direction에 정의된 모든 상수를 출력하려면?

 

Direction[] dArr = Direction.Values();

 

for (Direction d : dArr)

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

 

- Values() 는 열거형의 모든 상수를 배열에 담아 반환한다. 이 메서드는 모든 열거형이 가지고 있는것으로 컴파일러가 자동으로 추가해 준다.

- ordinal()은 모든 열거형의 조상인 java.lang.Enum클래스에 정의된 것으로 열거형 상수가 정의된 순서를 정수로 반환한다.

 

이외 Enum클래스 메서드 정의

- Calss <E> getDeclaringCalss() : 열거형의 calss객체를 반환한다.

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

- int ordinal() : 열거형 상수가 정의된 순서를 반환한다.(0부터시작)

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

 

 

 

 

예제.

 

 

package enumeration;

enum Direction { EAST, SOUTH, WEST, NORTH}

 

public class enums{

        public static void main(String[] args) {

               Direction d1 = Direction.EAST;

               Direction d2 = Direction.valueOf("WEST");

               Direction d3 = Enum.valueOf(Direction.class, "EAST");

              

               System.out.println("d1="+d1);

               System.out.println("d2="+d2);

               System.out.println("d3="+d3);

              

               System.out.println("d1 ==d2 ?" +(d1==d2));

               System.out.println("d1 ==d3 ?" +(d1==d3));

               System.out.println("d1.equals(d3) ?" +d1.equals(d3));

               //System.out.println("d2>d3?" +(d1>d3)); // 에러

               System.out.println("d1.compareTo(d3)?" +(d1.compareTo(d3)));

               System.out.println("d1.compareTo(d2)?" +(d1.compareTo(d2)));

              

               switch(d1) {

               case EAST:

                       System.out.println("The direction is EAST.");

                       break;

               case SOUTH:

                       System.out.println("The direction is SOUTH");

                       break;

               case WEST:

                       System.out.println("The direction is WEST");

                       break;

               case NORTH:

                       System.out.println("The direction is NORTH");

                       break;

               default:

                       System.out.println("Invalid direction.");

                       break;

               }

              

               Direction[] dArr = Direction.values();

              

               for(Direction d: dArr)

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

        }

}

 

 

출력 결과 :

d1=EAST
d2=WEST
d3=EAST
d1 ==d2 ?false
d1 ==d3 ?true
d1.equals(d3) ?true
d1.compareTo(d3)?0
d1.compareTo(d2)?-2
The direction is EAST.
EAST=0
SOUTH=1
WEST=2
NORTH=3

 

2.3 열거형에 멤버 추가하기.

 

열거형 상수의 값이 불규칙적인 경우 이때는 다음과 같이 열거형 상수의 이름 옆에 원하는 값을 괄호()와 함께 적어주면 된다.

 

enum Direction { EAST(1), SOUTH(5), West(-1), NORTH(10)}

 

그리고 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자를 새로 추가해 주어야 한다.

 주의할 점은 열거형 상수를 정의한 다음에 다른 멤버들을 추가해야 한다.

 

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;}

}

 

// Direction d = new Direction(1); 에러. 열거형의 생성자는 외부에서 호출 불가.

 

열거형의 생성자는 제어가자 묵시적으로 private이다.

 

필요에 따라 열거형 상수에 여러 값을 지정할 수도 있다. 다만 그에 맞게 인스턴스 변수와 생성자 등을 새로 추가해 주어야 한다.

 

enum Direction {

EAST (1,">"), SOUTH(2,"V"), WEST(3,"<"), NORTH(4,"^");

 

private final int value;

private final String symbol;

 

Direction(int value, Sting symbol){

this.value = value;

this.symbol = symbol;

}

 

public int getValue(){ return value;}

public String getSymbol() { return symbol;}

}

 

예제 2.

package enumeration;

enum Direction {

        EAST (1,">"), SOUTH(2,"V"), WEST(3,"<"), NORTH(4,"^");

       

        private static final Direction[] DIR_ARR = Direction.values();

        private final int value;

        private final String symbol;

       

        Direction(int value, String symbol){

               this.value = value;

               this.symbol = symbol;

        }

 

 

        public int getValue() {return value;}

        public String getSymbol() {return symbol;}

       

        public static Direction of(int dir) {

               if (dir <1||dir >4) {

                       throw new IllegalArgumentException("Invalid value :"+dir);

               }

               return DIR_ARR[dir-1];

        }

        public Direction rotate(int num) {

               num = num%4;

               if(num <0)num+=4;

               return DIR_ARR[(value-1+num)%4];

        }

        public String otString() {

               return name()+getSymbol();

        }

}

public class enums1 {

 

        public static void main(String[] args) {

               for(Direction d: Direction.values())

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

       

        Direction d1 = Direction.EAST;

        Direction d2 = Direction.of(1);

       

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

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

       

        System.out.println(Direction.EAST.rotate(1));

        System.out.println(Direction.EAST.rotate(2));

        System.out.println(Direction.EAST.rotate(-1));

        System.out.println(Direction.EAST.rotate(-2));

        }

 

}

 

 

출력 결과:

 EAST=1

SOUTH=2

WEST=3

NORTH=4

d1=EAST, 1

d2=EAST, 1

SOUTH

WEST

NORTH

WEST


* 열거형에 추상 메서드 추가하기

열거형 Transportation은 운송 수단의 종류 별로 상수를 정의하고 있으며, 각 운송 수단에는 기본요금(BASIC_FARE)이 책정되어 있다.

enum Transportation {
BUS(100), TRAIN(150), SHIP(100), AIRPLANE(300);

private static final BASIC_FARE;

private Transportation(int basicFare) {
BASIC_FARE = basicFare;
}

int fare(){ //운송요금 반환
return BASIC_FARE;
}
}

거리에 따라 요금을 계산하는 방식이 각 운송 수단마다 다를 것이다.
이럴 때, 열거형에 추상 메서드 'fare(int distance)' 를 선언하면 각 열거형 상수가 이 추상 메서드를 반드시 구현해야 한다.

enum Transportation {
BUS(100) {
int fare(int distance) { return distance*BASIC_FARE; }
},
TRAIN (150) {
int fare(int distance) { return distance*BASIC_FARE; }
},
SHIP(100) {
int fare(int distance) { return distance*BASIC_FARE; }
},
AIRPLANE(300){ 
int fare(int distance) { return distance*BASIC_FARE; }
};

abstract int fare(int distance); //거리에 따른 요금 계산하는 추상 메서드

protected final int BASIC_FARE; // protected로 해야 각 상수에서 접근 가능

Transportation(int basicFare) {
BASIC_FARE = basicFare;
}

public int getBasicFare() {return BASIC_FARE;}
}

예제 3. 
 

package enumeration;

 

enum Transportation {

        BUS(100) { int fare(int distance) {return distance*BASIC_FARE;}},

        TRAIN(150)     { int fare(int distance) {return distance*BASIC_FARE;}},

        SHIP(100){int fare(int distance) {return distance*BASIC_FARE;}}, 

        AIRPLANE(300){int fare(int distance) {return distance*BASIC_FARE;}};

  

        protected final int BASIC_FARE;

 

        Transportation(int basicFare){

               BASIC_FARE = basicFare;

        }

 

        public int getBasicFare() {  return BASIC_FARE;}

 

        abstract int fare(int distance);

}

public class enums1 {

        public static void main(String[] args) {

               System.out.println("bus fare ="+Transportation.BUS.fare(100));

               System.out.println("train fare ="+Transportation.TRAIN.fare(100)); 

               System.out.println("ship fare ="+Transportation.SHIP.fare(100)); 

               System.out.println("airplane fare ="+Transportation.AIRPLANE.fare(100));

        }

}

 

 

 


출력 결과.
bus fare =10000
train fare =15000
ship fare =10000
airplane fare =30000

2.4 열거형의 이해

enum Direction { EAST, SOUTH, WEST, NORTH }

거형 상수 하나하나가 Direction 객체이다. 위의 문장을 클래스로 정의 하면 다음과 같다.

class Direction{
static final Direction EAST = new Direction("EAST");
static final Direction SOUTH = new Direction("SOUTH");
static final Direction WEST = new Direction("WEST");
static final Direction NORTH = new Direction("NORTH");

private String name;

private Direction(String name){
this.name = name;
}

}



모든 열거형은 추상 클래스 Enum의 자손이므로, Enum을 흉내 내서 MyEnum을 작성하면 다음과 같다.


abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T> {

static int id =0; // 객체에 붙일 일련번호


int ordinal;

String name ="";


public int ordinal(){ return ordinal;}


MyEnum(String name){

this.name =name;

ordinal =id++;

}


public int compareTo(T t){

return ordinal - t.ordinal();

}

}

/*

객체가 생성될 때마다 번호를 붙여서 인스턴스 변수 ordinal 에 저장, 그리고 comparable 인터페이스를 구현해서 열거형 상수간의 비교가 가능하도록 되어있다.


두 열거형 상수의 ordinal값을 서로 빼주기만 하면 된다. 만일 클래스를 MyEnum<T>와 같이 선언하였다면, compareTo()를 위와 같이 간단히 작성할 수 없었을 것이다. 타입 T에 ordinal()이 정의되어 있는지 확인할 수 없기 때문이다.

*/ 이해가 잘안가는 부분...


abstract class MyEnum<T> implements Comparable<T> {

public int compareTo(T t) {

return ordinal - t.ordinal(); // 에러 타입 T에 ordinal()이 있나?

}

}



그래서 MyEnum<T extends MyEnum<T>>와 같이 선언 한 것이며, 이것은 타입 T가 MyEnum<T>의 자손이어야 한다는 의미이다. 타입 T가 MyEnum의 자손이므로 ordinal()이 정의되어 있는 것은 분명하므로 형변환 없이도 에러가 나지 않는다.


추상 메서드를 새로 추가하면, 클래스 앞에도 abstract를 붙여줘야 하고, 각 static 상수들도 추상 메서드를 구현해 주어야 한다. 아래의 코드에서 익명의 클래스의 형대로 추상메서드를 구현한 예이다.


abstract class Direction extends MyEnum {

static final Direction EAST = new Direction("EAST"){

point move(Point p) {}

};

static final Direction SOUTH = new Direction("SOUTH"){

point move(Point p) {}

};

static final Direction WEST= new Direction("WEST"){

point move(Point p) {}

};

static final Direction NORTH = new Direction("NORTH"){

point move(Point p) {}

};


private String name;


private Direction(String name){

this.name = name;

}


abstract Point move(Point p);

}


예제 4


package enumeration;

 

abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T> {

static int id =0;

 

int ordinal;

String name ="";

 

public int ordinal() { return ordinal;}

 

MyEnum(String name){

this.name = name;

ordinal = id++;

}

  

public int compareTo(T t) {

return ordinal -t.ordinal();

}

}

abstract class MyTransportation extends MyEnum {

static final MyTransportation BUS = new MyTransportation("BUS",100) {

int fare(int distance) {return distance*BASIC_FARE;}

};

 

static final MyTransportation TRAIN = new MyTransportation("TRAIN",100) {

int fare(int distance) {return distance*BASIC_FARE;} 

};

 

static final MyTransportation SHIP = new MyTransportation("SHIP",100) {

int fare(int distance) {return distance*BASIC_FARE;}

};

 

static final MyTransportation AIRPLANE = new MyTransportation("AIRPLANE",100) {

int fare(int distance) {return distance*BASIC_FARE;}

};

 

abstract int fare(int distance);

 

protected final int BASIC_FARE;

 

private MyTransportation(String name, int basicFare) {

super(name);

       BASIC_FARE = basicFare;

}

 

public String name() {return name;}

 

public String toString() {return name;} 

} 

 

 

public class enums2 {

public static void main(String[] args) {

MyTransportation t1 = MyTransportation.BUS; 

MyTransportation t2 = MyTransportation.BUS; 

MyTransportation t3 = MyTransportation.TRAIN; 

MyTransportation t4 = MyTransportation.SHIP; 

MyTransportation t5 = MyTransportation.AIRPLANE;

 

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

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

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

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

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

System.out.println("t1==t2?"+(t1==t2)); 

System.out.println("t1.compareTo(t3)="+t1.compareTo(t3));

} 

}

 

 

 

 



출력 결과

t1 =BUS,0
t2 =BUS,0
t3 =TRAIN,1
t4 =SHIP,2
t5 =AIRPLANE,3
t1==t2?true
t1.compareTo(t3)=-1



반응형
반응형

1.3 LinkedList

 

배열은 가장기본적인 형태의 자료구조로 사용하기 쉽고 데이터를 읽어오는데 걸리는 시간이 가장 빠르다는 장점을 가지고 있다.

 

단점 1 : 크기를 변경 할 수 없다.

2. 비순차적인 데이터의 추가 또는 삭제에 시간이 많이 걸린다.

 

이를 보완하기 위해 링크드 리스트 자료구조가 고안되었다.

 

Class Node {

Node next; // 다음 요소의 주소 저장

Object obj; // 데이터를 저장.

}

 

LinkedList 클래스

 

- LinkedList() : LinkedList 객체 생성

- LinkedList(Collection c) : 주어진 컬렉션을 포함하는 LinkedList객체를 생성

- boolean add(Object o) : 지정된 객체(o)를 LinkedList의 끝에 추가, 저장에 성공하면 true, 실패하면 false

- void add(int index, Object element) : 지정된 위치(index)에 객체(element)를 추가

- boolean addAll(Collection c) : 주어진 컬렉션에 포함된 모든 요소를 LinkedList의 끝에 추가한다. 성공하면 true, 실패하면 false

- boolean addAll(int index, Collection c) : 지정된 위치에 주어진 컬렉션에 포함된 모든 요소를 추가. 성공하면 true, 실패하면 false

- void clear() : LinkedList의 모든 요소를 삭제

- boolean contains(Object c) : 지정된 객체가 LinkedList에 포함되었는지 알려줌

- boolean containsAll(Collection c) : 지정된 컬렉션의 모든 요소가 포함되었는지 알려줌

- Object get(int index) : 지정된 위치의 객체를 반환

- int indexOf(Object o) : 지정된 객체가 저장된 위치를 반환

- boolean isEmpty() : LinkedList가 비어있는지 알려준다. 비어있으면 true

- Iterator iterator() : Iterator를 반환한다.

- int lastindexOF(Object o) : 지정된 객체의 위치를 반환(끝부터 역순검색)

- ListIterator listiterator() : listIterator 를 반환

- ListIterator listiterator(int index) : 지정된 위치에서부터 시작하는 listIterator를 반환

- Object remove(int index) : 지정된 위치의 객체를 LinkedList에서 제거

- boolean remove(Object o) : 지정된 객체를 LinkedList에서 제거. 성공하면 true, 실패하면 false

- boolean removeAll(Collection c) : 지정된 컬렉션의 요소와 일치하는 요소를 모두 삭제

- boolean retainAll(Collection c) : 지정된 컬렉션의 모든 요소가 포함되어 있는지 확인.

- Object set(int index, Object element) : 지정된 위치의 객체를 주어진 객체로 바꿈

- int size() : LinkedList에 저장된 객체 수를 반환

- List subList(int fromindex, ind tolndex) : LinkedList의 일부를 list로 반환

- Object[] toArray() : LinkedList저장된 객체를 배열로 반환

- Object[] toArray(Object[] a) : LinkedList저장된 객체를 주어진 배열에 저장하여 반환

- Object element() : LinkedList의 첫 번째 요소를 반환

- boolean offer(Object o) : 지정된 객체 를 LinkedList의 끝에 추가, 성공하면 ture, 실패하면 false

- Object peek() : LinkedList의 첫 번째 요소를 반환

- Object poll() : LinkedList의 첫 번째 요소를 반환. LinkedList에서는 제거된다.

- Object remove() : LinkedList의 첫 번째 요소를 제거

- void addFirst(Object o) : LinkedList의 맨 앞의 객체를 추가

- void addLast(Object o) : LinkedList의 맨 끝의 객체를 추가.

- Iterator dexcendingiterator() : 역순으로 조회하기 위한 DescendingIterator를 반환

- Object getFirst() : LinkedList의 첫번째 요소를 반환

- Object getLast() : LinkedList의 마지막 요소를 반환

- boolean offerFirst(Object o) : LinkedList의 맨 앞에 객체를 추가 성공하면 true

- boolean offerLast(Object o) : LinkedList의 맨 뒤에 객체를 추가 성공하면 true

- Object peekFirst() : LinkedList의 첫번째 요소를 반환

- Object peekLast() : LinkedList의 마지막 요소를 반환

- Object pollFirst() : LinkedList의 첫번째 요소를 반환하면서 제거

- Object pollLast() : LinkedList의 마지막 요소를 반환하면서 제거

- Object pop() : removeFirst()와 동일

- void push(Object o) : addFirst()와 동일

- Object removeFirst() : LinkedList의 첫번째 요소를 제거

- Object removeLast() : LinkedList의 마지막 요소를 제거

- boolean removefirstOccurrence(Object o) : LinkedList에서 첫번쨰로 일치하는 객체를 제거

- boolean removeLastOccurrence(Object o) : LinkedList에서 마지막으로 일치하는 객체를 제거

 

실습1. ArrayList와 LinkedList 수행 속도 차이

 

package Collection_Framework;

import java.util.*;

public class LinkedList1 {

 

public static void main(String[] args) {

ArrayList a1 = new ArrayList(2000000);

ArrayList ll = new ArrayList();

 

System.out.println("=순차적으로 추가하기=");

System.out.println("ArrayList :"+add1(a1));

System.out.println("LinkedList :"+add1(ll));

System.out.println();

System.out.println("=중간에 추가하기=");

System.out.println("ArrayList :"+add2(a1));

System.out.println("LinkedList :"+add2(ll));

System.out.println();

System.out.println("=중간에서 삭제하기 =");

System.out.println("ArrayList :"+remove2(a1));

System.out.println("LinkedList :"+remove2(ll));

System.out.println();

System.out.println("=순차적으로 삭제하기=");

System.out.println("ArrayList :"+remove1(a1));

System.out.println("LinkedList :"+remove1(ll));

}

 

public static long add1(List list) {

long start = System.currentTimeMillis();

for(int i = 0; i<100000;i++)

list.add(i+"");

long end = System.currentTimeMillis();

return end -start;

}

 

public static long add2(List list) {

long start = System.currentTimeMillis();

for(int i = 0; i<10000;i++)

list.add(500,"X");

long end = System.currentTimeMillis();

return end -start;

}

 

public static long remove1(List list) {

long start = System.currentTimeMillis();

for(int i=list.size()-1;i>=0;i--)

list.remove(i);

long end = System.currentTimeMillis();

return end - start;

}

 

public static long remove2(List list) {

long start = System.currentTimeMillis();

for(int i=0;i<10000;i++)

list.remove(i);

long end = System.currentTimeMillis();

return end - start;

}

}

 

 

출력 결과 :

=순차적으로 추가하기=
ArrayList :62
LinkedList :49

=중간에 추가하기=
ArrayList :316
LinkedList :295

=중간에서 삭제하기 =
ArrayList :294
LinkedList :279

=순차적으로 삭제하기=
ArrayList :5
LinkedList :1

반응형

'Study > Java' 카테고리의 다른 글

열거형 개념 정리  (1) 2018.03.26
열거형 enums  (0) 2018.03.19
Collection Framework 1.2 ArrayList  (0) 2018.03.05
java.time 패키지를 이용하여 달력 만들기  (0) 2018.03.05
Collection Framework 1.7 Comparator, Comparable  (0) 2018.02.26
반응형

1.2 ArrayList

 

: 가장 많이 사용되는 컬렉션 클래스. 데이터의 저장 순서가 유지되고 중복을 허용한다.

 

기존의 vector를 개선한 것, Object배열을 이용해서 데이터를 순차적으로 저장한다.

 

0번부터 차례로 저장, 더이상 공간이 없으면 새로운 배열을 생성하여 기존배열에 저장된 내용을 복사 한 후 저장된다.

 

public class arrayList extends AbstractList

implements List, RandomAccess, Cloneable, java.io.Serializable

{

transient Object[] elementData;

}

 

ArrayList 제공 메서드

- ArrayList() : 크기가 0인 ArrayList를 생성

- ArrayList(Collection c) : 주어진 컬렉션이 저장된 ArrayList를 생성 

- ArrayList(int initialCapacity) : 지정된 초기 용량을 갖는 ArrayList를 생성

- ArrayList(int initialCapacity, int capacityincrement) : 지정된 초기 용량과 용량의 증분을 갖는 ArrayList를 생성

- boolean add(Object o) : ArrayList의 마지막에 객체를 추가, 성공하면 true

- void add(int index, Object element) : 지정된 위치(index)에 객체를 저장

- boolean addAll(Collection c) : 주어진 컬렉션의 모든 객체를 저장한다.

- boolean addAll(int index, Collection c) : 지정된 위치부터 주어진 컬렉션의 모든 객체를 저장한다.

- void clear() : ArrayList를 완전히 비운다.

- Object clone() : ArrayList를 복제한다.

- boolean contains(Object o) : 지정된 객체(o)가 ArrayList에 포함되어 있는지 확인.

- void ensureCapacity(int minCapacity) : ArrayList의 용량이 최소한 minCapacity가 되도록 한다.

- Object get(int index) : 지정된 위치(index)에 저장된 객체를 반환한다.

- int indexOf(Object o) : 지정된 객체가 저장된 위치를 찾아 반환한다.

- boolean isEmpty() : ArrayList가 비어 있는지 확인한다.

- Iterator iterator() : ArrayList의 Iterator 객체를 반환

- int lastindexOf(Object o) : 객체(o)가 저장된 위치를 끝부터 역방향으로 검색해서 반환

- ListIterator listIterator() : ArrayList의 listIterator를 반환

- ListIterator listIterator(int index) : ArrayList의 지정된 위치부터 시작하는 ListIterator를 반환

- Object remove(int index) : 지정된 위치(index)에 있는 객체를 제거

- boolean remove(Object o) : 지정한 객체를 제거한다.(성공하면 true, 실패하면 false)

- boolean removeAll(Collection c) : 지정한 컬렉션에 저장된 것과 동일한 객체들을 ArrayList에서 제거한다.

- boolean retainAll(Collection c) : ArrayList에 저장된 객체 중에서 주어진 컬렉션과 공통된 것들만을 남기고 나머지는 삭제한다.

- Object set(int index, Object element) : 주어진 객체(element)를 지정된 위치(index)에 저장한다.

- int size() : ArrayList에 저장된 객체의 개수를 반환한다.

- void sort(Comparator c) : 지정된 정렬기준(c)으로 ArrayList를 정렬

- List subList(int fromindex, int toindex) : fromindex부터 toindex사이에 저장된 객체를 반환한다.

- Object[] toArray() : ArrayList에 저장된 모든 객체들을 객체배열로 반환한다.

- Object[] toArray(Object[] a) : ArrayList에 저장된 모든 객체들을 객체배열 a에 담아 반환한다.

- void trimToSize() : 용량을 크기에 맞게 줄인다.(빈공간을 없앤다.)

 

실습 1. 기본적인 ArrayList 메서드 이용하여 객체를 다루는 방법.

 

 

package Collection_Framework;

import java.util.*;

public class ArrayList1 {

 

public static void main(String[] args) {

ArrayList list1 = new ArrayList(10);

list1.add(new Integer(5));

list1.add(new Integer(4));

list1.add(new Integer(2));

list1.add(new Integer(0));

list1.add(new Integer(1));

list1.add(new Integer(3));

 

ArrayList list2 = new ArrayList(list1.subList(1, 4));

print(list1,list2);

 

Collections.sort(list1);

Collections.sort(list2);

print(list1,list2);

 

System.out.println("list1.containsAll(list2):" +list1.containsAll(list2));

list2.add("B");

list2.add("C");

list2.add(3,"A");

print(list1,list2);

 

list2.set(3, "AA");

print(list1, list2);

 

System.out.println("list1.retainAll(list2):"+list1.retainAll(list2));

print(list1,list2);

 

for(int i = list2.size()-1; i>=0;i--) {

 

if(list1.contains(list2.get(i)))

list2.remove(i);

}

 

print(list1,list2);

}

 

static void print(ArrayList list1, ArrayList list2) {

 

System.out.println("list1:" +list1);

System.out.println("list2:" +list2);

System.out.println();

}

}

 

 

 

 

 

출력결과 :

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

list1.containsAll(list2):true
list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, A, B, C]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, AA, B, C]

list1.retainAll(list2):true
list1:[0, 2, 4]
list2:[0, 2, 4, AA, B, C]

list1:[0, 2, 4]
list2:[AA, B, C]


 

실습 2. 긴 문자열 데이터를 원하는 길이로 잘라서 ArrayList에 담은 다음 출력하는 예제.

 

package Collection_Framework;

import java.util.*;

public class ArrayList2 {

 

public static void main(String[] args) {

final int LIMIT = 10;

String source = "0123456789abcdefghijABCDEFGHIJ!@#$%^&*()ZZZ";

int length = source.length();

 

List list = new ArrayList(length/LIMIT +10);

 

for (int i =0; i<length; i+=LIMIT) {

if(i+LIMIT < length)

list.add(source.substring(i, i+LIMIT));

else

list.add(source.substring(i));

}

 

for (int i =0; i<list.size();i++) {

System.out.println(list.get(i));

}

}

 

}

 

 

출력결과 :

0123456789
abcdefghij
ABCDEFGHIJ
!@#$%^&*()
ZZZ

 

실습 3. Vector의 용량과 크기에 관한 예제.

 

 

package Collection_Framework;

import java.util.*;

public class ArrayList3 {

 

public static void main(String[] args) {

Vector v = new Vector(5);

v.add("1");

v.add("2");

v.add("3");

print(v);

 

v.trimToSize();

System.out.println("=== After trimToSize() ===");

print(v);

 

v.ensureCapacity(6);

System.out.println("=== After ensureCapacity(6) ===");

print(v);

 

v.setSize(7);

System.out.println("=== After setSize(7) ===");

print(v);

 

v.clear();

System.out.println("=== After clear() ===");

print(v);

}

 

public static void print(Vector v){

System.out.println(v);

System.out.println("size:"+ v.size());

System.out.println("capacity:"+v.capacity());

}

}

 

 

출력 결과:

[1, 2, 3]
size:3
capacity:5
=== After trimToSize() ===
[1, 2, 3]
size:3
capacity:3
=== After ensureCapacity(6) ===
[1, 2, 3]
size:3
capacity:6
=== After setSize(7) ===
[1, 2, 3, null, null, null, null]
size:7
capacity:12
=== After clear() ===
[]
size:0
capacity:12

 

 

반응형

'Study > Java' 카테고리의 다른 글

열거형 enums  (0) 2018.03.19
Collection Framwork 1.3 LinkedList  (0) 2018.03.05
java.time 패키지를 이용하여 달력 만들기  (0) 2018.03.05
Collection Framework 1.7 Comparator, Comparable  (0) 2018.02.26
Collection Framework 1.6 Arrays  (2) 2018.02.26
반응형

package hello;
import java.time.*;
public class time_package {

 public static void main(String[] args) {

  LocalDateTime dateTime = LocalDateTime.of(2015,12,31,12,34,56);
  System.out.print(dateTime);
 }

}

 

출력결과 : 2015-12-31T12:34:56

 

 

package hello;
import java.util.*;

public class calendar {

 public static void main(String[] args) {
  Calendar cal = Calendar.getInstance();
  
  int year = cal.get(Calendar.YEAR);
  int month = cal.get(Calendar.MONTH) +1;
  //System.out.println("Current time is :" + cal.getTime());
  
  System.out.println("           "+year + "년"+ month + "월");
  System.out.println(" SUN MON THU WEN THR FRI SAT");
  Calendar sDay = Calendar.getInstance();
  Calendar eDay = Calendar.getInstance();
  
  sDay.set(year, month-1,1);
  eDay.set(year, month,1);
  eDay.add(Calendar.DATE, -1);
  
  int START_DAY_OF_WEEK = 0;
  int END_DAY = 0;
  
  START_DAY_OF_WEEK = sDay.get(Calendar.DAY_OF_WEEK);
  END_DAY = eDay.get(Calendar.DATE);
  for (int i = 1; i< START_DAY_OF_WEEK; i++) {
   System.out.print("    ");
  }
  for (int i =1, n = START_DAY_OF_WEEK; i<=END_DAY; i++, n++) {
   System.out.print((i<10)?"   " + i :"  "+ i);
   if(n%7 ==0) System.out.println();
  }
 }
}

 

출력결과 :

 

반응형
반응형

1.7 Comparator, Comparable

 

Arrays.sort() 호출시 배열을 정렬하나, 사실은 Character 클래스의 Comparable의 구현에 의해 정렬됨.

 

Comparator, Comparable은 모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의함.

 

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

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

 

package Collection_Framework;
import java.util.*;
public class comparator1 {
 public static void main(String []arge) {
  String[] strArr = {"cat","dog", "lion","tiger"};
  
  Arrays.sort(strArr);
  System.out.println("strArr=" + Arrays.toString(strArr));
  
  Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER);
  System.out.println("strArr=" + Arrays.toString(strArr));
  
  Arrays.sort(strArr, new Descending());
  System.out.println("strArr=" + Arrays.toString(strArr));
  
 }
}

class Descending implements Comparator{
 public int compare(Object o1, Object o2) {
  if(o1 instanceof Comparable && o2 instanceof Comparable) {
   Comparable c1 = (Comparable)o1;
   Comparable c2 = (Comparable)o2;
   return c1.compareTo(c2)*-1;
  }
  return -1;
 }
}

 

 

출력결과 :

strArr=[cat, dog, lion, tiger]
strArr=[cat, dog, lion, tiger]
strArr=[tiger, lion, dog, cat]

 

 

* String의 Comparable 구현은 문자열이 사전순으로 정렬됨. 오름차순 정력은 공백, 숫자, 대문자, 소문자 순으로 정렬됨.

즉, 유니코드 순서가 작은값에서 큰값으로 정렬됨.

 

* 대소문자를 구분하지 않고 비교하는 Comparator를 상수의 형태로 제공.

public static final Comparator CASE_INSENSITIE_ORDER

 

> Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); 사용시 대소문자 구분없이 정렬가능.

 

* 내림차순 정렬

String에 구현된 compareTo()의 결과에 -1을 곱하기만 하면 된다. 비교하는 객체의 위치를 바꿔서 c2.compareTo(c1)과 같이 해도 된다.

 

매개변수가 Object타입이기 때문에, compareTo()를 바로 호출 할수 없으므로 Comparable로 형변환 해야 한다.

 

class Descending() 참고.

 

 

반응형
반응형

1.6 Arrays

 

* Arrays 클래스 : 배열을 다루는데 유용한 메서드가 정의되어 있음. 아래 정의된 toString(), 모든 기본형 배열, 참조형 배열 별로 하나씩 정의됨.

 

static String toString(boolean[ ]a)

static String toString(byte[ ] a)

static String toString(char[ ] a)

static String toString(short[ ] a)

static String toString(int[ ] a)

static String toString(long[ ] a)

static String toString(float[ ] a)

static String toString(double[ ] a)

static String toString(object[ ] a)

 

------------------------------------------------------------------------------------------------------------------------------------------------------------

 

* 배열의 복사

- copyOf() : 배열 전체 복사

- copyOfRange() : 배열의 일부를 복사

하여 새로운 배열을 만들어 반환.

 

int[ ] arr = {0,1,2,3,4,};

int[ ] arr2 = Arrays.copyOf(arr, arr.length);

int[ ] arr3 = Arrays.copyOf(arr, 3);

int[ ] arr4 = Arrays.copyOf(arr, 7);

 

int[ ] arr5 = Arrays.copyOfRange(arr,2,4);

int[ ] arr6 = Arrays.copyOfRange(arr,0,7);

 

 

// 배열의 복사

package Collection_Framework;
import java.util.*;
public class Arrays1 {
 public static void main(String[]arge) {

  int[ ] arr = {0,1,2,3,4,};
  int[ ] arr2 = Arrays.copyOf(arr, arr.length);
  int[ ] arr3 = Arrays.copyOf(arr, 3);
  int[ ] arr4 = Arrays.copyOf(arr, 7);

  int[ ] arr5 = Arrays.copyOfRange(arr,2,4);
  int[ ] arr6 = Arrays.copyOfRange(arr,0,7);

  System.out.println(Arrays.toString(arr));
  System.out.println(Arrays.toString(arr2));
  System.out.println(Arrays.toString(arr3));
  System.out.println(Arrays.toString(arr4));
  System.out.println(Arrays.toString(arr5));
  System.out.println(Arrays.toString(arr6));
 }
}

 

출력결과 :

[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2]
[0, 1, 2, 3, 4, 0, 0]
[2, 3]
[0, 1, 2, 3, 4, 0, 0]


 

* 배열 채우기

- fil() : 배열의 모든 요소를 지정된 값으로 채운다.

- setAll() : 배열을 채우는데 사용할 함수형 인터페이스를 매겨변수로 받는다.

 

package Collection_Framework;
import java.util.*;
public class Arrays2 {

 public static void main(String[] args) {

  int[]arr = new int[5];
  Arrays.fill(arr, 9);
  Arrays.setAll(arr, () -> (int)(Math.random()*5)+1); // 람다식을 지정해야 함.

 System.out.println(Arrays.toString(arr));
 }

}

 

출력 결과 :

[9, 9, 9, 9, 9]

* 배열의 정렬과 검색

- sort() : 배열을 정렬할 때 사용

- binarySearch() : 저장된 요소를 검색 할 때 사용, 배열에서 지정된 값이 저장된 위치(index)를 찾아서 반환하는데, 반드시 배열이 정렬된 상태이어야 올바른 결과를 얻음.

 

package Collection_Framework;
import java.util.*;
public class Arrays3 {

 public static void main(String[] args) {
  int[] arr = {3,2,0,1,4};
  int idx = Arrays.binarySearch(arr, 2);
  System.out.println(Arrays.toString(arr));
 
  Arrays.sort(arr);
  System.out.println(Arrays.toString(arr));
  int idx2 = Arrays.binarySearch(arr,2);
 
  
 }

}

 

출력 결과 :

[3, 2, 0, 1, 4]
[0, 1, 2, 3, 4] 
<- 올바른 결과.
 

 

 

* 문자열의 비교와 출력

- equals() : 두 배열에 저장된 모든 요소를 비교해서 같으면 true, 다르면 false를 반환. 일차원 배열에서만 사용가능

- toString() : 일차원 배열에서 문자열로 편하게 출력함.

 

다차원 배열에서

- deepToString(), deepToEquals() 사용

 

package Collection_Framework;
import java.util.*;
public class Arrays4 {

 public static void main(String[] args) {
  int[] arr = {0,1,2,3,4};
  int[] [] arr2D = {{11,12},{21,22}};
  
  System.out.println(Arrays.toString(arr));
  System.out.println(Arrays.deepToString(arr2D));
  
  String[] [] str2D = new String [] [] {{"aaa","bbb"},{"AAA","BBB"}};
  String[] [] str2D2 = new String [] [] {{"aaa","bbb"},{"AAA","BBB"}};
  System.out.println(Arrays.equals(str2D, str2D2));
  System.out.println(Arrays.deepEquals(str2D, str2D2));
 }

}

출력결과 :

[0, 1, 2, 3, 4]
[[11, 12], [21, 22]]
false
true

* 배열을 List로 변환 // 이해가 잘 안감...

- asList(Object... a)

 

package Collection_Framework;
import java.util.*;
public class Arrays5 {

 public static void main(String[] args) {
  List list = Arrays.asList(new Integer[] {1,2,3,4,5,});
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  list.add(6);
  
 }

}

 

 

* parallel로 시작하는 메서드(), spliterator(), tream()등등

 

 

 

반응형
반응형

1.5 lterator, Listlterator, Enumeration

 

lterator, Listlterator, Enumeration 모두 컬렉션에 저장된 요소를 접근하는데 사용하는 인터페이스 이다.

 

Enumeration은 Iterator의 구버전이다. ListIterator은 Iterator의 기능을 향상 시킨 것이다.

 

* Iterator  

 

- interface 메서드
 public interface Iterator {
  boolean hasNext(); // 읽어 올 요소가 남아 있는지 확인 한다. 있으면 true, 없으면 false.
  Object next(); // 다음 요소를 읽어 온다. next()를 호출 하기 전에 hasNext()를 호출해서 읽어 올 요소가 있는지 확인하는 것이 안전.
  void remove(); // next()로 읽어 온 요소를 삭제한다. next()를 호출한 다음에 remove()를 호출해야 한다.(선택적)
 }
  public interface Collection{
  public Iterator iterator();
 }

-------------------------------------------------------------------------------------------------------------------------------------------------

 

package Collection_Framework;
import java.util.*;
public class Iterator1 {

 public static void main(String[] args) {

  ArrayList<String> list = new ArrayList<String>();
  
  list.add("1");
  list.add("2");
  list.add("3");
  list.add("4");
  list.add("5"); 
  
  Iterator<String> iter = list.iterator();
  
  while(iter.hasNext()) {
   Object obj = iter.next();
   System.out.println(obj);
  }
 }
}

 

출력 결과 :

1
2
3
4
5

 

===========================================================================================

* ListIterator

 : 양방향으로 이동하기 때문에 각 요소간의 이동이 자유롭다.

다만 이동하기 전에 반드시 hasNext() 나 hasPrevious()를 호출하여 이동할 수 있는지 확인해야 한다.

 

- interface 메서드

void add(Object o) // 컬렉션에 새로운 객체 o를 추가한다.

boolean hasNext() // 읽어 올 다음 요소가 남아있는지 확인한다. 있으면 true, 없으면 false를 반환

boolean hasPrevious() // 읽어 올 이전 요소가 남아 있는지 확인한다. 있으면 true, 없으면 false를 반환

Object next() //다음 요소를 읽어 온다. next()를 호출하기 전에 hasNext()를 호출해서 읽어 올 요소가 있는지 확인하는 것이 안전한다.

Object previous() // 이전 요소를 읽어온다. previous()를 초훌하기 전에 hasPrevious()를 호출해서 읽어 올 요소가 있는지 확인하는 것이 안전한다.

int nextindex() // 다음 요소의 index를 반환한다.

int previousindex() // 이전 요소의 index를 반환한다.

void remove() // next() 또는 previous()로 읽어 온 요소를 삭제한다. 반드시 next()나 previous()를 먼저 호출한 다음에 이 메서드를 호출해야 한다.

void set(Object o) // next()또는 previous()로 읽어 온 요소를 지정된 객체(o)로 변경한다. 반드시 next()나 previous()를 먼저 호출한 다음에 이 메서드를 호출해야한다.

 

예제.

package Collection_Framework;
import java.util.*;
public class listlterator1 {
 public static void main(String[]args) {
  ArrayList<String> list = new ArrayList<String>();
  list.add("1");
  list.add("2");
  list.add("3");
  list.add("4");
  list.add("5"); 
  
  ListIterator<String> iter = list.listIterator();
  
  while (iter.hasNext()) {
   System.out.print(iter.next());
  }
  System.out.println();
  
  while(iter.hasPrevious()) {
   System.out.print(iter.previous());
  }
  System.out.println();
 }
}

 

 

출력 결과 :

12345
54321


 

* Enumeration

- interface 메서드

boolean hasMoreElements() // 읽어 올 요소가 남아 있는지 확인한다. 있으면 true, 없으면 false 반환. Iterator의 hasNext()와 같음

Object nextElement() // 다음 요소를 읽어 온다. nextElement()를 호출하기 전에 hasMoreElements()를 호출해서 읽어올 요소가 남아 있는지 확인하는 것이 안전한다. Iterator의 next()와 같다.

반응형

+ Recent posts