09009

[Java] collection 본문

Back-End/JAVA
[Java] collection
09009 2023. 3. 11.

Iterator 인터페이스

컬렉션에 저장되어 있는 객체들을 저장방법에 상관없이 접근할 수 있도록 한 인터페이스

→ 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화, 컬렉션에 저장된 각 요소에 접근하는 기능

 반환형 메서드 설명
boolean hasNext() 읽어올 다음 요소가 있는지 확인
Object next() 반복 처리로 다음 요소를 읽어온다. 호출하기 전에 hasNext()를 호출하여 읽어 올 요소가 있는지 확인하는 것을 권장
void remove() next()로 읽어 온 요소 삭제. next()를 호출한 후에 remove()를 호출해야 한다.

 

컬렉션 프레임워크의 핵심 인터페이스

   
List 순서가 유지되는 데이터의 집합. 중복 허용
구현클래스 : ArrayList, LinkedList, Stack, Vector 등
Set 중복을 허용하지 않고 순서를 유지하지 않는 데이터의 집합
구현클래스 : HashSet, TreeSet 등
Map 키(key)와 값(value) 하나의 쌍으로 이루어진 데이터의 집합
순서 유지 x, 키는 중복 허용 x, 값은 중복 허용
구현클래스: HashMap, TreeMap 등

 

List

 

 ArrayList

 반환형 메서드 설명
void add(int index, Object o) 지정된 위치(index)에 객체를 저장
boolean add(Object o) ArrayList의 마지막에 객체를 추가, 성공하면 true
Object set(int index, Object o) 주어진 객체(element)를 지정된 위치(index)에 저장
Object remove(int index) 지정된 위치(index)에 있는 객체 제거
boolean remove(Object o) 지정된 객체 제거 (성공 시 true 실패 시 false)
Object get(int index) 지정된 위치(index)에 저장된 객체 반환
int size() ArrayList에 저장된 객체의 개수 반환

 

✍ 입력

package ch11;
import java.util.ArrayList;
import java.util.Iterator;
public class Array1 {
	public static void main(String[] args) {
		ArrayList<String> al1 = new ArrayList<>();
		al1.add("구렁이"); al1.add("팔렁이"); // al1.add(888); 문자열이 아님
		al1.add("구렁삼"); al1.add("구렁사"); al1.add("구렁이");
		System.out.println("데이터 개수 : " + al1.size());
		for(int i = 0; i < al1.size(); i++) {
			System.out.print(al1.get(i) + "\t");
		}
		System.out.println();
		for(String str : al1) {
			System.out.print(str + "\t");
		}
		System.out.println();
		
		Iterator<String> its = al1.iterator(); 
		while(its.hasNext()) { // 가져올 다음 데이터가 있는지? 
			System.out.print(its.next() + "\t"); // 다음 데이터를 가져와서 출력
		}
	}

}

 <E> E : Elements 요소, 제네릭 쓰는 이유: 데이터형을 정하기 위해
 개수가 정해지지 않음 (개수는 고정된 것이 아니라 유동적임)

 배열은 개수가 정해져 있고 리스트는 정해지지 않음

ArrayList<String> al1 = new ArrayList<>();

💻 출력 

데이터 개수 : 5
구렁이	팔렁이	구렁삼	구렁사	구렁이	
구렁이	팔렁이	구렁삼	구렁사	구렁이	
구렁이	팔렁이	구렁삼	구렁사	구렁이

✍ 입력

package ch11;
import java.util.ArrayList;
public class Array3 {
	public static void main(String[] args) {
		ArrayList<String> snakes = new ArrayList<>();
		snakes.add("구렁이"); snakes.add("팔렁이"); snakes.add("구렁삼");
		snakes.add("구렁사"); snakes.add("구렁이"); prn(snakes);
		snakes.add(1, "구렁오"); // index 1에 "구렁오" 추가, 1에 데이터가 들어가면서 index가 뒤로 이동
		prn(snakes);
		
	    	snakes.set(4, "도마뱀"); // index 4번째 값을 변경
            	prn(snakes);
	    
	   	snakes.remove(2); // 해당하는 인덱스를 지우면 뒤는 하나씩 앞으로 당겨진다. 
	   	prn(snakes);
	    
	    	snakes.remove("구렁이"); // 처음 발견된 "구렁이"를 지우고 인덱스가 하나씩 당겨진다. 나머지 "구렁이"는 안지워짐
	    	prn(snakes);
	}

	private static void prn(ArrayList<String> snakes) {
		for(String snake : snakes) {
			System.out.print(snake + "\t");
		}
		System.out.println();
	}

}

💻 출력 

구렁이	팔렁이	구렁삼	구렁사	구렁이	
구렁이	구렁오	팔렁이	구렁삼	구렁사	구렁이	
구렁이	구렁오	팔렁이	구렁삼	도마뱀	구렁이	
구렁이	구렁오	구렁삼	도마뱀	구렁이	
구렁오	구렁삼	도마뱀	구렁이

✍ 입력

import java.util.Iterator;
import java.util.LinkedList;
// 반복자를 사용하여 조회하는 방법은 모든 컬렉션 클래스의 종류에 상관없이 동일한 형태의 데이터 참조방식이다.
public class IteratorUsage {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<String>();
        list.add("First"); list.add("Second"); list.add("Third"); list.add("Fourth");

        Iterator<String> itr = list.iterator();// collection 객체가 모두 가지고 있는
//         반복자 (순서대로 조회해주는 기능을 가진 객체)를 반환해줌

        System.out.println("반복자를 이용한 1차 출력과 \"Third\" 삭제");

        while(itr.hasNext()) { // 현재 다음 항목이 있으면
            String curStr = itr.next();
            System.out.println(curStr);
            if(curStr.compareTo("Third") == 0) // •  a.compareTo(b) 메서드 : a와 b가 같은 순서면 0 ,a > b 이면 0보다 큰 값 반환 ,a < b 이면 0보다 작은 값 반환

            itr.remove();
        }
        System.out.println("\n\"Third\" 삭제 후 반복자를 이용한 2차 출력");
        itr = list.iterator();
        while(itr.hasNext()) {
            System.out.println(itr.next());
        }
    }
}

💻 출력 

반복자를 이용한 1차 출력과 "Third" 삭제
First
Second
Third
Fourth

"Third" 삭제 후 반복자를 이용한 2차 출력
First
Second
Fourth

얕은 복사 vs 깊은 복사

얕은 복사(shallow copy): 참조변수만 복사. 원본 객체의 주소값을 복사 →  원본을 변경하면 복사본도 영향을 받는다.

깊은 복사 (deepCopy):  참조값의 복사가 아닌 참조된 객체 자체를 복사, 같은 내용의 새로운 객체를 생성   원본과 복사본이 서로 다른 객체를 참조하므로 원본의 변경이 복사본에 영향을 미치지 않는다.

 

 

입력

package ch11;
import java.util.Arrays;
public class Copy1 {
	public static void main(String[] args) {
		int[] data = {1, 2, 3, 4};
		int[] sCopy = null, dCopy = null;
		sCopy = data; 
		dCopy = deepCopy(data);
		data[0] = 77;  // 원본 데이터 변경
		System.out.println("원본 : " + Arrays.toString(data));
		System.out.println("sCopy : " + Arrays.toString(sCopy));
		System.out.println("dCopy : " + Arrays.toString(dCopy));
	}

	private static int[] deepCopy(int[] data) {
		int[] result = new int[data.length]; // dCopy: 같은 내용의 새로운 객체 생성
		System.arraycopy(data, 0, result, 0, result.length);
		return result;
	}
}

💻 출력 

원본 : [77, 2, 3, 4]
sCopy : [77, 2, 3, 4]
dCopy: [1, 2, 3, 4]

얕은 복사(sCopy)는 원본 데이터인 data[0]의 값을 변경하였을 때 복사본의 결과도 바뀌었다. 하지만 깊은 복사(dCopy)의 경우 원본 데이터를 변경하여도 복사본의 결과는 바뀌지 않았다.

 

* Arrays 클래스 참고

 

[Java] Arrays 클래스

Arrays 클래스 • 배열 조작 기능을 하는 클래스 • 배열을 다루는데 유용한 메서드가 정의되어 있다. 배열의 비교와 출력 - equals(), toString() • equals() 두 배열에 저장된 모든 요소를 비교하여 같으

haaland09009.tistory.com


Stack

  마지막에 저장한 데이터를 가장 먼저 꺼내는 LIFO(Last In First Out) 구조

 반환형 메서드 설명
boolean empty() stack이 비어있는지 비교하여 비어 있으면 true 반환, isEmpty()도 동일한 기능 수행
Object peek() stack의 가장 위에 있는 객체 반환
Object pop() stack의 가장 위에 있는 객체 삭제 후 그 객체를 반환
Object push(Object item) stack의 가장 위쪽에서 객체 추가 (stack에 객체(item)를 저장한다)
int search(Object o) stack에서 주어진 객체(o)를 찾아 그 위치를 반환
못 찾으면 -1을 반환 (배열과 달리 인덱스값은 1부터 시작)

 

✍ 입력

package ch11;
import java.util.Stack;
public class Stack1 {
	public static void main(String[] args) {
		String[] nations = {"미국","중국","한국","영국","일본","대만"};
		Stack<String> stack = new Stack<>();
		for(String nation : nations) {
			stack.push(nation);
		}
		while(!stack.isEmpty()) {
			System.out.println(stack.pop());
		}
	}
}

💻 출력 

대만
일본
영국
한국
중국
미국

 

 stack에서 pop()을 실행하였을 때, 지정한 배열에서 가장 마지막에 들어간 "대만"부터 먼저 출력된다.


Queue

• 처음에 저장된 데이터를 가장 먼저 꺼내는 FIFO(First In First Out) 구조

• Queue 인터페이스의 구현체인 LinkedList 사용

 

 반환형 메서드 설명
boolean add(Object o) 지정된 객체를 Queue에 추가
Object remove() Queue에서 객체를 꺼내 반환. Queue가 비어있을 때 NoSuchElementException 발생
Object element() 삭제없이 요소를 읽어온다. Queue가 비어있을 때 NoSuchElementException 발생
boolean offer(Object o) Queue에 객체를 넣는다.
Object poll() Queue에서 객체를 꺼내서 반환. Queue가 비어있다면 null을 반환
Object peek() Queue의 맨 위에 있는 객체 반환. 이 때 객체를 queue에서 제거하지는 않는다. 
Queue가 비어있다면 null을 반환

 

✍ 입력

package ch11;
import java.util.LinkedList;
public class Queue1 {
	public static void main(String[] args) {
		String[] fruits = {"사과","딸기","포도","바나나"};
		LinkedList<String> q = new LinkedList<>();
		for(String fruit : fruits) {
			q.offer(fruit);
		}
		while(!q.isEmpty()) {
			System.out.println(q.poll());
		}
	}
}

💻 출력 

사과
딸기
포도
바나나

Queue에서 객체를 꺼내는 poll 메서드를 실행하였을 때 지정한 배열에서 가장 먼저 들어간 사과부터 출력된다.


Set

Set내에 저장되는 객체들은 특별한 기준에 맞춰서 정렬되지 않는다. index가 없으므로 순서가 뒤죽박죽으로 출력됨.

저장되는 객체들 간의 중복된 요소가 발생하지 못하도록 내부적으로 관리된다.

→ Set은 입력 순서대로 출력되지 않는다. Set계열은 중복이 불가. 순서가 정해지지 않음

 

Set의 구조

HashSet

기본적인 Set인터페이스를 구현하고 있다.

HashSet은 내부적으로 HashMap을 이용하여 만들어진 것이다.

정렬순서나 반복처리 시 처리순서에 대한 기준은 존재하지 않는다.

 

HashSet에 새로운 요소를 추가할 때 add 메서드나 addAll 메서드를 사용한다.

- HashSet에 이미 저장되어 있는 요소와 중복된 요소를 추가하고자 할 때, 위 메서드들은 false를 반환하여 중복된 요소이므로 추가에 실패했다는 것을 알린다.

 반환형 메서드 설명
boolean add(Object o) 새로운 객체를 저장
void clear() Set에 저장된 모든 객체를 삭제
boolean contains(Object o) 지정된 객체를 포함하고 있는지 알려줌
boolean isEmpty() HashSet이 비어있는지 알려줌, 저장된 요소가 없다면 true 반환
boolean remove(Object o) 지정된 객체를 HashSet에서 삭제
boolean removeAll(Collection c) 주어진 컬렉션에 저장된 모든 객체와 동일한 것들을 HashSet에서 삭제 (차집합)
int size() 현재 Set 구조에 저장된 요소의 수 반환

 

HashSet에서 중복을 필터링하는 원리

1) HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 메소드를 호출하여 해시코드를 얻어낸다.

 

2) 저장되어 있는 객체들의 해시코드와 비교한 후, 동일한 해시코드가 있을 경우 다시 equals() 메서드로 두 객체를 비교하여

true로 반환되면 동일한 객체로 판단하여 중복 저장을 하지 않는다.

문자열을 HashSet에 저장할 경우, 같은 문자열을 갖는 String 객체는 동일한 객체로 간주된다.

다른 문자열을 갖는 String 객체는 다른 객체로 간주된다.

그 이유는 String 클래스가 hashCode()와 equals() 메서드를 재정의하여 같은 문자열일 경우 hashCode()의 return값을 같게, equals()의 return값은 true가 나오도록 하였기 때문이다.

 

String 클래스는 문자열의 내용으로 해시코드를 만들어내기 때문에 문자열의 내용이 서로 같으면 hashCode() 호출은 항상 동일한 해시코드를 반환한다.

반면 Object 클래스는 객체의 주소로 해시코드를 만들어내기 때문에 실행할 때마다 해시코드 값이 달라질 수 있다.

 

 

✍ 입력

package ch11;
import java.util.HashSet;
import java.util.Iterator;

public class Set1 {
	public static void main(String[] args) {
		HashSet<String> set = new HashSet<>();
		set.add("사과"); set.add("포도"); set.add("사과");
		set.add("키위"); set.add("바나나"); set.add("바나나");
		System.out.println("개수 : " + set.size());

		Iterator<String> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		System.out.println("=============");
		for(String str : set) {
			System.out.println(str);
		}
	}
}

💻 출력 

개수 : 4
포도
사과
키위
바나나
=============
포도
사과
키위
바나나

set에 바나나 2번, 사과 2번, 포도와 키위 1번을 저장하였지만 포도,사과,키위,바나나 모두 1개씩만 출력되었다.


✍ 입력

package ch11;
import java.util.HashSet;
public class Set3 {
	public static void main(String[] args) {
		String[] snakes = {"구렁이","팔렁이","구렁이","칠렁이","팔렁이","육렁이"};
		HashSet<String> hs1 = new HashSet<>();
		HashSet<String> hs2 = new HashSet<>();
		for(String snake : snakes) {
			if (!hs1.add(snake)) // hs1에 snake 데이터를 입력하고 에러가 발생하면
				hs2.add(snake); // 입력안된 것만 hs2에 입력한다
		}
//		완료한 후에 출력
		System.out.println(hs1);
		System.out.println(hs2);
		System.out.println();
		hs1.removeAll(hs2); // hs1에서 hs2에 있는 데이터를 모두 제거하라 (차집합)
		System.out.println(hs1);
		System.out.println(hs2);
	}
}

💻 출력 

[육렁이, 팔렁이, 구렁이, 칠렁이]
[팔렁이, 구렁이]

[육렁이, 칠렁이]
[팔렁이, 구렁이]

 

hs1에 이미 들어있어 hs1에 추가할 수 없는 데이터들은 hs2에 추가하였다.

hs1에서 removeAll()을 이용하면 hs1과 hs2에 동일하게 들어있는 데이터들은 제거된다는 것을 알 수 있다.

 

✍ 입력

package ch11;
import java.util.HashSet;
import java.util.Set;
public class Lotto1 {
	public static void main(String[] args) {
		Set<Integer> lotto = new HashSet<>();
		while(lotto.size() < 6) {
			int num = (int)(Math.random()*45) + 1; // 중복을 체크하는 코드를 작성하지 않아도 set에서 중복된 원소를 추가할 수 없도록 방지함
			lotto.add(num); 
		}
		System.out.println(lotto);
	}
}

 

💻 출력 

[17, 18, 5, 37, 26, 14]

!!   Set에서 중복된 값이 출력되는 현상

 

✍ 입력

class SimpleNumber{
    int num;
    public SimpleNumber(int n) {
        num = n;
    }
    public String toString() {
        return String.valueOf(num); // 숫자를 문자열로 반환해주는 valueOf 메서드
    }
}
public class HashSetEqualityOne {
    public static void main(String[] args) {
        HashSet<SimpleNumber> hset = new HashSet<SimpleNumber>();
        hset.add(new SimpleNumber(10));
        hset.add(new SimpleNumber(20));
        hset.add(new SimpleNumber(20));

        System.out.println("저장된 데이터 수: " + hset.size());
        Iterator<SimpleNumber> itr = hset.iterator();
        while(itr.hasNext()) {
            System.out.println(itr.next());
        }
    }
}

💻 출력 

10
20
20

SimpleNumber 클래스에서 equals() 메서드를 따로 오버라이딩하지 않았으므로 객체의 같음을 판단하는 기준을 사용자가 재정의하지 않았기 때문에 Object 클래스의 equals()메서드(주소값 비교)로 인식 후 다른 것으로 판단하여 20이라는 값이 Set이라는 자료구조임에도 불구하고 중복되어 출력된 것이다.

 

HashSet의 add() 메서드는 새로운 요소를 추가하기 전에 기존에 저장된 요소와 같은 것인지 판별하기 위하여 위에 추가하려는 요소의 hashCode()equals()를 호출하므로 hashCode()와 equals()를 목적에 맞게 오버라이딩해야 한다.

 

아래는 SimpleNumber 클래스에서 hashCode()와 equals() 메서드를 재정의하여 같음의 기준을 정하고 실행한 코드이다.

앞의 결과와 달리 아래 소스코드는 중복된 값이 필터링되는 결과가 출력된다.

 

수정한 코드

import java.util.HashSet;
import java.util.Iterator;

class SimpleNumber{
    int num;
    public SimpleNumber(int n) {
        num = n;
    }
    public String toString() {
        return String.valueOf(num); // 숫자를 문자열로 반환해주는 valueOf 메서드
    }

    // hashCode 메서드 오버라이딩.
//     동일한 것을 찾는 검색에서 hashCode 메서드의 결과가 같은 것에 대해 equals로 같은지 확인하여 검색 공간을 줄일 수 있다.
//    hashCode 값이 같은 것끼리 분류해주는 기능
    @Override
    public int hashCode() {
        return num % 3;
    }

    @Override
    public boolean equals(Object obj) { // 두 객체가 같다고 판단하는 기준을 작성
//        새로 만든 클래스의 객체들 사이에 같음의 의미를 규정
//        만들지 않으면 객체들의 주소를 비교하는 Object의 equals 메서드가 그대로 적용됨
//        즉 주소값이 같음으로 같음을 규정. 결국 모든 인스턴스들은 서로 다른 것으로 판단하게 됨.
        SimpleNumber comp = (SimpleNumber)obj;
        if(num == comp.num)
            return true;
        else
            return false;
    }
}
public class HashSetEqualityOne {
    public static void main(String[] args) {
        HashSet<SimpleNumber> hset = new HashSet<SimpleNumber>();
        hset.add(new SimpleNumber(10));
        hset.add(new SimpleNumber(20));
        hset.add(new SimpleNumber(20));

        System.out.println("저장된 데이터 수: " + hset.size());
        Iterator<SimpleNumber> itr = hset.iterator();
        while(itr.hasNext()) {
            System.out.println(itr.next());
        }
    }
}

💻 출력 

저장된 데이터 수: 2
10
20

HashSet에서 중복을 필터링하는 원리에 의하여

HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode()를 호출하여 해시코드를 얻어낸다.

-------------------------------------------------------------------------------------------------------------------------------------------------------

* String 클래스는 문자열의 내용으로 해시코드를 만들어내기 때문에 문자열의 내용이 서로 같으면 hashCode() 호출은 항상 동일한 해시코드를 반환한다.

반면 Object 클래스는 객체의 주소로 해시코드를 만들어내기 때문에 실행할 때마다 해시코드 값이 달라질 수 있다. *

그러므로 SimpleNumber 클래스는 Object 클래스의 자손이기 때문에 중복된 값을 추가하지 않게 하려면 우선 hashCode()를 목적에 맞게 오버라이딩 해주어야 한다.

-------------------------------------------------------------------------------------------------------------------------------------------------------

현재 저장되어 있는 객체들의 해시코드와 비교한 후, 같은 해시코드가 있으면 위 코드에서 재정의한

equals() 메서드로  두 객체를 비교하는 것이다. 

equals() 메서드가 true로 반환될 경우 같은 객체로 인식하여 중복저장을 하지 않아 10, 20만 출력된다.

 


TreeSet

•  이진 검색 트리의 형태로 데이터를 저장하는 컬렉션 클래스

•  중복된 데이터의 저장 허용 x, 정렬된 위치에 저장하므로 저장순서 유지 x

기본적으로 얻어지는 Iterator의 요소들은 오름차순 정렬 상태 유지

•  검색과 정렬에 유리

 

✍ 입력

package ch11;
import java.util.Set;
import java.util.TreeSet;

public class Lotto2 {
	public static void main(String[] args) {
		Set<Integer> lotto = new TreeSet<>();
		while(lotto.size() < 6) {
			int num = (int)(Math.random()*45) + 1;
			lotto.add(num); // 중복을 체크하는 코드를 작성하지 않아도 set에서 중복된 원소를 추가할 수 없도록 방지함
		}
		System.out.println(lotto);
	}

}

 

💻 출력 

[6, 14, 16, 17, 19, 30]

HashSet에서 lotto의 출력 결과는 정렬이 되지 않은 상태로 되어 있었지만 TreeSet을 이용한 lotto의 출력 결과는 오름차순 정렬 상태로 유지된다. 


Map

키(key)와 값(value)을 매핑하는 객체
순서 유지 x, 키(key)는 중복 허용 x, 값은 중복 허용

 

HashMap

Key와 Value를 하나의 데이터로 저장하는 구조

• key는 저장된 값을 찾는데 사용된다. → 컬렉션 내에서 유일해야함.

• HashMap에 저장된 데이터를 하나의 key로 검색하였을 때 결과가 단 하나이어야함.

  → 하나의 key에 대해 여러 결과 값을 얻는다면 원하는 값이 어떤 것인지 알 수 없기 때문

 반환형 메서드 설명
Object get(Object key) 지정된 키(key)의 값(value)을 반환
void clear() HashMap에 저장된 모든 객체를 제거
Set keySet() HashMap에 저장된 모든 키(key)가 저장된 set을 반환
(Map에 저장되고 있는 key들을 set 인터페이스로 반환)
boolean isEmpty() HashMap이 비어있는지 알려줌
Object put(Object key, Object value) 인자로 전달된 키(key)와 값(value)를 HashMap에 저장
Object get(Object Key) 지정된 키(key)의 값(value)을 반환. 못찾으면 null 반환
Object remove(Object key) HashMap에 지정된 키(key)로 저장된 값(value)를 제거
int size() HashMap에 저장된 키(key)와 값(value)으로 매핑된 수를 반환
Collection values() HashMap에 저장된 모든 값을 컬렉션 형태로 반환

 

HashMap에서 중복을 필터링하는 원리

HashMap의 key로 사용할 객체는 hashCode()와 equals() 메서드를 재정의하여 동등한 객체가 될 조건을 정해야 한다.

객체가 다르더라도 동등한 객체라면 같은 key로 간주하고 중복 저장하지 않도록 하기 위해서다.

동등한 객체의 조건: hashCode()의 리턴값이 같아야 한다. equals() 메서드가 true를 리턴해야 한다.

 

HashMap에서 key 타입은 주로 String을 많이 사용한다.String은 문자열이 같으면  동등 객체가 될 수 있도록 hashCode()와 equals() 메서드가 재정의되어 있다.

 

 

✍ 입력

package ch11;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

// 딸기, 달콤하다 / 수박, 시원하다 / 키위, 시큼하다
// hashmap 입력한 후에 set과 iterator 사용하여 출력

public class Map2 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();
		map.put("딸기", "달콤하다"); map.put("수박", "시원하다"); map.put("키위", "시큼하다");
		
		Set<String> keys = map.keySet();
		for(String key : keys) {
			System.out.println(key + " : " + map.get(key));
		}
		System.out.println("============");
		
		Iterator<String> its = map.keySet().iterator();
		while(its.hasNext()) {
			String key = its.next();
			System.out.println(key + " : " + map.get(key));
		}
	}
}

💻 출력 

수박 : 시원하다
키위 : 시큼하다
딸기 : 달콤하다
============
수박 : 시원하다
키위 : 시큼하다
딸기 : 달콤하다

 

TreeMap

• 이전검색트리의 형태로 Key와 Value를 하나의 데이터로 저장하는 구조

 

✍ 입력

import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeMap;

public class IntroTreeMap {
    public static void main(String[] args) {
        TreeMap<Integer, String>  tMap = new TreeMap<Integer, String>();
        tMap.put(1, "data1");
        tMap.put(3, "data3");
        tMap.put(5, "data5");
        tMap.put(2, "data2");
        tMap.put(4, "data4");

        NavigableSet<Integer> navi = tMap.navigableKeySet(); // naviagable 메서드로 key들로 구성된
        // NavigableSet 인터페이스형의 객체생성
        System.out.println("오름차순 출력");
        Iterator<Integer> itr = navi.iterator(); // NavigableSet 객체로부터 key들 사이를 오름차순으로 순회하는 반복자를 생성
        while (itr.hasNext()) {
            System.out.println(tMap.get(itr.next())); // 키들의 오름차순으로 해당 값들을 출력
        }

        System.out.println("내림차순 출력");
        itr = navi.descendingIterator(); // NavigableSet 객체로부터 key들 사이를 내림차순으로 순회하는 반복자를 생성
        while (itr.hasNext()) {
            System.out.println(tMap.get(itr.next())); // 키들의 내림차순으로 해당 값들을 출력
        }
        
    }
}

💻 출력

오름차순 출력
data1
data2
data3
data4
data5
내림차순 출력
data5
data4
data3
data2
data1

 

 

/

5/11

'Back-End > JAVA' 카테고리의 다른 글

[Java] Generic  (0) 2023.03.12
[Java] Arrays 클래스  (0) 2023.03.12
[Java] Object 클래스, equals(), toString()  (2) 2023.03.11
[Java] 클래스 간의 관계 - 포함관계  (0) 2023.03.11
[Java] 상속  (0) 2023.03.11