반응형
HashMap Traversal Methods

1. entrySet() 이용

entrySet()HashMap의 모든 키-값 쌍을 Map.Entry 객체로 반환합니다.

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

특징

  • 구조: Map.Entry 객체를 통해 키와 값을 동시에 접근.
  • 장점:
    • 키와 값 모두를 한 번에 접근할 수 있어 효율적.
    • 코드가 간결하고 가독성이 높음.
  • 단점: entrySet()Set<Map.Entry>를 반환하므로 추가적인 객체를 생성.

2. keySet() 이용

keySet()HashMap의 모든 키를 Set으로 반환합니다.

for (String key : map.keySet()) {
    System.out.println("Key: " + key + ", Value: " + map.get(key));
}

특징

  • 구조: 키를 순회하며 각 키를 이용해 get()으로 값을 가져옴.
  • 장점:
    • 키만 필요할 때 간단하게 사용 가능.
  • 단점:
    • 키를 순회하면서 get() 메서드를 호출하므로, 성능이 상대적으로 떨어질 수 있음(특히 큰 HashMap에서는 비효율적).

3. values() 이용

values()HashMap의 모든 값을 Collection으로 반환합니다.

for (Integer value : map.values()) {
    System.out.println("Value: " + value);
}

특징

  • 구조: 값만 순회하며 접근.
  • 장점:
    • 값만 필요할 때 간단히 사용 가능.
  • 단점:
    • 값에 대응하는 키를 얻을 수 없음.

4. Java 8+ forEach() 이용

Java 8부터는 HashMap에 대해 forEach() 메서드를 사용할 수 있습니다.

map.forEach((key, value) -> {
    System.out.println("Key: " + key + ", Value: " + value);
});

특징

  • 구조: 람다 표현식을 통해 키와 값에 동시에 접근.
  • 장점:
    • 최신 스타일의 코드로 가독성 높음.
    • 병렬 처리를 지원하는 스트림과 쉽게 결합 가능.
  • 단점:
    • Java 8 이상에서만 사용 가능.

5. Iterator 이용

Iterator를 사용해 entrySet()이나 keySet()을 탐색합니다.

Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, Integer> entry = iterator.next();
    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

특징

  • 구조: Iterator를 통해 순회하며 요소 제거도 가능.
  • 장점:
    • 순회 중 안전하게 요소를 제거할 수 있음.
  • 단점:
    • 코드가 다소 장황해짐.

차이점 요약

순회 방법 키 접근 값 접근 성능 사용 시기
entrySet() 가능 가능 효율적 키와 값을 동시에 접근할 때
keySet() 가능 가능 비효율적 키만 필요하거나 간단한 순회 시
values() 불가능 가능 효율적 값만 필요한 경우
forEach() 가능 가능 효율적 람다를 활용하여 코드 간결화 시
Iterator 가능 가능 보통 순회 중 요소를 제거해야 할 때

추천

  • 키와 값을 모두 접근해야 한다면 entrySet()이나 forEach()가 가장 효율적.
  • 키만 필요하면 keySet(), 값만 필요하면 values().
  • 요소 제거를 포함한 순회는 Iterator를 사용.
반응형

'프로그래밍 > java' 카테고리의 다른 글

HashMap 순회 에러 방지  (0) 2025.01.02
hashset, treeset 비교  (0) 2024.12.22
hashmap vs treemap 비교  (1) 2024.12.21
[java]keystore 경로, list 확인  (0) 2023.02.02
이클립스 주요 단축키  (0) 2022.12.30
반응형
HashMap Iterator Removal

문제: 일반적인 순회에서 요소 제거

HashMapfor-each 루프나 keySet() 등을 통해 순회하면서 remove() 메서드를 직접 호출하면, HashMap의 내부 구조가 변경되므로 ConcurrentModificationException이 발생합니다.

HashMap<String, Integer> map = new HashMap<>();
map.put("Alice", 30);
map.put("Bob", 25);
map.put("Charlie", 35);

// 순회 중 요소를 직접 제거하려고 시도
for (String key : map.keySet()) {
    if (map.get(key) < 30) {
        map.remove(key); // 예외 발생: ConcurrentModificationException
    }
}

해결 방법: Iterator를 사용한 안전한 제거

Iteratorremove() 메서드를 제공하여 순회 중 안전하게 요소를 제거할 수 있습니다.

HashMap<String, Integer> map = new HashMap<>();
map.put("Alice", 30);
map.put("Bob", 25);
map.put("Charlie", 35);

Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, Integer> entry = iterator.next();
    if (entry.getValue() < 30) { // 값이 30보다 작은 경우 제거
        iterator.remove(); // 안전하게 요소 제거
    }
}

// 결과 출력
System.out.println(map); // {Alice=30, Charlie=35}

왜 Iterator를 사용해야 할까?

  • 동기화 문제 방지:
    • Iterator는 내부적으로 fail-fast 메커니즘을 사용해 동기화 문제를 방지.
    • remove() 호출 시 HashMap의 상태를 안전하게 업데이트.
  • 구조적 변경 감지:
    • HashMap은 구조적 변경(요소 추가/삭제 등)이 발생할 때 즉시 예외를 던져 무결성을 유지.
    • Iterator는 이러한 변경을 감지하고 안전한 방식으로 처리.
  • 성능:
    • Iterator를 통해 요소를 제거하면 내부 버킷(bucket)과 해싱 구조를 최적화하며 동작.

요약

  • 요소(element): HashMap의 각 키-값 쌍.
  • 순회 중 제거 문제: HashMap의 구조 변경 시 ConcurrentModificationException이 발생.
  • 해결책: Iteratorremove() 메서드를 사용해 안전하게 요소를 제거.

결론: Iterator는 구조적 무결성을 유지하면서 순회 중 요소를 안전하게 제거하는 가장 표준적인 방법입니다.

반응형

'프로그래밍 > java' 카테고리의 다른 글

HashMap을 탐색(순회) 방법  (0) 2025.01.02
hashset, treeset 비교  (0) 2024.12.22
hashmap vs treemap 비교  (1) 2024.12.21
[java]keystore 경로, list 확인  (0) 2023.02.02
이클립스 주요 단축키  (0) 2022.12.30
반응형

 

Java HashSet과 TreeSet 비교 및 사용 예제

 

HashSet vs TreeSet 비교

특징 HashSet TreeSet
데이터 구조 해시 테이블 기반 이진 탐색 트리 기반 (Red-Black Tree)
정렬 여부 순서를 보장하지 않음 자동 정렬 (기본: 오름차순)
중복 허용 여부 중복 값 허용하지 않음 중복 값 허용하지 않음
시간 복잡도 삽입/삭제/검색: O(1) (평균) 삽입/삭제/검색: O(log n)
null 허용 여부 1개의 null 값 허용 null 값을 허용하지 않음
사용 사례 빠른 검색 및 순서가 중요하지 않은 경우 정렬된 데이터나 범위 검색이 필요한 경우

 

HashSet 사용 예제


import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        HashSet set = new HashSet<>();

        // 요소 추가
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        set.add("Apple"); // 중복은 추가되지 않음

        // 출력
        System.out.println("HashSet: " + set);

        // 요소 검색
        System.out.println("Contains 'Apple': " + set.contains("Apple"));

        // 요소 제거
        set.remove("Banana");
        System.out.println("After removing 'Banana': " + set);
    }
}

출력:


HashSet: [Orange, Apple, Banana]
Contains 'Apple': true
After removing 'Banana': [Orange, Apple]

 

TreeSet 사용 예제


import java.util.TreeSet;

public class TreeSetExample {
    public static void main(String[] args) {
        TreeSet set = new TreeSet<>();

        // 요소 추가
        set.add("Apple");
        set.add("Banana");
        set.add("Orange");
        set.add("Apple"); // 중복은 추가되지 않음

        // 출력
        System.out.println("TreeSet: " + set);

        // 첫 번째와 마지막 요소 확인
        System.out.println("First: " + set.first());
        System.out.println("Last: " + set.last());

        // 요소 제거
        set.remove("Banana");
        System.out.println("After removing 'Banana': " + set);
    }
}

출력:


TreeSet: [Apple, Banana, Orange]
First: Apple
Last: Orange
After removing 'Banana': [Apple, Orange]
반응형

'프로그래밍 > java' 카테고리의 다른 글

HashMap을 탐색(순회) 방법  (0) 2025.01.02
HashMap 순회 에러 방지  (0) 2025.01.02
hashmap vs treemap 비교  (1) 2024.12.21
[java]keystore 경로, list 확인  (0) 2023.02.02
이클립스 주요 단축키  (0) 2022.12.30
반응형
--- HashMap vs TreeMap

HashMap과 TreeMap의 비교

주요 비교

특징 HashMap TreeMap
데이터 구조 해시 테이블(Hash Table) 기반으로 키-값을 저장합니다. 이진 탐색 트리(Red-Black Tree) 기반으로 키-값을 저장합니다.
정렬 여부 키 순서를 보장하지 않습니다. 키를 자동으로 정렬(기본 오름차순)합니다. (사용자 정의 Comparator 가능)
시간 복잡도 삽입/검색/삭제: 평균적으로 O(1)
최악의 경우(충돌): O(n)
삽입/검색/삭제: O(log n)
null 허용 여부 키: 1개의 null 허용
값: 다수의 null 허용
키: null 허용하지 않음
값: 다수의 null 허용
성능 일반적으로 빠름 (해시 기반 접근). 느림 (트리 기반 접근).
적합한 사용 사례 빠른 검색/삽입/삭제가 중요한 경우. 데이터가 정렬된 상태로 필요하거나 범위 검색이 필요한 경우.

예제 코드

HashMap 사용 예제

    

import java.util.HashMap; public class HashMapExample { public static void main(String[] args) { HashMap hashMap = new HashMap<>(); hashMap.put(1, "One"); hashMap.put(2, "Two"); hashMap.put(3, "Three"); System.out.println("HashMap: " + hashMap); System.out.println("Value for key 2: " + hashMap.get(2)); hashMap.remove(2); System.out.println("After removal: " + hashMap); System.out.println("Keys: " + hashMap.keySet()); System.out.println("Values: " + hashMap.values()); } }

출력:


HashMap: {1=One, 2=Two, 3=Three}
Value for key 2: Two
After removal: {1=One, 3=Three}
Keys: [1, 3]
Values: [One, Three]

    

TreeMap 사용 예제


import java.util.TreeMap;

public class TreeMapExample {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap<>();
        treeMap.put(3, "Three");
        treeMap.put(1, "One");
        treeMap.put(2, "Two");

        System.out.println("TreeMap: " + treeMap);
        System.out.println("First Key: " + treeMap.firstKey());
        System.out.println("Last Key: " + treeMap.lastKey());

        System.out.println("SubMap (1 to 3): " + treeMap.subMap(1, 3));
    }
}

	

출력:


TreeMap: {1=One, 2=Two, 3=Three}
First Key: 1
Last Key: 3
SubMap (1 to 3): {1=One, 2=Two}

    
반응형

'프로그래밍 > java' 카테고리의 다른 글

HashMap 순회 에러 방지  (0) 2025.01.02
hashset, treeset 비교  (0) 2024.12.22
[java]keystore 경로, list 확인  (0) 2023.02.02
이클립스 주요 단축키  (0) 2022.12.30
printf() 출력  (0) 2022.12.21
반응형
PostgreSQL Query Discussion
SELECT
datname AS "metric",
count(datname) AS "Value",
date_trunc('minute', xact_start) AS time
FROM
pg_stat_activity
GROUP BY
datname,
xact_start
ORDER BY
xact_start
쿼리는 Invalid type for column time, must be of type timestamp or unix timestamp, got: 에러

Assistant: 죄송합니다. pg_stat_activity 테이블에서 트랜잭션이 시작되지 않은 세션의 xact_start 값은 NULL일 수 있습니다. 이를 방지하기 위해 xact_startNULL이 아닌 경우에만 집계하도록 필터링을 추가해야 합니다. 또한, Grafana에서 요구하는 형식에 맞게 time 열을 적절히 처리해야 합니다.

다음은 xact_startNULL이 아닌 경우에만 데이터를 집계하여 Grafana에서 사용할 수 있는 쿼리입니다:

SELECT
  date_trunc('minute', xact_start) AS time,
  datname AS metric,
  count(*) AS value
FROM
  pg_stat_activity
WHERE
  xact_start IS NOT NULL
GROUP BY
  time, datname
ORDER BY
  time

이 쿼리는 다음과 같은 기능을 합니다:

  • date_trunc('minute', xact_start)를 사용하여 xact_start를 분 단위로 잘라냅니다.
  • xact_startNULL이 아닌 경우에만 데이터를 필터링합니다.
  • 각 데이터베이스(datname)별로 트랜잭션의 수(count(*))를 집계합니다.
  • 결과를 시간(time)을 기준으로 정렬합니다.

이렇게 하면 Grafana가 요구하는 시계열 데이터 형식에 맞게 데이터를 준비할 수 있습니다. 이 쿼리를 Grafana에 입력하면 시계열 패널에 각 데이터베이스의 트랜잭션 수를 시간별로 시각화할 수 있습니다.

반응형

+ Recent posts