[ ArrayList / LinkedList / HashMap와의 차이점 및 클래스가 좋은 이유 ]
ArrayList / LinkedList / HashMap 와의 차이점 ArrayList : 찾고자 하는 값을 인덱스 번호를 통해 다이렉트 엑세스 가능. LinkedList : 가를 찾아야 나를 찾음. 나를 찾아야 다를 찾음. 이어져 있어서 > 영원히 쓰지마 HashMap : 키 이름으로 값을 찾음
문제
< HashMap으로 가공 >
package ex14; import java.util.*; public class StreamEx01 { public static void main(String[] args) { Map<String, Object> data = new HashMap<>(); data.put("name", "홍길동"); data.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(data, 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(d -> { System.out.println(d.get("age")); }); } }
* 연속적으로 타입이 같은 어떤 데이터를 저장하고 싶다 : 무조건 ArrayList 사용
위에서부터 각각 0번지, 1번지, 2번지
* 데이터 자료형으로 쓰고 싶다 > 걍 클래스 써라 ?
클래스로 표현 안하고(String name, int age),
간단하게 표현하려고 하면 모든 언어는 다 Map을 사용
[ Map의 단점 ]
1. 오타를 낼 수 있음. 2. Object 타입으로 받게 되는 경우가 많기에, 호출할 때 다운캐스팅 해줘야 함 : User u = (User) data3.get("user");
< 클래스로 가공>
코드 (이렇게 쓰지 마라. 클래스는 쓰는 의미가 없다)
package ex14; import java.util.ArrayList; import java.util.Arrays; import java.util.List; class User { String name; int age; public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } } public class StreamEx02 { public static void main(String[] args) { //User 3명 만들기 (홍길동 20, 장보고 15, 임꺽정 30) User u1 = new User("홍길동", 20); User u2 = new User("장보고", 15); User u3 = new User("임꺽정", 30); //ArrayList에 User 담기 List<User> arr = Arrays.asList(u1, u2, u3); //steram으로 순회하면서 map으로 가공하기 (나이 -1) List<User> newArr = arr.stream().map(u -> { u.setAge(u.getAge() - 1); //이렇게 쓰면 클래스를 쓰는 의미 X return u; }).toList(); } }
코드 (이렇게 써라)
package ex14; import java.util.ArrayList; import java.util.Arrays; import java.util.List; class User { String name; int age; public User(String name, int age) { this.name = name; this.age = age; } public void changeAge() { this.age = this.age - 1; } //이런!! 메소드를 써서 넣어주는게 바로 클래스의 편안함! public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } } public class StreamEx02 { public static void main(String[] args) { //User 3명 만들기 (홍길동 20, 장보고 15, 임꺽정 30) User u1 = new User("홍길동", 20); User u2 = new User("장보고", 15); User u3 = new User("임꺽정", 30); //ArrayList에 User 담기 List<User> arr = Arrays.asList(u1, u2, u3); //steram으로 순회하면서 map으로 가공하기 (나이 -1) List<User> newArr = arr.stream().map(u -> { u.changeAge(); return u; }).toList(); newArr.stream().forEach(user -> { System.out.println(user.getAge()); }); } }
Collections 클래스
정적(static) 메서드들로 구성되어 있으며, 제네릭 기술을 사용하여서 작성되었다. 컬렉션에 대해 정렬, 섞기, 탐색 등의 작업을 수행할 수 있도록 도와준다.
Comparable 인터페이스
: 객체 자체의 자연적인 순서를 기반으로 비교를 수행하기 위해 사용한다.
즉, String이 sort했을 때, 말하지 않아도 알파벳으로 정렬되는 이유는
Comparable 인터페이스를 구현하고 있기 때문
1. 정렬 (Collections.sort() 메서드)
Collections.sort() 메서드를 사용하여 컬렉션의 요소들을 정렬할 수 있다. List 인터페이스를 구현하는 컬렉션에 대하여 정렬을 수행한다.
[ 문자열 정렬하기 ]
package ex08; import java.util.Arrays; import java.util.Collections; import java.util.List; public class Test16 { public static void main(String[] args) { String[] sample = {"i", "walk", "the", "line"}; List<String> list = Arrays.asList(sample); Collections.sort(list); System.out.println(list); } }
Arrays.sort(numbers);
배열도 sort[ 사용자 클래스의 객체 정렬하기 ] - 이해못함
사용자가 만든 클래스라면 Comparable 인터페이스가 구현되지 않았을 것 compareTo 메소드는 매개 변수 객체를 현재의 객체와 비교하여 음수(작으면), 0(같으면), 양수(크면)를 반환한다.
[ 코드 ]
package ex08; import java.util.Arrays; import java.util.Collections; import java.util.List; class Student implements Comparable<Student> { int number; String name; public Student(int number, String name) { this.number = number; this.name = name; } @Override public String toString() { return name; } public int compareTo(Student s) { return s.number - number; } } public class Test17 { public static void main(String[] args) { Student array[] = { new Student(2, "김철수"), new Student(3, "이철수"), new Student(1, "박철수"), }; List<Student> list = Arrays.asList(array); Collections.sort(list); System.out.println(list); } }
number값을 어떻게 알아?
2. 섞기 (shuffle() 메서드)
shuffle() 메서드는 주어진 리스트를 무작위로 섞는 기능 ex) 게임 등에서 카드를 랜덤하게 섞는 경우
[ 코드 ]
package ex08; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Test18 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 0; i <= 10; i++) { list.add(i); } Collections.shuffle(list); System.out.println(list); } }
3. 탐색 (binarySearch() 메서드)
리스트 안에서 원하는 원소를 찾는 것 리스트 정렬 O > 이진 탐색 (중간에 있는 원소와 먼저 비교) 리스트 정렬 X > 선형 탐색 (처음부터 모든 원소 방문)
[ binarySearch() ]
이진 탐색 알고리즘을 사용하여 정렬된 리스트에서 특정 요소의 인덱스를 찾는다. (이때 리스트는 사전에 오름차순으로 정렬되어 있어야 함) 존재 O > 해당 요소의 인덱스를 반환 존재 X > 음수 값 반환
[ binarySearch() 예시 ] - 50을 이진 탐색으로 서치
package ex08; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Test19 { public static void main(String[] args) { int key = 50; List<Integer> list = new ArrayList<>(); for (int i = 0; i < 100; i++) { list.add(i); } int index = Collections.binarySearch(list, key); System.out.println("탐색의 반환값 = " + index); } }
값이 존재하지 않으면 음수 값이 나오는 것 확인!
Map 예시 - 영어 사전 구현
quit
을 입력하면 프로그램 종료package ex08; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Test20 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Map<String, String> mapDic = new HashMap<>(); mapDic.put("map", "지도"); mapDic.put("school", "학교"); mapDic.put("java", "자바"); while (true) { System.out.print("영어 단어를 입력하세요 : "); String key = sc.nextLine(); if (key.equals("quit")) { break; } System.out.print("단어의 의미는 " + mapDic.get(key)); System.out.println(); System.out.println(); } } }
다이아몬드 연산자
이 기능을 사용하면 변수를 선언할 때 제네릭 타입을 생략할 수 있고, 컴파일러는 제네릭 타입을 추론하여 사용한다. ArrayList<String> list = new ArrayList<>(); // 다이아몬드 연산자로 생략 가능 ArrayList<String> list = new ArrayList<String>(); // 원본 (명시적 지정) HashSet<String> set = new HashSet<>(); HashSet<String> set = new HashSet<String>();
Share article