반응형
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에 입력하면 시계열 패널에 각 데이터베이스의 트랜잭션 수를 시간별로 시각화할 수 있습니다.

반응형
반응형
PostgreSQL Query Discussion

Assistant: Grafana 패널에 시계열 데이터를 시각화하려면 해당 시계열 데이터를 쿼리하여 Grafana가 이해할 수 있는 형식으로 가져와야 합니다. PostgreSQL의 pg_stat_activity 테이블에서 데이터베이스 이름(datname)과 트랜잭션 시작 시간(xact_start)을 사용하여 시계열 데이터를 추출하는 쿼리를 작성할 수 있습니다.

다음은 Grafana 패널을 만드는 데 사용할 수 있는 쿼리 예제입니다:

SELECT
  datname AS "Database",
  count(datname) AS "Session Count",
  xact_start AS "Transaction Start Time"
FROM
  pg_stat_activity
GROUP BY
  datname,
  xact_start
ORDER BY
  xact_start

이 쿼리는 각 데이터베이스 별 세션 수와 각 트랜잭션의 시작 시간을 반환합니다. Grafana에서 이 쿼리를 사용하여 시계열 데이터를 시각화할 수 있습니다. 데이터베이스 별로 세션 수의 변화와 각 트랜잭션의 시작 시간을 시계열 차트에 표시할 수 있습니다.

User: Value column must have numeric datatype, column: Database type: string value: postgres 이런 에러가 발생하네

Assistant: 죄송합니다. Grafana의 시계열 패널에서 사용하는 쿼리는 시간(timestamp), 메트릭(metric), 값(value)의 세 가지 필드가 필요합니다. datname 필드는 문자열 타입이므로 메트릭으로 사용할 수 없습니다. 대신, 각 데이터베이스의 트랜잭션 수를 시간별로 집계하여 표시해야 합니다.

이를 위해서는 xact_start의 시간 부분을 기준으로 세션 수를 집계해야 합니다. 다음은 이러한 쿼리를 작성하는 방법입니다:

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

이 쿼리는 xact_start를 분 단위로 잘라서(time) 각 데이터베이스(datname) 별로 트랜잭션 수(count(*))를 집계합니다. 이렇게 하면 Grafana에서 시계열 차트로 시각화할 수 있습니다.

반응형
반응형

 

 

User: postgresql이 pg_stat_activity 테이블에서 xact_start, querystart차이

Assistant: pg_stat_activity 테이블은 현재 실행 중인 PostgreSQL 세션에 대한 정보를 제공합니다. 여기에는 각 세션의 시작 시간, 실행 중인 쿼리의 시작 시간 및 트랜잭션 시작 시간과 같은 정보가 포함됩니다.

- xact_start: 현재 세션이 시작된 시간으로, 해당 세션이 트랜잭션을 시작한 시간을 나타냅니다. 이는 현재 세션이 트랜잭션 내에서 작동 중인지 여부를 파악하는 데 사용됩니다.

- query_start: 현재 세션에서 현재 실행 중인 쿼리의 시작 시간입니다. 이것은 현재 세션에서 실행 중인 쿼리의 시작 시간을 나타내며, 다음 쿼리가 실행되기 전까지 해당 값이 갱신되지 않습니다. 이것은 현재 세션이 얼마나 오랫동안 쿼리를 실행하고 있는지를 추적하는 데 사용됩니다.

따라서 두 값의 차이는 세션이 트랜잭션을 시작한 후 현재까지 얼마나 오랫동안 실행되고 있는지를 나타냅니다. 만약 이 값이 크다면, 해당 세션이 오랜 시간동안 활동 중이거나 긴 트랜잭션을 가지고 있을 수 있습니다.

User: pg_stat_activity를 count(datname), xact_start는 Time series 로 grafana 패널 만드는 쿼리

Assistant: Grafana 패널에 시계열 데이터를 시각화하려면 해당 시계열 데이터를 쿼리하여 Grafana가 이해할 수 있는 형식으로 가져와야 합니다. PostgreSQL의 pg_stat_activity 테이블에서 데이터베이스 이름(datname)과 트랜잭션 시작 시간(xact_start)을 사용하여 시계열 데이터를 추출하는 쿼리를 작성할 수 있습니다.

SELECT
  datname AS "Database",
  count(datname) AS "Session Count",
  xact_start AS "Transaction Start Time"
FROM
  pg_stat_activity
GROUP BY
  datname,
  xact_start
ORDER BY
  xact_start
        

이 쿼리는 각 데이터베이스 별 세션 수와 각 트랜잭션의 시작 시간을 반환합니다. Grafana에서 이 쿼리를 사용하여 시계열 데이터를 시각화할 수 있습니다. 데이터베이스 별로 세션 수의 변화와 각 트랜잭션의 시작 시간을 시계열 차트에 표시할 수 있습니다.

User: Value column must have numeric datatype, column: Database type: string value: postgres 이런 에러가 발생하네

Assistant: Grafana의 시계열 패널에서 사용하는 쿼리는 시간(timestamp), 메트릭(metric), 값(value)의 세 가지 필드가 필요합니다. datname 필드는 문자열 타입이므로 메트릭으로 사용할 수 없습니다. 대신, 각 데이터베이스의 트랜잭션 수를 시간별로 집계하여 표시해야 합니다.

이를 위해서는 xact_start의 시간 부분을 기준으로 세션 수를 집계해야 합니다. 다음은 이러한 쿼리를 작성하는 방법입니다:

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
        

이 쿼리는 xact_start를 분 단위로 잘라서(time) 각 데이터베이스(datname) 별로 트랜잭션 수(count(*))를 집계합니다. 이렇게 하면 Grafana에서 시계열 차트로 시각화할 수 있습니다.

User: 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
        

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

  1. date_trunc('minute', xact_start)를 사용하여 xact_start를 분 단위로 잘라냅니다.
  2. User: Value column must have numeric datatype, column: Database type: string value: postgres 이런 에러가 발생하네
  3. 각 데이터베이스(datname)별로 트랜잭션의 수(count(*))를 집계합니다.
  4. 결과를 시간(time)을 기준으로 정렬합니다.

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

반응형
반응형
Spring 프레임워크와 Tomcat의 차이

Spring 프레임워크와 Tomcat의 차이

스프링 프레임워크(Spring Framework)

  • 스프링은 Java 기반의 웹 애플리케이션 및 엔터프라이즈 애플리케이션을 개발하기 위한 오픈 소스 프레임워크입니다.
  • 주요 기능은 의존성 주입(Dependency Injection), 관점 지향 프로그래밍(Aspect-Oriented Programming), 포터블 리미팩토링(POJO), 템플릿을 통한 데이터 접근(Data Access Templates), 트랜잭션 관리(Transaction Management) 등이 있습니다.
  • 스프링은 애플리케이션의 모듈화, 테스트 용이성, 코드의 재사용성 등을 촉진합니다.
  • 주로 개발자들이 소프트웨어 아키텍처를 유연하게 만들기 위해 사용됩니다.

Tomcat

  • 아파치 톰캣(Apache Tomcat)은 Java Servlet, JavaServer Pages(JSP) 등을 실행하기 위한 웹 애플리케이션 서버입니다.
  • Tomcat은 웹 애플리케이션의 배포, 실행, 관리를 담당합니다.
  • Servlet 컨테이너로서 동작하며, HTTP 요청에 대한 처리 및 응답을 처리합니다.
  • Tomcat은 스프링이나 다른 프레임워크를 이용하여 개발된 Java 웹 애플리케이션을 호스팅하고 실행하는 고 실행하는 데 사용됩니다.
반응형

'IT-기타' 카테고리의 다른 글

browser(브라우져) ssl 인증서 확인  (0) 2023.01.16
반응형

 

import java.io.*; 
import java.util.*; 

public class Main {
//	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//	static StringTokenizer st;
	
	
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
		
	public static void main(String[] args)throws Exception{

		st = new StringTokenizer(br.readLine());
		
		char a=st.nextToken().charAt(0);
//		int b=Integer.parseInt(st.nextToken());

// 아스키코드표를 보면, 대소문자는 정확히 32만큼 차이가 나므로,
//  char a를 (int)로 형변환 후 32를 빼주면, 소문자->대문자가 됨
		int b = (int)a-32;
		
		
		System.out.println((char)b);

	}

}
반응형

'프로그래밍 > 문제풀이' 카테고리의 다른 글

[반복문] N값만큼 건너띄어서 출력하기  (1) 2023.12.28
반응형
import java.io.*; 
import java.util.*; 

public class Main {
	
	
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
		
	public static void main(String[] args)throws Exception{

		st = new StringTokenizer(br.readLine());
		
		int N=Integer.parseInt(st.nextToken());
		
		int [] arr = {1,2,3,4,5,6,7,8,9,10};

		for (int i = 0; i < arr.length; i += N) {
		   // n값 만큼 건너뛰려면,  for문의 i에  i += N을 써주면 됨,
           // 보통 i++,  i--가 익숙해서, 틀린문제
			System.out.println(arr[i]);
			
		}
		

	}

}
반응형

'프로그래밍 > 문제풀이' 카테고리의 다른 글

소문자->대문자 변환  (1) 2023.12.29

+ Recent posts