본문 바로가기
수업 일지/JAVA

13일차 - [JAVA] Map/증감 연산자/추상 클래스

by 쿠쿠씨 2022. 1. 17.
반응형

Map 컬렉션 - HashMap

 

ArrayList는 순차적으로(인덱스로 접근) 데이터를 관리하는 자료구조이고, 배열과 유사한 구조이다.

HashMap은 순차적인 구조가 아니고, Key 값을 이용하여 데이터에 접근하여 저장/읽기한다.

 → 검색이 많은 알고리즘에 유용하다.

위 2개 클래스는 제네릭 타입을 <> 기호 안에 표시한다.

HashMap은 K: Key, V: Value 한 쌍이다. ex) HashMap<Key,Value>

제네릭 타입은 int, long, double 기본형 타입 대신에 래퍼(wrapper) 클래스로 표기한다.

 

14라인 HashMap으로 map 변수를 선언한다. 저장되는 key 값은 String, value 값은 Integer로 한다.

18~22라인 put(key, value) 메소드로 키와 값을 저장한다.

24라인 map 변수를 출력하면 데이터가 출력된다(toString 재정의)

27라인 get(key) 메소드로 주어진 키가 있는 값을 반환한다.

28라인 키가 존재하지 않는다면 null을 반환한다.

33라인 put() 메소드로 기존에 저장된 키와 동일한 키로 값을 저장하면 새로운 값으로 대체된다.

37라인 remove(key, value) 메소드로 값을 제거할 수 있다. 키와 값이 모두 일치할 때 제거된다.

44라인 remove(key) 메소드로 키값 만으로도 값을 제거할 수 있다.

45라인 remove() 메소드는 삭제된 항목의 값(value)을 반환한다.

 

HashMap 예제1: 메뉴 투표하기

 

11라인 HashMap으로 키는 String 형식, 값은 Integer 형식인 map 변수를 선언한다.

17~21라인 put() 메소드로 키와 값을 저장한다.

23라인 while문으로 투표를 반복한다.

29라인 end 문자열을 입력하면 break로 while문을 종료한다.

30라인 ! map.contansKey(menu) 메소드가 true라는 것은 키값으로 없는 문자열이 입력된 경우이다.

 map.contansKey(key) : key값이 map에 존재하면 true, 존재하지 않으면 false를 반환한다.

32라인 map에 새로운 키와 값을 저장한다.

33라인 foods 문자열에 새로운 문자열을 저장한다.

35라인 map에 존재하는 키값이 입력된 경우이다.

37라인 temp에 입력받은 키의 value 값을 저장한다.

38라인 put() 메소드로 값을 1 증가시켜 저장한다.

 → ++temp만 가능하다. temp++일 경우 메소드가 실행된 후 temp가 1 증가하여 값은 계속 0으로 남아 있다. ★

43라인 Collerctions.max(map.values()) 메소드는 vaule중에 가장 큰 값을 반환한다. 여기서는 최대 득표수를 반환한다.

44라인 Collerctions.max(map.keySet()) 메소드는 key값 정렬 시 최대값, 즉 가나다순으로 가장 마지막 키값이 반환된다.

45라인 Collections의 종류에는 List, Set, Map이 있다. 집합, 이터레이터(Iterator)

 

결과

 

증감 연산자

 

++i와 i++의 연산에는 차이가 있다.

++i는 다른 연산을 수행하기 전에 i의 값을 1 증가시킨다.

map.put(menu,++temp);

 temp +1 증가 → temp 값을 put 메소드로 저장

 ++temp;  →  map.put(menu,temp);

 

i++는 다른 연산을 수행한 후에 i의 값을 1 증가시킨다.

map.put(menu,temp++);

 temp 값을 put 메소드로 저장 → temp +1 증가

 map.put(menu,temp);  →  temp++;

 

HashMap 예제2: 영한사전

 

문제: 영한 단어사전을 Map을 이용하여 구현합니다.*실행화면*
---------------------
선택 기능  1. 단어저장 2. 단어검색 3.단어장보기 4.프로그램 끝내기

선택 ✏️-> 1
English -> milk
Korean -> 우유

선택 ✏️-> 2
Korean -> 우유
단어장에 검색했습니다. -> milk

선택 ✏️-> 1
English -> apple
Korean -> 사과

선택 ✏️-> 3
{apple: 사과, milk: 우유}

 

9라인 TreeMap으로 String타입 키와 String타입 값을 갖는 변수 word를 선언한다. 키값으로 오름차순 정렬

14라인 switch문에서 while문 종료 조건을 넣기 위해 변수 run을 true로 선언한다.

19~23라인 영어 입력 값을 변수 eng에 한글 입력 값을 변수 kor에 저장한다.

24라인 키 값이 이미 존재하다면 temp에 value 값을 저장하고 새로 입력 받은 value값을 추가 시킨다.

29라인 키 값이 존재하지 않을 경우 입력 받은 키와 값을 저장한다.

32~34라인 영어 입력 값을 변수 eng에 저장한다.

35라인 get() 메소드로 eng 키 값에 저장된 value 값을 반환한다.

38라인 3을 입력 받으면 저장된 word를 출력한다.

41라인 4를 입력 받으면 변수 run을 false로 하여 while문을 종료한다.

44라인 1~4 외의 값을 입력 받으면 다시 입력하라는 메시지를 출력한다.

 

결과

 

추상 클래스

 

추상 클래스를 선언할 때는 클래스 선언에 abstract 키워드를 붙인다.

abstract 키워드를 붙이면 new 연산자로 객체를 만들 수 없고, 상속으로 자식 클래스만 만들 수 있다.

추상 클래스도 필드, 생성자, 메소드를 선언할 수 있다.

추상 메소드는 중괄호 { }가 없으며 abstract 키워드가 있다.

추상 메소드 형식: 접근제한자 abstract 리턴타입 메소드이름(인자);

자식 클래스는 반드시 추상 메소드를 재정의해서 실행문을 작성해야한다.

 

추상 클래스 예제

 

AShape 클래스

7라인 추상 클래스 선언 시 abstract 키워드를 작성한다

12라인 추상 메소드 getArea()를 선언한다.

 

 

 

ATriangle 클래스

3라인 ATriangle 클래스는 추상 클래스 AShape의 상속을 받는다.

5,6라인 필드 height, width를 선언한다.

9라인 추상 메소드 getArea()를 재정의한다.

13라인 ATriangle 클래스에만 있는 메소드 triangle()을 선언한다.

 

ASquare 클래스

3라인 ASquare 클래스는 추상 클래스 AShape의 상속을 받는다.

5라인 필드 width를 선언한다.

8라인 ASquare 클래스에만 있는 square() 메소드를 선언한다.

20라인 추상 메소드 getArea()를 재정의한다.

 

AbstractTest

7라인 추상 클래스 AShape는 new 객체로 생성할 수 없다.

8라인 ATriangle 객체를 생성하고 참조 타입이 AShape인 참조 변수 tri에 참조시킨다.

9라인 setter 메소드로 ShapeName 필드에 값을 저장한다.

11라인 tri를 ATriangle 타입으로 강제 캐스팅하고 ATriangle 타입을 참조하는 변수 atri에 저장한다.

12,13라인 setter 메소드로 width에 20, height에 40을 저장한다.

15,16라인 재정의한 getArea() 메소드로 넓이 값을 출력한다.

19라atri 변수는 ATriangle 타입이므로 triangle() 메소드를 실행할 수 있다.

 → tri 변수는 AShape 타입이므로  triangle() 메소드를 실행할 수 없다.(triangle()은 ATriangle 클래스에서 선언)

21라인 ASquare 객체를 생성하고 참조 타입이 AShape인 참조 변수 square에 참조시킨다.

22라인 setter 메소드로 ShapeName 필드에 값을 저장한다.

23라인 square을 ASquare 타입으로 강제 캐스팅하고 ASqure 타입을 참조하는 변수 asq에 저장한다.

25라인 asq 변수는 ASquare 타입이므로 square() 메소드를 실행할 수 있다.

 → square 변수는 AShape 타입이므로 square() 메소드를 실행할 수 없다.(square()는 ASquare 클래스에서 선언)

27라인 setter 메소드로 width에 30을 저장한다.

28,29라인 재정의한 getArea() 메소드로 넓이 값을 출력한다.

 

* AShape 타입은 getArea(), getShapeName(), setShapeName() 메소드만 실행할 수 있다.

 

 

AbstractTest2

6라인 배열에 서로 다른 객체를 참조하기위해 길이가 3인 shapes를 선언한다

8~10라인 shapes 0번 인덱스에 ATriangle 객체, 1번 인덱스에 ASquare 객체, 2번 인덱스에 ATriangle 객체를 참조시킨다.

12라인 ASquare 타입인 shapes[1]을 ATriangle로 캐스팅하면 오류가 발생한다.

 → 만들어진 객체(자식)와 다른 (자식 객체)타입으로 캐스팅할 수 없다.

13라인 shapes[2]는 ATriangle 타입이므로 정상 실행되어 변수 ty가 선언된다. 

14라인 for문으로 모든 인덱스의 타입을 검사한다.

17라인 instanceof 연산자로 shapes[i]가 참조하는 객체가 ATriangle 타입인지 검사한다.

19라인 ATriangle 타입이 맞다면 변수 at에 shapes[i]를 참조시킨다.

20라인 setter 메소드로 width에 100을 height에 50을 저장한다.

21라인 triangle() 메소드가 실행하는지(ATriangle 타입인지) 확인한다.

22라인  instanceof 연산자로 shapes[i]가 참조하는 객체가 ASquare 타입인지 검사한다.

23라인 ASquare 타입이 맞다면 변수 as에 shapes[i]를 참조시킨다.

24라인 setter 메소드로 width에 90을 저장한다.

25라인 square() 메소드가 실행하는지(ASquare 타입인지) 확인한다.

27,28라인 getArea() 메소드로 넓이 값들을 출력한다.

 

* instanceof 연산자 : A(객체) instanceof B(참조 타입)

 → A가 B타입으로 생성되었다면 true, 그렇지 않으면 false를 반환한다.

반응형

댓글