35일차
15.6 Map
15.6.4 leet 2206
Divide Array Into Equal Pairs
배열의 숫자가 쌍을 이루고 있나?
public boolean divideArray(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
// 각 값이 몇개인 세는 코드
for (int n : nums) {
if (map.containsKey(n)) {
// 키 n의 값을 1 더해서 다시 entry에 넣는다.
int oldvalue = map.get(n);
map.put(n, oldvalue + 1);
} else {
map.put(n, 1);
}
}
// value가 홀수 인게 잇으면 return false
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
for (Entry<Integer, Integer> entry : entrySet) {
if (entry.getValue() % 2 != 0) {
return false;
}
}
return true;
}다른풀이 1748 응용
public boolean divideArray(int[] nums) {
//Divide Array Into Equal Pairs
Map<Integer, Integer> map = new HashMap<>();
for (int n : nums) {
map.putIfAbsent(n, 0);
int oldValue = map.get(n);
map.replace(n, oldValue + 1);
}
// value가 홀수 인게 잇으면 return false
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
for (Entry<Integer, Integer> entry : entrySet) {
if (entry.getValue() % 2 != 0) {
return false;
}
}
return true;
}15.6.5 leet 1748
You are given an integer array nums.
The unique elements of an array are the elements that appear exactly once in the array.
Return the sum of all the unique elements of nums.
배열에서 단 한번만 등장하는 수들의 합을 구해라.
public static int sumOfUnique(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
// 각 값이 몇개인 세는 코드
for (int n : nums) {
if (map.containsKey(n)) {
// 키 n의 값을 1 더해서 다시 entry에 넣는다.
int oldvalue = map.get(n);
map.put(n, oldvalue + 1);
} else {
map.put(n, 1);
}
}
int sum = 0;
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
for (Entry<Integer, Integer> entry : entrySet) {
if (entry.getValue() == 1) {
sum += entry.getKey();
}
}
return sum;
}다른풀이(내풀이추가)
public static int sumOfUnique(int[] nums) {
// Sum of Unique Elements
int sum = 0;
int[] arr = new int[101];
for (int n : nums) {
arr[n] += 1;
}
for (int n : nums) {
if (arr[n] == 1) {
sum += n;
}
}
return sum;
}다른풀이(강사님)
맵에 값이 없으면 넣는 메소드 : putIfAbsent();
map.putIfAbsent(n, 0);
맵 값 업데이트 하는 메소드 : replace();
map.replace(n, oldValue + 1);
public int sumOfUnique(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
// 각 값이 몇개인 세는 코드
for (int n : nums) {
// 없으면 넣는 메소드
map.putIfAbsent(n, 0);
int oldValue = map.get(n);
// 값 업데이트 하는 메소드
map.replace(n, oldValue + 1);
}
int sum = 0;
Set<Entry<Integer, Integer>> entrySet = map.entrySet();
for (Entry<Integer, Integer> entry : entrySet) {
if (entry.getValue() == 1) {
sum += entry.getKey();
}
}
return sum;
}15.7 LIFO & FIFO
15.7.1 FIFO(큐)
FIFO는 First In First Out의 약자이다.
큐라고도 하는데 줄 서 있는 모습을 의미한다.
줄을 서면 먼저온사람이 먼저 입장을 한다. 즉 선입선출이다.
큐를 정의한 인터페이스가 있는데 이것이 Queue 이다.
구현한 여러 클래스가 있다.
LinkedList가 큐를 구현하고 있다.
주요메소드는 다음과 같다.
offer : 값 넣기
poll : 꺼내면서 지우기
public class C01Queue {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
// offer : 새 아이템 삽입
queue.offer("kang");
// poll : 기존 아이템 삭제(꺼내기)
String s1 = queue.poll();
System.out.println(queue.size()); // 0
System.out.println(s1); // kang
System.out.println();
queue.offer("chae");
queue.offer("song");
queue.offer("jeong");
queue.offer("seo");
System.out.println(queue.size()); // 4
System.out.println(queue.poll());
System.out.println(queue.size()); // 3
// 꺼내면서 전체탐색
while (queue.size() > 0) {
System.out.println(queue.poll());
}
}
}15.7.2 LIFO
LIFO은 Last In First Out의 약자이다.
나중에 넣은 객체가 먼저 빠져나간다.
후입선출이고 Stack이라고도 한다.
Stack은 인터페이스가 아니라 객체라서 Stack으로 만들면 된다.
주요메소드
push() : 주어진 객체를 스택에 넣는다.
pop() : 스택 맨 위 객체를 꺼내고 삭제한다.
public class C01Stack {
public static void main(String[] args) {
// LIFO(Last In First Out), 후입선출, Stack
// 주요메소드
// push : 새 아이템 추가
// pop : 아이템 꺼내기(삭제)
Stack<String> stack = new Stack<>();
stack.push("backho");
stack.push("chisoo");
stack.push("taesup");
stack.push("daeman");
stack.push("taewoong");
System.out.println(stack.size()); // 5
String s1 = stack.pop();
System.out.println(s1); // taewoong
while (stack.size() > 0) {
System.out.println(stack.pop());
}
}
}15.7.3 leet 844
stack관련
두개의 스트링을 검사해서 같으면 true 틀리면 false
빈메모장에 타이핑 한다고 생각 #은 백스페이스
public boolean backspaceCompare(String s, String t) {
Stack<Character> stack1 = new Stack<>();
Stack<Character> stack2 = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '#') {
if (!stack1.isEmpty()) {
stack1.pop();
}
} else {
stack1.push(c);
}
}
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
if (c == '#') {
if (!stack2.isEmpty()) {
stack2.pop();
}
} else {
stack2.push(c);
}
}
if (stack1.equals(stack2)) {
return true;
} else {
return false;
}
}15.8 TreeSet
중복 저장되지 않는 Set인데 검색기능을 강화시켰다.
NavigableSet을 구현하고 있는 클래스이다.
SortedSet을 구현하고 있는데 아이템들이 정렬되어 있다.
중복 없이 정렬된 순서를 가지고 있는 것이다.
Comparable을 구현하고 있따면 자연스럽게 정렬되고 없다면 comparator를 구현해줘야한다.
그런데 왜 하필 TreeSet인가? 정렬을 Tree모양으로 정렬하기 때문이다.
어떤 element기준으로 작으면 왼쪽 크면 오른쪽으로 저장하게 된다.
다 저장한 형태가 나무 형태가 된다.
즉 어떤 element기준으로 왼쪽은 작은거 오른쪽은 큰거가 된다.
첫번째 노드부터 가장 왼쪽으로 가면 첫번째 아이템이게 되는 것이다.
결론은 정렬되어 저장되니 정렬하고 싶다면 TreeSet을 사용하는 것이 좋다.
public class C01TreeSet {
public static void main(String[] args) {
// 정렬된 Set
Set<Integer> set = new HashSet<>();
Set<Integer> treeSet = new TreeSet<>();
set.add(3000);
treeSet.add(3000);
set.add(20);
treeSet.add(20);
set.add(20000);
treeSet.add(20000);
//HashSet은 순서보장 x
System.out.println(set); //[20000, 20, 3000]
System.out.println(treeSet); //[20, 3000, 20000]
}
}TreeSet이 가진 주요 메소드가 따로 있다.
first() : 가장 첫번째 아이템
last() : 마지막 아이템
lower() : 특정값보다 작은 아이템 (본인 포함x)
higher() : 특정값보다 큰 아이템 (본인 포함x)
floor() : 특정값보다 작거나 같은 아이템 (본인 포함)
ceiling() : 특정 값보다 크거나 같은 아이템 (본인 포함)
descendingSet() : 거꾸로 정렬된 NavigableSet 리턴(원본이 바뀌는게 아님)
public class C02TreeSet {
public static void main(String[] args) {
// 정렬된 Set
NavigableSet<Integer> set = new TreeSet<>();
set.addAll(Set.of(3, 1, 20, 3000, 15, 7, 9, 2500, 100));
System.out.println(set);
// [1, 3, 7, 9, 15, 20, 100, 2500, 3000]
// first : 가장 첫번째 아이템
System.out.println(set.first()); // 1
// last : 마지막 아이템
System.out.println(set.last()); // 3000
// lower : 특정값보다 작은 아이템
System.out.println(set.lower(50)); // 20
// higher : 특정값보다 큰 아이템
System.out.println(set.higher(50)); // 100
// floor : 특정값보다 작은데 본인 포함
System.out.println(set.floor(20)); // 20
// ceiling : 특정 값보다 큰데 본인 포함
System.out.println(set.ceiling(20)); // 20
// 거꾸로 정렬된 NavigableSet 리턴
NavigableSet<Integer> descendingSet = set.descendingSet();
System.out.println(descendingSet);
// [3000, 2500, 100, 20, 15, 9, 7, 3, 1]
}
}필요하면 가져다 사용하자.
15.8.1 Comparator -1
element가 있는데 두개를 비교할텐데 어떻게 비교하나?
Comparable, comparator를 기준으로 비교한다.
Comparable이 없는 객체를 TreeSet에 넣고 싶다면
TreeSet()생성자 중 comparator을 파라미터로 사용하는 생성자가 있다.
public class C03Comparator {
public static void main(String[] args) {
TreeSet<Book> set = new TreeSet<>((b1, b2) -> b1.getTitle().compareTo(b2.getTitle()));
set.add(new Book("slamdunk"));
set.add(new Book("avatar"));
set.add(new Book("glory"));
}
}15.8.2 Comparator -2
public class ComparatorExample {
public static void main(String[] args) {
// 비교자를 제공한 TreeSet 컬렉션 생성
TreeSet<Fruit> treeSet = new TreeSet<>((f1, f2) -> f1.price - f2.price);
// 객체저장
treeSet.add(new Fruit("포도", 3000));
treeSet.add(new Fruit("수박", 10000));
treeSet.add(new Fruit("딸기", 6000));
// 객체 하나씩 가져오기
for (Fruit fruit : treeSet) {
System.out.println(fruit.name + ":" + fruit.price);
}
}
}15.8.3 Comparable
Comparable을 구현하고 있으면 자연적으로 정렬이 가능하다.
Comparable이 가지고 잇는 추상메소드를 구현해야한다.
class Movie implements Comparable<Movie> {
private String title;
@Override
public int compareTo(Movie o) {
// 이 객체가 파라미터보다 작으면 음수
// 같으면 0
// 이 객체가 파라미터 보다 크면 양수
return this.title.compareTo(o.title);
}
}15.8.4 확인문제 10번
TreeSet에 Student객체를 저장할때 score필드 값을 기준으로 자동정렬하고싶다.
last()메소드를 호출 햇을때 가장 높은 score의 객체가 리턴되도록하기
public class TreeSetExample {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<>();
treeSet.add(new Student("blue", 96));
treeSet.add(new Student("hong", 56));
treeSet.add(new Student("white", 92));
Student student = treeSet.last();
System.out.println("최고점수: " + student.score); //96
System.out.println("최고점수를 받은 아이디: " + student.id); // blue
}
}public class Student implements Comparable<Student>{
public String id;
public int score;
public Student(String id, int score) {
this.id = id;
this.score = score;
}
@Override
public int compareTo(Student o) {
return this.score - o.score;
}
}15.9 수정할 수 없는 컬렉션
수정할 수 없는 컬렉션이란 요소 추가 삭제 할 수없는 컬렉션을 말한다.
of()메소드 , copyOf()메소드, 배열로부터 List만들기 등이 있다.
Arrays.asList는 사이즈가 고정된 List를 리턴한다. 그래서 수정은 가능하다.
public class ImmutableExample {
public static void main(String[] args) {
// List 불변 컬렉션 생성
List<String> immutableList1 = List.of("A", "B", "C");
// immutableList1.add("D"); 불가능
// Set 불변 컬렉션 생성
Set<String> immutableSet1 = Set.of("A", "B", "C");
// immutableSet1.remove("A"); 불가능
// Map 불변 컬렉션 생성
Map<Integer, String> immutableMap1 = Map.of(
1, "A",
2, "B",
3, "C");
// immutableMap1.put(4, "D"); 불가능
// List 컬렉션을 불변 컬렉션으로 복사
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
List<String> immutableList2 = List.copyOf(list);
// Set컬렉션을 불변 컬렉션으로 복사
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
Set<String> immutableset2 = Set.copyOf(set);
// Map컬렉션을 불변 컬렉션으로 복사
Map<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
Map<Integer, String> immutableMap2 = Map.copyOf(map);
// 배열로부터 List불변 컬렉션 생성
// 수정은 가능하다
String[] arr = { "A", "B", "C" };
List<String> immutableList3 = Arrays.asList(arr);
}
}수정 가능한 컬렉션으로 변경하려면 수정불가능한 컬렉션을 새 컬렉션을 만들때 생성자의 파라미터로 넣어주면된다.
2023.03.16 후기
Comparable comparator 구분 해서 사용하는 이유를 몰랐었는데
람다를 배우고 사용하니 알게 되엇다.
'국비 > Java' 카테고리의 다른 글
| 2023.03.20 37일차 Java (0) | 2023.03.20 |
|---|---|
| 2023.03.17 36일차 Java (0) | 2023.03.19 |
| 2023.03.15 34일차 Java (0) | 2023.03.15 |
| 2023.03.14 33일차 Java (0) | 2023.03.14 |
| 2023.03.13 32일차 Java (0) | 2023.03.13 |