본문 바로가기
개발/JAVA

자바 - Collection

by chansungs 2020. 6. 14.
728x90
반응형

Collection

package collection;

// 자료구조
// - 컴퓨터 내에서 데이터를 저장하기 위한 구조

// 컬렉션(Collection) == 자료구조
// - 컬렉션은 자바에서 제공해주는 자료구조 클래스의 모음입니다.
//   데이터를 개수의 제약없이 저장할 수 있는 방법을 제공합니다.
//   링크드 리스트, 동적 배열, 셋, 맵, 트리 타입의 다양한 자료구조 
//   클래스들이 제공됩니다.

// - 컬렉션 클래스를 활용하기 위해서는 java.util 패키지를 임포트해야만 합니다.
//   (모든 컬렉션 클래스들은 java.util 패키지에 선언되어 있습니다.) 

import java.util.*;

public class Collection_01 {
	public static void main(String[] args) {
		// java.util.ArrayList 클래스
		// - 동적 배열을 처리할 수 있는 클래스
		// - 일반 배열과 다르게 크기가 동적으로 확장될 수 있는 기능을 제공
		ArrayList list;
		
		// 동적 배열 객체 생성
		list = new ArrayList();
		
		// 데이터 입력
		list.add(10);
		list.add(20);
		list.add(30);
		
		System.out.printf("list[0] -> %d\n", (int)list.get(0));
		System.out.printf("list[1] -> %d\n", (int)list.get(1));
		System.out.printf("list[2] -> %d\n", (int)list.get(2));
		
		System.out.printf("동적 배열내부에 저장된 데이터 개수 -> %d\n", list.size());
		
		for( int i = 0 ; i < 1000000 ; i++ )
			list.add(i * 10);
		
		for( int i = 0 ; i < list.size() ; i++ )
			System.out.printf("list[%d] -> %d\n", i, (int)list.get(i));
		
		System.out.printf("동적 배열내부에 저장된 데이터 개수 -> %d\n", list.size());
	}
}


package collection;

import java.util.*;

public class Collection_02 {
	public static void main(String[] args) {
		// 리스트 구조를 갖는 컬렉션 클래스
		// 1. 순서가 유지
		// 2. 중복을 허용
		
		// 링크드리스트의 구현체
		// - java.util.LinkedList 클래스
		// 동적 배열의 구현체
		// - java.util.ArrayList(싱글 쓰레드 환경), 
		//   java.util.Vector(멀티 쓰레드 환경)
		
		// 선형 자료구조인 링크드 리스트 구조의 객체 생성
		LinkedList linked = new LinkedList();
		
		// 동적 배열의 구조를 갖는 객체 생성
		Vector vector = new Vector();
		ArrayList array = new ArrayList();
		
		// 리스트 구조의 컬렉션 클래스들은
		// 값을 추가하기 위해서 add 메소드를 사용합니다.
		linked.add(10);
		vector.add(20);
		array.add(30);
		
		// 리스트 구조의 컬렉션 클래스들은
		// 값을 참조하기 위해서 get 메소드를 사용합니다.
		// (인덱스 값이 사용됨)
		System.out.println(linked.get(0));
		System.out.println(vector.get(0));
		System.out.println(array.get(0));
		
		// 값의 삽입
		// 리스트 구조의 컬렉션 클래스들이 제공하는
		// add 메소드는 2가지로 오버로딩 되어있습니다.
		// 매개변수가 하나인경우 해당 컬렉션 객체의
		// 마지막 자리에 값을 입력하고,
		// 매개변수가 두개인 경우, 첫번째 매개변수는
		// 값을 입력할 인덱스, 두번째 매개변수는 저장할 값이됩니다.
		// 아래의 코드는 컬렉션 객체의 가장 앞에 데이터를
		// 삽입하는 코드입니다.
		linked.add(0, 40);	// 데이터의 삽입과 삭제에 최적화 된 자료구조 LinkedList 클래스
		vector.add(0, 50);
		array.add(0, 60);
		
		System.out.println(linked.get(0));
		System.out.println(vector.get(0));
		System.out.println(array.get(0));
		
		// 컬렉션 내부에 저장된 데이터의 개수 확인
		// - 리스트 구조의 컬렉션 클래스들은 저장하고 있는 요소의 개수를 반환할 수 있는
		//   size 메소드를 제공합니다.
		System.out.printf("linked 내부에 저장된 데이터 개수 -> %d\n", linked.size());
		System.out.printf("vector 내부에 저장된 데이터 개수 -> %d\n", vector.size());
		System.out.printf("array 내부에 저장된 데이터 개수 -> %d\n", array.size());
		
		// 컬렉션 내부에 저장된 값의 저장 유무를 확인
		// - 모든 리스트 구조의 컬렉션 클래스들은 저장된 데이터에서 값을 검색하기 위한 
		//   contains 메소드를 제공합니다.
		System.out.printf("linked 내부에서 10을 검색한 결과 : %b\n", linked.contains(10));
		System.out.printf("vector 내부에서 10을 검색한 결과 : %b\n", vector.contains(10));
		System.out.printf("array 내부에서 30을 검색한 결과 : %b\n", array.contains(30));
		
	}
}


package collection;

import java.util.*;

public class Collection_03 {
	public static void main(String[] args) {
		// 자바의 모든 컬렉션 클래스들은 데이터의 저장 타입이
		// Object 로 지정되어 있습니다.
		// - 데이터 저장의 타입에 관계없이 저장할 수 있습니다.
		ArrayList array = new ArrayList();
		
		array.add(10);		// Integer 타입을 저장
		array.add(10.751);	// Double 타입을 저장
		array.add("Hello");	// String 타입을 저장
		
		// 기본적으로 Object 타입이 저장되기 때문에
		// 값을 꺼내올때도 Object 타입이 반환됩니다.
		
		// 컬렉션에 저장된 데이터를 get 메소드로
		// 추출할 때, 저장된 타입에 맞춰 형변환을 해야합니다.
		int i = (int)array.get(0);
		double d = (double)array.get(1);
		String s = (String)array.get(2);
		
		// 만약 컬렉션에 입력된 타입과 다른 타입으로
		// 형변환을 하게 되면 런타임 에러가 발생하여
		// 프로그램이 종료됩니다.
		// 아래의 코드는 Double 타입을 String 타입으로
		// 형변환하여 런타임 에러가 발생됩니다.
		// s = (String)array.get(1);
		
		// 제네릭 문법
		// 컬렉션 클래스에 저장할 타입을 지정하여
		// 데이터를 저장하는 문법
		// 하나의 클래스를 다양한 타입에 맞춰 사용할 수 있도록
		// 지원하는 문법
		
		// JDK 1.5 이후부터 모든 컬렉션 클래스들은
		// 제네릭 문법을 지원하고 있습니다.
		
		// ArrayList<저장할타입> list_s = new ArrayList<저장할타입>();
		ArrayList<Integer> list1 = new ArrayList<Integer>(); 
		
		// 제네릭을 적용한 컬렉션 객체는 
		// 지정한 타입을 저장할 수 있습니다.
		list1.add(10);
		// list1.add("Hello");
		
		// 제네릭을 적용한 컬렉션 객체는 
		// 지정한 타입의 값을 반환받을 수 있습니다.
		// (형변환 필요 X)
		int num = list1.get(0);
		
		ArrayList<String> list2 = new ArrayList<String>(); 
	}
}

package collection;

import java.util.*;

class Student04 {
	private String name;
	public Student04(String name) {
		this.name = name;
	}
	public String toString() {
		return String.format("학생의 이름은 '%s' 입니다.", this.name);
	}
}
public class Collection_04 {
	public static void main(String[] args) {
		// 컬렉션 클래스에는 사용자가 직접 정의한 클래스의
		// 객체를 저장할 수 있습니다.
		ArrayList<Student04> array = new ArrayList<Student04>();
		array.add(new Student04("홍길동"));
		array.add(new Student04("이순신"));
		array.add(new Student04("유관순"));
		
		for( int i = 0 ; i < array.size() ; i++ )
			// Student04 클래스에서 오버라이딩한 toString 메소드가 호출
			System.out.println(array.get(i));
		
		// 특정 인덱스의 값을 삭제
		// - remove 메소드
		System.out.println("=======================");
		array.remove(0);
		for( int i = 0 ; i < array.size() ; i++ )
			// Student04 클래스에서 오버라이딩한 toString 메소드가 호출
			System.out.println(array.get(i));
		
		// 전체 데이터 삭제
		System.out.println("=======================");
		array.clear();
		System.out.printf("array 내부에 저장된 데이터 개수 -> %d\n", array.size());
	}
}


 

 

package collection;

import java.util.*;

class Student05 {
	private String name;
	public Student05(String name) {
		this.name = name;
	}
	public String toString() {
		return String.format("학생의 이름은 '%s' 입니다.", this.name);
	}
	public boolean equals(Object obj) {
		System.out.printf("equals 실행 - %s\n", this.name);
		return super.equals(obj);
	}
}
public class Collection_05 {
	public static void main(String[] args) {
		// 컬렉션 클래스에는 사용자가 직접 정의한 클래스의
		// 객체를 저장할 수 있습니다.
		ArrayList<Student05> array = new ArrayList<Student05>();
		array.add(new Student05("홍길동"));
		array.add(new Student05("이순신"));
		array.add(new Student05("유관순"));
		
		// 컬렉션 클래스의 contains 메소드는
		// 내부에 저장된 객체들 중 매개변수에 전달된 
		// 객체와 동일한 객체를 찾는 역할을 합니다.
		
		// 이때 컬렉션 내부에 저장된 모든 객체들에 대해서
		// equals 메소드를 호출하여 동일한 객체임을 확인하는
		// 과정을 거칩니다.
		
		// 만약 사용자 정의 클래스에서 equals 메소드를 오버라이딩
		// 하지않으면 레퍼런스 비교만을 하기 때문에
		// 동일한 형태의 객체를 검색할 수 없습니다.
		System.out.println(
				array.contains(new Student05("이순신")));
		
		// 컬렉션 내부에서 사용자 정의 클래스의 객체를
		// 삭제하는 경우에도 equals 메소드를 오버라이딩해야만
		// 올바르게 삭제됩니다.
		// 아래는 동일한 객체를 검색할 수 없어서 
		// 삭제가 이뤄지지 않습니다.
		array.remove(new Student05("이순신"));
		System.out.printf("array 내부에 저장된 데이터 개수 -> %d\n", array.size());
	}
}


package collection;

import java.util.*;

class Student06 {
	private String name;
	public Student06(String name) {
		this.name = name;
	}
	public String toString() {
		return String.format("학생의 이름은 '%s' 입니다.", this.name);
	}
	// 컬렉션 내부에서 동일한 객체임을 검증하기 위한
	// equals 메소드 오버라이딩 구현
	public boolean equals(Object obj) {
		// 0. 형변환이 가능한 객체인지 검증
		if( !(obj instanceof Student06) )
			return false;
		
		// 1. 객체 형변환을 처리
		Student06 s = (Student06)obj;
		
		// 2. 동일한 객체 여부를 판단
		boolean flag = this.name.equals(s.name);
		
		// 3. 판단 결과를 반환
		return flag;
	}
}
public class Collection_06 {
	public static void main(String[] args) {
		// 컬렉션 클래스에는 사용자가 직접 정의한 클래스의
		// 객체를 저장할 수 있습니다.
		ArrayList<Student06> array = new ArrayList<Student06>();
		array.add(new Student06("홍길동"));
		array.add(new Student06("이순신"));
		array.add(new Student06("유관순"));
		System.out.printf("array 내부에 저장된 데이터 개수 -> %d\n", array.size());
		
		// 컬렉션 클래스의 contains 메소드는
		// 내부에 저장된 객체들 중 매개변수에 전달된 
		// 객체와 동일한 객체를 찾는 역할을 합니다.
		
		// 이때 컬렉션 내부에 저장된 모든 객체들에 대해서
		// equals 메소드를 호출하여 동일한 객체임을 확인하는
		// 과정을 거칩니다.
		
		// 만약 사용자 정의 클래스에서 equals 메소드를 오버라이딩
		// 하지않으면 레퍼런스 비교만을 하기 때문에
		// 동일한 형태의 객체를 검색할 수 없습니다.
		System.out.println(
				array.contains(new Student06("이순신")));
		
		// 컬렉션 내부에서 사용자 정의 클래스의 객체를
		// 삭제하는 경우에도 equals 메소드를 오버라이딩해야만
		// 올바르게 삭제됩니다.
		// 아래는 동일한 객체를 검색할 수 없어서 
		// 삭제가 이뤄지지 않습니다.
		array.remove(new Student06("이순신"));
		array.remove(new Student06("홍길동"));
		System.out.printf("array 내부에 저장된 데이터 개수 -> %d\n", array.size());
	}
}


package collection;

import java.util.*;

public class Collection_07 {
	public static void main(String[] args) {
		// Set 타입의 컬렉션 클래스
		// - HashSet, TreeSet
		// 1. 데이터의 중복을 허용하지 않습니다.
		//    (사용자 정의 자료형은 반드시 equals 메소드를 
		//     오버라이딩 해야만 중복이 허용되지 않습니다.)
		// 2. 입력 순서가 유지되지 않습니다.
		
		HashSet<String> set = new HashSet<>();
		
		// 데이터 저장
		set.add("One");
		set.add("Two");
		set.add("Three");
		set.add("Four");
		set.add("Five");
		
		// HashSet 타입은 데이터의 저장 순서를 유지하지 않아
		// 인덱스를 사용할 수 없습니다.
		// get 메소드가 지원되지 않습니다.
		// System.out.println(set.get(0));
		
		// HashSet 타입에 저장된 데이터를 순회하는 방법
		
		// 1. 개선된 for 반복문을 사용하여 데이터를 순회
		// set 컬렉션으로부터 데이터를 하나씩 꺼내어서
		// String s 변수에 대입한 후 for 반복문의 실행코드를 수행합니다.
		// 모든 데이터를 한번씩 실행할때까지
		for( String s : set ) {
			System.out.println(s);
		}
		
		System.out.println("=========");
		
		// 동일한 값을 입력되지 않습니다.
		// (데이터 중복 불가)
		set.add("Four");
		set.add("Five");
		
		for( String s : set ) {
			System.out.println(s);
		}
		
		// 데이터 개수 확인
		System.out.printf("set 내부에 저장된 데이터의 개수 : %d 개\n", set.size());
		
		System.out.println("=========");
		
		// 2. Iterator를 사용한 데이터 순회 방법
		// set 내부의 데이터들을 순회할 수 있는 Iterator 객체를 추출
		Iterator<String> iter = set.iterator();
		while(iter.hasNext()) {
			// Iterator의 next 메소드를 사용하여
			// 다음 데이터로 이동한 후, 값을 추출
			String s = iter.next();
			System.out.println(s);
		}
	}
}


package collection;

import java.util.*;

public class Collection_08 {
	public static void main(String[] args) {
		// Set 타입을 활용한 로또번호 생성 예제
		// - Set 타입의 특징인 중복이 제거되는 현상
		
		// 6개의 중복되지 않는 로또번호를 저장할 Set 객체
		HashSet<Integer> lotto = new HashSet<>();
		
		// 임의의 로또 번호를 생성하기 위한 Random 객체
		Random random = new Random();
		
		while( lotto.size() < 6 ) {
			// 임의의 숫자를 추출
			int number = random.nextInt(45) + 1;
			// 추출된 숫자를 컬렉션에 저장
			// - 동일한 숫자는 입력되지 않음
			lotto.add(number);
		}
		
		System.out.println("로또번호 생성 완료");
		for( int n : lotto )
			System.out.printf("%d ", n);
		System.out.println();
		
		// Set 타입의 데이터를 정렬하여 출력하는 예제
		// 1. set 타입을 List 타입으로 변환
		// - ArrayList, Vector의 생성자 매개변수로 Set 객체를 전달
		List<Integer> lottoList = new ArrayList<>(lotto);
		// 2. Collections 가 제공하는 sort 메소드를 사용하여
		//    리스트 타입의 객체를 정렬
		Collections.sort(lottoList);
		// - 리스트를 정렬한 이후에 reverse 메소드를 호출하면
		//   내림차순으로 정렬됩니다.
		// Collections.reverse(lottoList);
		
		for( int n : lottoList )
			System.out.printf("%d ", n);
		System.out.println();
	}
}


package collection;

import java.util.*;

public class Collection_09 {
	public static void main(String[] args) {
		// Map 타입의 컬렉션 클래스
		// 1. 키와 밸류의 쌍으로 데이터를 입력
		//    (제네릭을 구현할 때, 키와 밸류의 타입을
		//     각각 기술합니다.)
		// 2. 키의 중복을 허용하지 않습니다.
		//    (밸류의 데이터는 중복을 허용합니다.)
		// - Hashtable(멀티쓰레드 환경), HashMap(싱글쓰레드 환경) 클래스가 제공됩니다.
		
		// String 을 키 값으로하고 Integer 타입을 밸류로 사용하는
		// HashMap 객체를 생성
		HashMap<String, Integer> map = new HashMap<>();
		
		// Map 타입의 컬렉션은 put 메소드를 사용하여
		// 데이터를 저장합니다.
		map.put("One", 1);
		map.put("Two", 2);
		map.put("Three", 3);
		
		System.out.printf("map에 저장된 데이터의 개수 : %d 개\n", map.size());
		
		// 동일한 키를 사용하여 데이터를 입력
		// - 키값의 중복을 허용하지 않기 때문에
		//   아래의 put 메소드는 데이터가 추가되지 않습니다.
		map.put("One", 1);
		map.put("Two", 2);
		map.put("Three", 3);
		
		// - 아래의 put 메소드는 새로운 키가 입력되었기 때문에
		//   데이터가 추가됩니다.
		map.put("Four", 4);
		map.put("Five", 5);
		
		System.out.printf("map에 저장된 데이터의 개수 : %d 개\n", map.size());
		
		// Map 타입의 컬렉션은 get 메소드를 사용하여
		// 특정 키 값의 데이터를 추출합니다.
		System.out.printf("One : %d\n", map.get("One"));
		System.out.printf("Five : %d\n", map.get("Five"));
		System.out.println("==============");
		
		// Map 컬렉션에 저장된 데이터를 순회하는 방법
		// 1. 모든 키 값이 저장된 Set 객체를 반환받음
		Set<String> keys = map.keySet();
		
		// 2. 키 값을 순회하면서 각각의 키값을
		//    Map 객체의 get 메소드에 전달하여
		//    해당 키 값의 밸류를 추출할 수 있음
		for( String key : keys ) {
			int value = map.get(key);
			System.out.printf("%s -> %d\n", key, value);
		}
	}
}


package collection;

import java.util.*;

public class Collection_10 {
	public static void main(String[] args) {
		// Map 타입의 컬렉션 클래스
		// 1. 키와 밸류의 쌍으로 데이터를 입력
		//    (제네릭을 구현할 때, 키와 밸류의 타입을
		//     각각 기술합니다.)
		// 2. 키의 중복을 허용하지 않습니다.
		//    (밸류의 데이터는 중복을 허용합니다.)
		// - Hashtable(멀티쓰레드 환경), HashMap(싱글쓰레드 환경) 클래스가 제공됩니다.
		
		// String 을 키 값으로하고 Integer 타입을 밸류로 사용하는
		// HashMap 객체를 생성
		HashMap<String, Integer> map = new HashMap<>();
		
		// Map 타입의 컬렉션은 put 메소드를 사용하여
		// 데이터를 저장합니다.
		map.put("One", 1);
		map.put("Two", 2);
		map.put("Three", 3);
		
		System.out.printf("map에 저장된 데이터의 개수 : %d 개\n", map.size());
		
		// Map 컬렉션 객체 내부의 키 값을 검색하는 방법
		// containsKey 메소드를 사용하여
		// 특정 키 값이 존재하는지 여부를 검색할 수 있음
		boolean flag = map.containsKey("One");
		System.out.printf("One -> %b\n", flag);
		
		flag = map.containsKey("Four");
		System.out.printf("Four -> %b\n", flag);
		
		// Map 컬렉션 객체는 키 값의 중복을 허용하지 않습니다.
		map.put("Two", 2);
		System.out.printf("map에 저장된 데이터의 개수 : %d 개\n", map.size());
				
		// 하지만, 밸류의 중복은 허용합니다.
		map.put("Four", 1);
		System.out.printf("map에 저장된 데이터의 개수 : %d 개\n", map.size());
		
		System.out.println("=================");
		for( String key : map.keySet() ) {
			int value = map.get(key);
			System.out.printf("%s -> %d\n", key, value);
		}
		
		System.out.println("=================");
		// 동일한 키 값이 Map 객체에 저장(put)되는 경우
		// 데이터가 추가되지 않습니다.
		// 하지만, 해당 키 값이 가지고 있는 밸류는
		// 새롭게 입력된 데이터로 수정(교체)됩니다.
		map.put("Three", 11);
		System.out.printf("map에 저장된 데이터의 개수 : %d 개\n", map.size());
		
		for( String key : map.keySet() ) {
			int value = map.get(key);
			System.out.printf("%s -> %d\n", key, value);
		}
	}
}

728x90
반응형