자바에서 객체를 생성해 데이터를 저장할 때 Map 을 사용할 수도 있고, class를 사용할 수도 있다.
이번 블로그에서는 객체를 생성해 저장할때 차이를 비교해본다. 객체에 이름과 나이를 저장 후 나이에서 하나씩 빼는 코드를 만들어보았다.
1. Map 사용
public class StreamEx01 {
public static void main(String[] args) {
Map<String, Object> data1 = new HashMap<>();
data1.put("name", "홍길동");
data1.put("age", 20);
Map<String, Object> data2 = new HashMap<>();
data2.put("name", "장보고");
data2.put("age", 15);
Map<String, Object> data3 = new HashMap<>();
data3.put("name", "이순신");
data3.put("age", 30);
List<Map<String, Object>> arr = Arrays.asList(data1, data2, data3);
List<Map<String, Object>> newArr = arr.stream().map(d -> {
int newAge = (Integer) d.get("age") - 1;
d.put("age", newAge);
return d;
}).toList();
newArr.stream().forEach(System.out::println);
}
}
Map<String, Object> data1 = new HashMap<>();
data1.put("name", "홍길동");
data1.put("age", 20);
맵은 키-값 의 구조를 가지고 있다. name 이라는 키에 맞는 값을 넣을 수 있다.
키 값은 보통 String 변수로 설정하고, 입력 값은 정할 수 없기 때문에 추상화된 Object 변수 를 사용한다.
List<Map<String, Object>> arr = Arrays.asList(data1, data2, data3);
List 를 사용할 때 변수가 2개이기 때문에 <<>> 이중 괄호로 값을 입력한다.
List<Map<String, Object>> newArr = arr.stream().map(d -> {
int newAge = (Integer) d.get("age") - 1; // 다운캐스팅
d.put("age", newAge);
return d;
}).toList();
map() 을 사용해 데이터들의 값을 변환한다. Map 에서 출력값은 Object 타입이기 때문에 값을 대입하려면 다운캐스팅을 반드시 해야 한다.
2. class 사용
class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public void changeAge() {
this.age = this.age - 1;
}
}
public class StreamEx02 {
public static void main(String[] args) {
// 객체 3명 만들기
User u1 = new User("홍길동", 20);
User u2 = new User("장보고", 15);
User u3 = new User("이순신", 30);
List<User> list = Arrays.asList(u1, u2, u3);
List<User> newAge = list.stream().map(u -> {
u.changeAge();
return u;
}).toList();
newAge.stream().forEach(u -> System.out.println(u.getAge()));
}
}
이번에는 클래스를 통해 객체를 생성해 데이터를 저장했다.
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
User 클래스를 만들어 변수 설정을 하고 생성자를 만 들어 초기화를 했다.
public void changeAge() {
this.age = this.age - 1;
}
클래스에서는 메서드를 만들어 호출하는 방식으로 사용할 수 있다. changeAge 메서드를 만들고, 이 메서드가 호출될 때마다 나이가 1씩 차감되는 방식이다.
List<User> newAge = list.stream().map(u -> {
u.changeAge();
return u;
}).toList();
Map 에서는 다운캐스팅을 해서 int 값으로 저장했지만, class 는 메서드를 호출하기만 하면 된다.

3. class 를 사용해야 하는 이유
컴파일 에러 확인 불가
Map 은 Object 형을 변수로 갖기 때문에 잘못된 값을 입력받아도 확인할 수 없다. 예를 들어 String 값을 저장해야 하지만 int 로 저장해도 확인할 수 없다.
가독성이 떨어짐
Map을 사용하는 구조는 가독성이 떨어진다. 만약 Map<String, Object>를 본다면, 우리가 받는 Key 값은 무엇이고, Value 값은 무엇이며 어떠한 타입인지를 파악하기가 쉽지않다. Map으로 작성된 코드를 이해하기 위해서는 불필요한 코드 리딩 시간이 필요하고 생산성이 떨어지게 된다.
다운캐스팅을 해야됨
Map은 자료형이 Object 기 때문에 해당 데이터를 사용하려면 다운캐스팅이 불가피하다.
데이터의 불변성을 확보할 수 없음
Map<String, Object> data1 = new HashMap<>();
data1.put("name", "홍길동");
Map<String, Object> data2 = new HashMap<>();
data1.put("name", "장보고");
Map 은 오타의 가능성이 있고, 데이터를 잘못 입력하면 데이터값이 변경될 수 있다.
Share article