Set
- 순서를 유지하지 않음
- 중복을 유지하지 않음
- null은 하나만 등록 가능
- 구현 클래스 HashSet, LinkedHashSet, TreeSet

HashSet
- Set인터페이스 구현 클래스
- 순서를 유지하지 않음, 중복을 허용하지 않음.

LinkedHashSet
- HashSet 하위 클래스
- 중복 허용하지 않음
- 순서 유지

TreeSet
- SortedSet 인터페이스 구현
- 정렬된 순서에 의해 반복
- 중복 허용 안함
- Comparable 인터페이스 구현 클래스만 추가 가능

List
- 순서가 있다.
- 배열과 유사한 구조
- 가변 길이(저장 공간이 부족하면 자동으로 공간이 늘어남)
- 중복적인 요소도 추가 가능
- 중간에 데이터를 추가하거나 삭제도 가능
- 주요 구현 클래스 - ArrayList, Vector, LinkedList, Stack 등...

ArrayList
- List 인터페이스 구현 클래스
- 검색시 속도가 빠름
- 동기화 되지 않음.

LinkedList
- List 인터페이스 구현 클래스
- 검색은 느림
- 앞에서 추가하고 뒤에서 삭제가 빈번한 경우 빠름
- 중간에 삽입시 속도 현저히 떨어짐
- 동기화 되지 않음

Vector
- List 인터페이스 구현 클래스
- 동기화 지원, 다중 스레드 환경에서 안전

배열과 ArrayList의 차이점
- 배열 
 : 배열 요소의 크기를 변경할 수 없다.
 : 배열 중간에 데이터를 삽입 시에 기존 데이터를 덮어쓰기 때문에 기존의 데이터값은 사라진다.

- ArrayList
 : 가변길이의 자료구조로 데이터의 검색에 유리하며, 추가/삭제에는 성능을 고려 해야 한다.
 : 리스트의 처음, 끝, 중간에 요소를 추가/삭제하는 기능을 제공한다.
 

'쌍용강북교육센터 > 8월' 카테고리의 다른 글

0805_Oracle : 단일행함수  (1) 2021.08.05
0803_Oracle : SQL  (1) 2021.08.04
0804_Oracle : SQL  (1) 2021.08.04
0802_Ex03~Ex05_Map : 맵  (2) 2021.08.03
0802_Ex01~Ex02_Sort  (1) 2021.08.03
package ex0802;

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

/*
 - Map
 	: 키와 값 구조
 	: 키는 중복을 허용하지 않음
 	: 키는 순서가 없음
 	: 반복자가 없음(키는 반복자가 존재)
 - Map 구현 클래스
 	: HashMap - 동기화 지원하지 않음
 	: Hashtable - 동기화 지원
 	: TreeMap - 키 순서로 정렬. 키는 Comparable 인터페이스가 구현되어 있어야 함.
 */
public class Ex03_Map {
	public static void main(String[] args) {
		// 키, 값
		Map<String, Integer> map = new HashMap<String, Integer>();
		
		// map에 값 저장
		map.put("서울", 1000);
		map.put("부산", 350);
		map.put("대구", 250);
		map.put("인천", 350);
		map.put("광주", 150);
		map.put("대전", 150);
		map.put("울산", 110);
		map.put("세종", 20);
		map.put("서울", 980); // 동일한 키는 기존 값을 덮어씀
		System.out.println(map);
		
		// map에서 값 가져오기
		int n = map.get("서울");
		System.out.println(n);
		
		boolean b = map.containsKey("서울");
		System.out.println("키에 서울이 존재합니까 ? " + b);
		b = map.containsValue(350);
		System.out.println("값으로 350이 존재합니까 ? "+ b);
		
		System.out.println("map의 전체 데이터 개수 : " + map.size());
		
		map.remove("세종"); // 키가 세종인 데이터 삭제
		System.out.println(map);
		
		// Map은 Iterator가 존재하지 않음. 향상된 for 문도 사용 불가
		// 키는 처음부터 끝까지 순회가능(Iterator가 존재)
		Set<String> keySet = map.keySet(); // 키에서 Set 객체를 반환
		Iterator<String> it = keySet.iterator();
		while(it.hasNext()) {
			String key = it.next();
			Integer value = map.get(key);
			System.out.println(key + " -> " + value);
		}
		
	}
}

 

package ex0802;

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

public class Ex04_Map {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();

		map.put("자바", 80);
		map.put("오라클", 90);
		map.put("빅데이터", 100);
		map.put("서블릿", 60);
		map.put("스프링", 80);

		// map의 키를 Set으로 가져오기
		System.out.println("map의 키를 Set으로 가져오기");
		Set<String> set = map.keySet();
		System.out.println(set);

		System.out.println("map의 값을 List로 가져오기");
		List<Integer> list = new LinkedList<Integer>(map.values());
		System.out.println(list);

		System.out.println("\nmap 전체 리스트 -1");
		Iterator<String> it = map.keySet().iterator();
		while (it.hasNext()) {
			String key = it.next();
			int value = map.get(key);
			System.out.println(key + " -> " + value);
		}

		System.out.println("\nmap 전체 리스트 -2");
		for (String key : map.keySet()) {
			int value = map.get(key);
			System.out.println(key + " -> " + value);
		}
		
		
		
	}

}

package ex0802;

import java.util.Map;
import java.util.TreeMap;

public class Ex05_Map {

	public static void main(String[] args) {
		// TreeMap : 키로 정렬하여 저장. 키는 Comparable 인터페이스가 구현되어 있어야 함.
		// Comparable 인터페이스 : 정렬의 기준
		// Map<String, Integer> map = new TreeMap<>();
		TreeMap<String, Integer> map = new TreeMap<>();
		map.put("서울", 1000);
		map.put("부산", 350);
		map.put("대구", 250);
		map.put("인천", 350);
		map.put("광주", 150);
		map.put("대전", 150);
		map.put("울산", 110);
		map.put("세종", 20);
		
		System.out.println(map);
		
		Map<String, Integer> subMap = map.subMap("대전", "세종");
		System.out.println(subMap); // 대전에서 세종 전까지 추출
	}

}

 

'쌍용강북교육센터 > 8월' 카테고리의 다른 글

0805_Oracle : 단일행함수  (1) 2021.08.05
0803_Oracle : SQL  (1) 2021.08.04
0804_Oracle : SQL  (1) 2021.08.04
0802_Collections  (1) 2021.08.03
0802_Ex01~Ex02_Sort  (1) 2021.08.03

ArrayList

  • List 인터페이스 구현 클래스
  • 검색시 속도가 빠름
  • 동기화 되지 않음

Collections.sort(list); 정렬메소드는 Comparable을 구현한 클래스만 가능하다.

package ex0802;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Ex01_Sort {
	public static void main(String[] args) {
		List<UserVO> list = new ArrayList<UserVO>();
		list.add(new UserVO("너자바", "010-1111-1111", 23));
		list.add(new UserVO("홍길동", "010-2222-1111", 20));
		list.add(new UserVO("스프링", "010-1111-3333", 25));
		list.add(new UserVO("김자바", "010-1313-1111", 23));
		list.add(new UserVO("나나나", "010-1111-1515", 20));

		print("정렬 전...", list);

		// 정렬 : Comparable를 구현한 클래스만 가능 
		Collections.sort(list);
		print("정렬 후...", list);

	}

	public static void print(String title, List<UserVO> list) {
		System.out.println(title);
		for (UserVO vo : list) {
			System.out.print(vo.getName() + "\t");
			System.out.print(vo.getTel() + "\t");
			System.out.print(vo.getAge() + "\n");
		}
		System.out.println();
	}

}

class UserVO implements Comparable<UserVO> { // 정렬의 기준점을 만들어주어야 정렬할 수 있다.
	private String name;
	private String tel;
	private int age;

	public UserVO() {

	}

	public UserVO(String name, String tel, int age) {
		this.name = name;
		this.tel = tel;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	// compareTo : Comparable 인터페이스 메소드로 정렬할 때 정렬할 기준(방법)을 설정
	@Override
	public int compareTo(UserVO o) {
		// 이름 오름차순 : String capareTo() 메소드로 문자열을 비교
		// return name.compareTo(o.getName());
		
		// return -name.compareTo(o.getName()); // 이름 내림차순
		
		return age - o.getAge(); // 나이 오름 차순 
		
	}
}

 

package ex0802;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Ex02_Sort {
	public static void main(String[] args) {
		List<UserDTO> list = new ArrayList<UserDTO>();
		list.add(new UserDTO("나너노", "010-1111-2222", 25));
		list.add(new UserDTO("가나다", "010-3333-2222", 20));
		list.add(new UserDTO("호호호", "010-1111-4545", 23));
		list.add(new UserDTO("가도도", "010-1212-2222", 27));
		list.add(new UserDTO("마마마", "010-1111-5241", 23));
		
		print("정렬 전...", list);
		// Comparator 인터페이스 구현 : 정렬 기준 설정(이름 오름차순)
		Comparator<UserDTO> comp = new Comparator<UserDTO>() {
			@Override
			public int compare(UserDTO o1, UserDTO o2) {
				return o1.getName().compareTo(o2.getName());
			}
		};
		Collections.sort(list, comp);
		
		print("이름 오름차순...", list);
		
		// Comparator 인터페이스 구현 : 정렬 기준 설정(나이 오름차순)
		Comparator<UserDTO> comp2 = new Comparator<UserDTO>() {
			@Override
			public int compare(UserDTO o1, UserDTO o2) {
				return o1.getAge() - o2.getAge(); // 양수이면 swap
			}
		};
		Collections.sort(list, comp2);
			
		print("나이 오름차순...", list);

	}
	
	public static void print(String title, List<UserDTO> list) {
		System.out.println(title);
		for(UserDTO dto : list)	{
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getTel()+"\t");
			System.out.print(dto.getAge()+"\n");
		}
		System.out.println();
	}
}

class UserDTO {
	private String name;
	private String tel;
	private int age;

	public UserDTO() {
		
	}
	
	public UserDTO(String name, String tel, int age) {
		this.name = name;
		this.tel = tel;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

 

'쌍용강북교육센터 > 8월' 카테고리의 다른 글

0805_Oracle : 단일행함수  (1) 2021.08.05
0803_Oracle : SQL  (1) 2021.08.04
0804_Oracle : SQL  (1) 2021.08.04
0802_Collections  (1) 2021.08.03
0802_Ex03~Ex05_Map : 맵  (2) 2021.08.03
package ex0730;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/*
  ArrayList
    : List 인터페이스 구현 클래스
    : 검색시 속도가 빠름
    : 동기화 되지 않음(멀티 스레드에서 안전하지 않음)
  LinkedList
    : List 인터페이스 구현 클래스
    : 검색은 느림
    : 앞에서 추가하고 뒤에서 삭제가 빈번한 경우 빠름
    : 앞뒤 아무데서나 추가 삭제 가 빈번한 경우 
    : 중간에 삽입 삭제시에는 속도가 현저히 떨어짐. LinkedList 사용하지 말 것.
    : 동기화 되지 않음(멀티 스레드에서 안전하지 않음)
 */
public class Ex01_List {
	public static void main(String[] args) {
		List<String> list1 = new ArrayList<>();
		list1.add("자바");
		list1.add("오라클");
		list1.add("서블릿");
		System.out.println("ArrayList...");
		print(list1);
		
		List<String> list2 = new LinkedList<String>();
		list2.add("서울");
		list2.add("부산");
		list2.add("대구");
		System.out.println("\nLinkedList...");
		print(list2);
		
	}
	
	public static void print(List<String> list) {
		for(String s : list) {
			System.out.print(s +"  ");
		}
		System.out.println();
	}
}

2021.07.30 - [쌍용강북교육센터/7월] - Q 0729_Ex001~Ex002_List

 

Q 0729_Ex001~Ex002_List

package ex0729; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /* - List 인터페이스 : 순서가 있다. : 배열과 유사한 구조 : 가변 길이(저장..

development-writing.tistory.com

내가 여기에서 왜 업캐스팅을 하지? 하고 오늘 수업할 때 선생님께 질문했더니, 예제를 통해 그 이유를 알려주셨다.

업캐스팅을 안했으면 ArrayList 와 LinkedList 두 개를 선언하고 print() 메소드를 정의할 때,  매개변수에 

public static void print(ArrayList<String> list1)

public static void print(LinkedList<String> list2) 이렇게 해야 되서, 업캐스팅해서 한 번만 적으면 코드가 짧아진다.


package ex0730;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Ex02_List {
	public static void main(String[] args) {
		ArrayList<String> list1 = new ArrayList<>();
		LinkedList<String> list2 = new LinkedList<>();
		
		timeTest1("LinkedList", list2);
		timeTest1("ArrayList", list1); // 앞줄과 순서를 바꿔보면 시간 차이가 보임
		System.out.println("-------------------------------");
		
		timeTest2("LinkedList", list2);
		timeTest2("ArrayList", list1);
	}
	
	public static void timeTest1(String cls, List<String> list) {
		long s, e;
		
		s = System.nanoTime();
		for(int i=0; i<20000; i++) {
			list.add( String.valueOf(i) );
				// 가장 뒤에 추가하는 경우 실행 순서에 따라 차이가 있으나 ArrayList가 빠름
		}
		e = System.nanoTime();
		
		System.out.printf("%s, 시간:%,d\n", cls, (e-s));
		
		list.clear();
	}

	public static void timeTest2(String cls, List<String> list) {
		long s, e;
		
		s = System.nanoTime();
		for(int i=0; i<20000; i++) {
			list.add( 0, String.valueOf(i) ); // 앞 추가 삭제시 LinkedList 가 빠름
		}
		e = System.nanoTime();
		
		System.out.printf("%s, 시간:%,d\n", cls, (e-s));
		
		list.clear();
	}
}

이것은 ArrayList와 LinkedList 검색 시 걸리는 시간을 비교해본 것이다. 

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

Q 0729_Ex001~Ex002_List  (0) 2021.07.30
0729_Ex06~Ex09_system : Java API  (0) 2021.07.29
0729_ConsoleEx_콘솔 입력  (0) 2021.07.29
0729_Ex01~Ex05_Generic  (0) 2021.07.29
0728_Ex11~Ex17_generic : 제네릭  (0) 2021.07.29
package ex0729;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
 - List 인터페이스
 	: 순서가 있다.
 	: 배열과 유사한 구조
 	: 가변 길이(저장 공간이 부족하면 자동으로 공간이 늘어남)
 	: 중복적인 요소도 추가 가능
 	: 중간에 데이터를 추가하거나 삭제도 가능
 	: 주요 구현 클래스 - ArrayList, Vector, LinkedList, Stack 등..
 	: 동기화 지원 : Vector - 다중 스레드 환경에서 안전
 	: 동기화 지원 안함 : AraayList, LinkedList - 다중 스레드 환경에서 안전하지 않음(속도 빠름)
 */
public class Ex001_List {
	public static void main(String[] args) {

		List<String> list = new ArrayList<String>(); // up casting
		String s;

		// 마지막에 요소 추가
		list.add("서울");
		list.add("부산");
		list.add("인천");
		list.add("광주");
		list.add("서울"); // 요소의 중복 가능
		list.add("대전");

		System.out.println(list);

		// 2인덱스에 데이터 추가
		list.add(2, "대구");
		System.out.println(list);

		// 데이터 개수 ?
		System.out.println("개수 : " + list.size());

		// 처음 데이터
		s = list.get(0);
		System.out.println("처음 : " + s);

		// 두번째
		s = list.get(1);
		System.out.println("두번째 : " + s);

		// 마지막
		s = list.get(list.size() - 1);
		System.out.println("마지막 : " + s);

		// 처음에 한국 추가
		list.add(0, "한국");
		System.out.println(list);

		// 처음의 데이터를 대한민국으로 수정
		list.set(0, "대한민국");
		System.out.println(list);

		int idx;
		// 인천은 몇 번째 인덱스에 ?
		idx = list.indexOf("인천");
		System.out.println("인천 인덱스 : " + idx);

		idx = list.indexOf("세종"); // 없으면 -1
		System.out.println("세종 인덱스 : " + idx);

		idx = list.indexOf("서울");
		System.out.println("서울(처음부터 검색) : " + idx);

		idx = list.lastIndexOf("서울");
		System.out.println("서울(뒤부터 검색) : " + idx);

		// 부산 존재 여부
		System.out.println("부산이 존재합니까 ? " + list.contains("부산"));

		// 대한민국 삭제
		// list.remove("대한민국");
		list.remove(0);
		System.out.println(list);

		System.out.println("전체 출력 - 1");
		for (int i = 0; i < list.size(); i++) {
			System.out.print(list.get(i) + "  ");
		}
		System.out.println();

		System.out.println("전체 출력 - 2");
		for (String str : list) {
			System.out.print(str + "  ");
		}
		System.out.println();

		System.out.println("전체 출력 - 3");
		// 반복자. 순방향만 가능
		Iterator<String> it = list.iterator(); // 하나씩 데이터를 꺼낸다.
		while (it.hasNext()) { // 데이터가 존재하면 true, 없으면 false
			String str = it.next(); // 있는 곳의 데이터를 돌려주고 다음으로 간다.
			System.out.print(str + "  ");
		}
		System.out.println();

		System.out.println("역순 - 1");
		for (int i = list.size() - 1; i >= 0; i--) {
			System.out.print(list.get(i) + "  ");
		}
		System.out.println();

		System.out.println("역순 - 2");
		// ListIterator : 순방향과 역방향 모두 이동 가능
		// 반복자의 위치를 가장 마지막으로 이동
		ListIterator<String> it2 = list.listIterator(list.size());
		while (it2.hasPrevious()) {
			String str = it2.previous();
			System.out.print(str + "  ");
		}
		System.out.println();

		// 모두 지우기
		list.clear();
		System.out.println("모두 삭제 후 개수 : " + list.size());

	}
}

List 인터페이스

  • 순서가 있는 컬렉션
  • 목록에서 각 요소가 삽입되는 위치를 제어 할 수 있다.
  • 요소를 인덱스로 관리하며, 인덱스로 요소를 검색하거나 삭제 할 수 있다.
  • 동일한 요소(객체)를 중복해서 저장할 수 있다.
  • List 컬렉션은 객체 자체가 저장되는 것이 아니라 객체의 번지를 참조한다.
  • null도 저장이 가능하며, null을 저장한 경우에는 해당 인덱스는 객체를 참조하지 않는다.
  • 배열과 유사한 구조
  • 가변 길이로 저장 공간이 부족하면 자동으로 공간이 늘어난다.

 

List를 하기 위해서 제네릭을 배운 것!

List<String> list = new ArrayList<String>(); 

String인 자료형을 저장할 리스트를 생성

add 메소드로 요소를 추가 할 수 있다.

size 메소드로 리스트의 크기를 알 수 있다.

set 메소드로 원하는 위치에 리스트를 변경 할 수 있다.

contains 메소드로 리스트에서 검색 후 boolean으로 반환해준다.

package ex0729;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Ex002_List {

	public static void main(String[] args) {
		List<String> list1 = new ArrayList<String>();
		list1.add("서울");
		list1.add("부산");
		list1.add("대구");

		List<String> list2 = new ArrayList<String>();
		list2.add("강원");
		list2.add("경기");
		list2.add("경상");

		// list2에 list1의 모든 데이터를 추가
		list2.addAll(list1);
		System.out.println(list2);

		// List<String> => String[]
		String[] ss = list2.toArray(new String[list2.size()]);
		System.out.println("리스트를 배열로 복사...");
		for (String s : ss) {
			System.out.print(s + "  ");
		}
		System.out.println();

		// String[] => List<String>
		List<String> list3 = Arrays.asList(ss);
		System.out.println("배열을 리스트로 복사 후 : " + list3);

		// subList(a, b) : a인덱스에서 b-1인덱스까지의 부분 List
		List<String> list4 = list3.subList(1, 4);
		System.out.println(list4); // [경기, 경상, 서울]

		// 전체 삭제
		list1.clear();
		System.out.println("전체 삭제 후 : " + list1.size());

		// list2의 데이터중 [경상, 서울, 부산] 삭제
		System.out.println("삭제 전 : " + list2);
		list2.subList(2, 5).clear();
		
		System.out.println("삭제 후 : " + list2);
		
		
	}

}

list의 메소드를 익히고 적절하게 사용해보도록 하자!

 

배열과 ArrayList

  • 배열은 한 번 크기가 결정되면 배열의 크기를 변경할 수 없다.
  • 배열의 처음이나 중간에 데이터를 삽입하는 경우, 기존 데이터가 존재하면 데이터를 덮어쓰기 때문에 기존 데이터는 사라진다.
  • ArrayList는 가변 길이의 자료구조로 데이터의 검색에 유리하며, 추가 또는 삭제에는 성능을 고려해야 한다.
  • 리스트의 처음, 끝, 중간에 자료를 추가 또는 삭제하는 기능을 제공한다.

근데 왜 

List<String> list = new Arraylist<>(); 이렇게 업 캐스팅 하는 건쥐..?

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0730_Ex01~Ex02_List  (0) 2021.07.30
0729_Ex06~Ex09_system : Java API  (0) 2021.07.29
0729_ConsoleEx_콘솔 입력  (0) 2021.07.29
0729_Ex01~Ex05_Generic  (0) 2021.07.29
0728_Ex11~Ex17_generic : 제네릭  (0) 2021.07.29
package ex0729;

public class Ex06_system {

	public static void main(String[] args) {
		String s;

		s = System.getProperty("os.name");
		System.out.println("운영체제 : " + s);

		s = System.getProperty("file.encoding");
		System.out.println("character set : " + s); // MS949(euc-kr 유사)

		s = System.getProperty("java.version");
		System.out.println("자바 버전 : " + s);

		s = System.getProperty("user.dir");
		System.out.println("현재 작업 경로 : " + s);

		
	}

}

package ex0729;

import java.util.Enumeration;
import java.util.Properties;

public class Ex07_system {

	public static void main(String[] args) {
		// 시스템 환경 설정 정보(운영체제, 인코딩, 작업 경로 등...)
		Properties p = System.getProperties();
		Enumeration<?> e = p.propertyNames();

		while (e.hasMoreElements()) {
			String key = (String) e.nextElement();
			String value = p.getProperty(key);
			System.out.println(key + "->" + value);
		}

	}

}

이런저런것들 볼 수 있음...

package ex0729;

import java.util.Scanner;

public class Ex08_system {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n;

		try {
			while (true) {
				System.out.print("정수 ? ");
				n = sc.nextInt();

				if (n == 0) {
					System.exit(0); // 프로그램 강제 종료. finally 블록은 실행 안됨.
					// return; // finally 블럭은 실행됨.
					// return 은 main() 메소드를 빠져 나가는 것으로
					// main()이 종료된다고 프로그램이 종료되는 것은 아니다.
					// main()은 프로그램의 진입점이지만 종료점은 아니다.
				}

				System.out.println("입력 값 : " + n);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("final block ...");
			sc.close();
		}
		System.out.println("end...");
		
	}

}

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0730_Ex01~Ex02_List  (0) 2021.07.30
Q 0729_Ex001~Ex002_List  (0) 2021.07.30
0729_ConsoleEx_콘솔 입력  (0) 2021.07.29
0729_Ex01~Ex05_Generic  (0) 2021.07.29
0728_Ex11~Ex17_generic : 제네릭  (0) 2021.07.29
package ex0729;

import java.io.Console;

public class ConsoleEx {

	public static void main(String[] args) {
		// 콘솔 입력을 지원하는 클래스로 JDK 6이상 부터 가능. 이클립스에서는 테스트 불가.
		Console c = System.console();
		if( c==null) {
			System.out.println("Console을 지원하지 않습니다.");
			System.exit(0);
		}
		
		String id = c.readLine("%s", "ID : ");
		char[] pwd = c.readPassword("%s", "Password : ");
		
		String s = new String(pwd); // char[]을 String으로
		
		System.out.println("아이디 : " + id);
		System.out.println("패스워드 : " + s);

	}

}

위 소스는 이클립스로 실행이 안되기 때문에 cmd 창에서 확인해보았다.

패스워드를 입력할 때 보이지 않게끔 해주는 거 보려고 한 코드!

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

Q 0729_Ex001~Ex002_List  (0) 2021.07.30
0729_Ex06~Ex09_system : Java API  (0) 2021.07.29
0729_Ex01~Ex05_Generic  (0) 2021.07.29
0728_Ex11~Ex17_generic : 제네릭  (0) 2021.07.29
0728_Ex01~Ex03_exception : 예외처리  (0) 2021.07.29
package ex0729;

public class Ex01 {
	public static void main(String[] args) {
		Test1<Integer> t = new Test1<>();
		
		t.append(10);
		t.append(20);
		t.append(30);
		
		// t.append("자바"); // 컴파일 오류
		
		Integer i = t.get(2);
		System.out.println(i);
	}
}

class Test1<E> {
	private Object[] data;
	private int count;

	public Test1() {
		data = new Object[10];
	}

	public void append(E e) {
		if(count >= data.length) {
			// ArrayIndexOutOfBoundsException() : unchecked 예외. 배열의 첨자가 초과한 경우 발생
			throw new ArrayIndexOutOfBoundsException("요소의 개수를 초과 했습니다.");
		}
		
		data[count++] = e;
	}
	
	@SuppressWarnings("unchecked") // 부적절한 컴파일러의 경고를 제거하기 위해 사용
	public E get(int index) {
		if(index >= count) {
			throw new ArrayIndexOutOfBoundsException(index);
		}
		
		// 제네릭으로 casting 하면 경고가 발생
		return (E) data[index];
	}
	
	public int getCount() {
		return count;
	}
	
}

@SuppressWarnings("unchecked") // 부적절한 컴파일러의 경고를 제거하기 위해 사용

하지만 정확하게 알 때만 사용. 거의 사용하지 않는다!!

<위 코드는 아래와 비교해서 이해할 것!>

package ex0729;

public class Ex02 {
	public static void main(String[] args) {
		Test2<Integer> t = new Test2<>();
		t.append(10);
		t.append(20);
		t.append(30);

		// Integer[] i = t.get(); // 런타임 오류. ClassCastException. 배열은 강제 형변환이 안됨.

		// Cast가 필요
		Object[] oo = t.get();
		for (Object o : oo) {
			Integer i = (Integer) o;
			System.out.println(i);
		}
		// 제네릭배열은 의미가 없다.
	}
}

class Test2<E> {
	private E[] data;
	private int count;

	@SuppressWarnings("unchecked")
	public Test2() {
		// 제네릭 배열 메모리 할당
		// data = new E[10]; // 컴파일 오류
		data = (E[]) new Object[10]; // 제네릭은 Object로 메모리할당을 해야 함.
	}

	public void append(E e) {
		if (count >= data.length) {
			throw new ArrayIndexOutOfBoundsException("배열 요소의 개수를 초과 했습니다.");
		}

		data[count++] = e;
	}

	public E[] get() {
		return data;
	}

	public int getCount() {
		return count;
	}
}

위에서는 Object로 배열을 만들어서 생성자에서 배열의 메모리 할당을 해주었는데,

밑에서는 제네릭클래스에서 제네릭 배열을 만들었다. 

배열의 선언을 위해 생성자에서 할당하려고 했을 때 

data = new E[10]; 은 컴파일 오류가 발생했다. 메모리 할당을 위해서는 Object로 해야 했다. 그래서 배열 메모리 할당 후에 data에 다시 제네릭타입으로 캐스팅하고 넣었다. 여기서 느낌표가 발생해서 다시 

@SuppressWarnings("unchecked") 를 넣어줬다.

 

메인 클래스에서 제네릭타입을 Integer로 해서 객체를 생성한 후 Integer 값들을 3개를 넣었는데 그 배열을 다시 만들으려 했으나

Integer[] i = t.get(); // 런타임 오류. ClassCastException. 배열은 강제 형변환이 안된다.

결국 이 배열을 받기 위해서는 Object로 배열을 생성해서 받아야 했다.

 

package ex0729;

public class Ex03 {
	public static void main(String[] args) {
		Test3<Integer> t = new Test3<>();
		
		Integer[] i = {10,20,30};
		
		t.set(i);
		
		Integer[] i2 = t.get();
		System.out.println(i2[1]);
		
	}
}

class Test3<E> {
	private E[] data;
	
	public void set(E[] data) {
		this.data = data;
	}
	
	public E[] get() {
		return data;
	}
}

 

 

package ex0729;

public class Ex04 {
	public static void main(String[] args) {
		Test4<Number> ob1 = new Test4<>();	
		ob1.set(new Integer(30)); // 타입 매개변수의 상속 관계는 성립
		System.out.println(ob1.get());
		
		// Number n = ob1.get();
		// Integer i = ob1.get(); // 컴파일 오류
		// Integer i = (Integer)ob1.get();
		
		// Number n = new Integer(30); // 업 캐스팅
		Test4<Integer> ob2 = new Test4<>();
		ob2.set(new Integer(30));
		// Test4<Number> ob3 = ob2; // 컴파일 오류. 제네릭은 업캐스팅 불가.
		
		
	}
}

class Test4<T> {
	private T t;
	
	public void set(T t) {
		this.t=t;
	}
	
	public T get() {
		return t;
	}
}

제네릭 타입을 Number로 주었기 때문에 

Integer i = ob1.get(); 은 컴파일 오류이고 강제적으로 캐스팅을 한 후에는 가능하다.

Integer i = (Integer)ob1.get();

Test4<Number> ob3 = ob2; 제네릭은 업캐스팅이 불가해서 컴파일 오류이다.

 

제네릭은 컴파일 단계에서 타입 안정성을 위해 지원하므로 기본적으로 다형성을 갖지 않는다. 

package ex0729;

public class Ex05 {
	public static void main(String[] args) {
		Test5<Integer> ob = new Test5<>();
		ob.set(30);
		
		// Test5<Number> ob2 = ob; // 컴파일 오류. 상속관계가 아님.
		// 제네릭은 같은 데이터 타입만 가능. 훨씬 안정적이다.
		
		// 제네릭 - 와일드 카드
		// ? : 모든 클래스나 인터페이스가 가능
		// 제네릭 타입에 의존적이지 않는 메소드등을 호출
		Test5<?> ob2 = ob;
		ob2.print();
		
		// ob2.set(new Integer(30) ); // 컴파일 오류. 자료형이 결정되지 않은 상태이므로
	}
}

class Test5<T> {
	private T t;
	
	public void set(T t) {
		this.t=t;
	}
	
	public T get() {
		return t;
	}
	
	public void print() {
		System.out.println(t);
	}
}

제네릭에 다형성을 갖도록 만들기 위해 와일드 카드를 사용한다.

제네릭 타입의 클래스를 파라미터로 사용할 때 구체적인 타입이 정해지지 않는 경우에 사용한다.

 

제네릭타입<?> 

  • 제한 없다.
  • 타입 파라미터를 대치하는 구체적인 타입으로 ?에는 모든 클래스나 인터페이스 타입이 올 수 있다.

Test5<?> ob2 = ob;
ob2.print(); // 제네릭 타입에 의존적이지 않은 메소드는 호출할 수 있지만 

ob2.set(); // 이것과 같은 제네릭 타입이 들어가는 메소드는 호출할 수 없다. 컴파일 오류,

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0729_Ex06~Ex09_system : Java API  (0) 2021.07.29
0729_ConsoleEx_콘솔 입력  (0) 2021.07.29
0728_Ex11~Ex17_generic : 제네릭  (0) 2021.07.29
0728_Ex01~Ex03_exception : 예외처리  (0) 2021.07.29
0727_패키지  (0) 2021.07.27

+ Recent posts