- HashMap과 ArrayList 활용
문제
PokeBag 클래스
(1) private final 자료형 pokemons = new 자료형();
HashMap 강의에서 만들었던 PokeDex에서는 한 마리의 마릴 인스턴스만 담을 수 있었죠? PokeBag에서는 마릴이라는 key 하나에 여러 마리의 마릴 인스턴스를 담을 수 있습니다.
이 상황에 적합한 자료형을 생각해 봅시다.
(2) public ArrayList<Pokemon> getPokemons(String name)
name 이름을 갖고 있는 포켓몬을 모두 가져오는 메소드입니다.
(3) public void add(Pokemon pokemon)
과정 (1)에서 구현한 pokemons에 Pokemon을 넣는 메소드입니다.
(4) public Pokemon getStrongest(String name)
name 이름의 포켓몬 중 가장 강한(cp가 가장 큰) 포켓몬을 가져오는 메소드입니다.
(5) public Pokemon getStrongest()
내가 가진 모든 포켓몬 중 가장 강한 포켓몬을 가져오는 메소드입니다. 내부적으로 (4)번 메소드를 호출하도록 구현해보세요.
템플릿
(1) Main.java
public class Main {
public static void main(String[] args) {
PokeBag pokeBag = new PokeBag();
pokeBag.add(new Pokemon("마그마", 1024));
pokeBag.add(new Pokemon("마그마그", 215));
pokeBag.add(new Pokemon("마릴", 816));
pokeBag.add(new Pokemon("마그마그", 136));
pokeBag.add(new Pokemon("라프라스", 1822));
pokeBag.add(new Pokemon("마릴", 215));
pokeBag.add(new Pokemon("마릴", 185));
pokeBag.add(new Pokemon("마릴", 110));
pokeBag.add(new Pokemon("니드킹", 1709));
pokeBag.add(new Pokemon("마릴", 39));
pokeBag.add(new Pokemon("마자용", 12));
System.out.println(pokeBag.getStrongest("마릴"));
System.out.println(pokeBag.getStrongest());
System.out.println(pokeBag.getStrongest("피카츄"));
}
}
(2) Pokemon.java
public class Pokemon {
public final String name;
public final int cp;
public Pokemon(String name, int cp) {
this.name = name;
this.cp = cp;
}
@Override
public String toString() {
return name + "(" + cp + ")";
}
}
(3) PokeBag.java <- 수정
import java.util.ArrayList;
public class PokeBag {
private final 자료형 pokemons = new 자료형();
public ArrayList<Pokemon> getPokemons(String name) {
}
public void add(Pokemon pokemon) {
}
public Pokemon getStrongest(String name) {
}
public Pokemon getStrongest() {
}
}
출력값
마릴(816)
라프라스(1822)
null
풀이 및 답
import java.util.ArrayList;
import java.util.HashMap;
public class PokeBag {
// PokeBag은 포켓몬들을 담을 수 있는 가방(잡은 포켓몬들을 보관하는 장소)
// PokeBag에 내가 추가하려는 포켓몬의 종류가 있으면, 이들이 저장되어있는 ArrayList에 추가 가능
// 만약 내가 추가하려는 포켓몬의 종류가 없다면, 해당 포켓몬의 종류와 이들을 담을 ArrayList를 생성해준 후 추가
// 포켓몬의 종류(String name)을 key로,
// 이들을 담을 배열(ArrayList<Pokemon>)을 value로 갖고 있는 HaspMap 자료형 사용
// 즉, Key = String, Value = ArrayList<Pokemon>인 pokemons HashMap 생성
private final HashMap<String, ArrayList<Pokemon>> pokemons = new HashMap<>();
public ArrayList<Pokemon> getPokemons(String name) {
// name이라는 이름의 포켓몬을 모두 가져오는 메소드
return pokemons.get(name);
}
public void add(Pokemon pokemon) {
// pokemons에 Pokemon 인스턴스를 넣는 구조
// 추가할 새 포켓몬의 종류(이름)을 저장
String name = pokemon.name;
// 1. 이미 같은 이름의 포켓몬이 존재하는 경우
getPokemons(name).add(pokemon);
// 2. 완전히 새로운 포켓몬인 경우
// 새 포켓몬의 종류에 해당하는 ArrayList에 포켓몬을 추가.
// 힌트: getPokemons 메소드를 사용. 리턴값이 null이면 새롭게 key-value값을 추가.
if(getPokemons(name)==null) {
pokemons.put(name, new ArrayList<Pokemon>());
}
}
public Pokemon getStrongest(String name) {
// name이라는 이름의 포켓몬 중 가장 강한(cp가 가장 큰) 포켓몬을 가져오는 메소드
// name 이름의 포켓몬 목록.
ArrayList<Pokemon> pokemonList = getPokemons(name);
// name 이름의 포켓몬 목록이 비어있으면, null 리턴.(존재하지 않는 이름을 넣으면 null 리턴)
if (pokemonList == null) {
return null;
}
// return할 포켓몬(가장 센 포켓몬)을 담을 변수.
Pokemon strongest = null;
// 포켓몬 리스트 안에 있는, 모든 포캣몬의 cp를 비교.
// strongest를 가장 센 포켓몬으로 교체
for (Pokemon pokemon : getPokemons(name)) {
// for (T element : ArrayList<T>)와 같은 방식
if (strongest == null || pokemon.cp > strongest.cp) {
strongest = pokemon;
}
}
return strongest;
}
public Pokemon getStrongest() {
// 가진 모든 포켓몬 중 가장 강한 포켓몬을 가져오는 메소드
// return할 포켓몬(가장 센 포켓몬)을 담을 변수.
Pokemon strongest = null;
// HashMap 전체를 탐색 (keySet을 통해 얻은 key로 탐색)
for (String key : pokemons.keySet()) {
// key에 해당하는 가장 센 포켓몬을 가져오기
Pokemon p = getStrongest(key);
// strongest를 가장 센 포켓몬으로 교체
if (strongest == null || p.cp > strongest.cp) {
strongest = p;
}
}
return strongest;
}
}
- HashMap의 가장 중요한 연산은 .get(Key k) (Value 리턴 타입 - k에 해당하는 Value 리턴) 와 .put(Key k, Value v) ((k, v)를 저장함)