[Java] 2020.11.16. day_19 객체화종류, 자주사용하는클래스_List,Set

2020. 11. 16. 16:07Web_Back-end/Java SE

◎ 객체화 종류

객체화를 하는 이유 : static 영역에서 instance 영역의 자원을 사용하기 위해

방법 객체화 종류
1
자식클래스만 가지고 객체화
  자식클래스명 객체명 = new 자식클래스생성자();

객체만 만들고
method호출 안할 때
  new 생성자();
3
인스턴스객체화 하면서 method하나만 부를 때
  new 생성자.method();
  chain 방식으로 부르는 것
4
is a 관계 객체화
  부모클래스명 객체명 = new 자식클래스생성자();
  객체다형성

inner class 객체화
  바깥클래스명.안쪽클래스명 객체명 = 바깥클래스인스턴스명.new 안쪽클래스생성자();

◎ JCF (Java Collection Framwork)

  • JCF : 자료구조
    • 자료구조 : 데이터를 상황에 따라 편하게 처리하기 위해 제공하는 객체들
  JCF (Java Collection Framwork)
JCF 자료구조 : 데이터를 상황에 따라 편하게 처리하기 위해 제공하는 객체들
Collection 계열 ( _ List, Set)
Map 계열로 구분 ( _ Map)
JDK 1.5 에서부터 Generic , Autoboxing , Unboxing 지원
import java.util package 에서 제공

List

  List
  일차원배열의 구조를 가진다
가변길이형 (개발자가, 발생하는 데이터의 갯수를 몰라도 된다)
가변길이형 값을 추가하면 방의 갯수(길이)가 늘어나고, 값을 삭제하면 방의 갯수(길이)가 줄어든다 
  검색의 기능이 있으며, 중복데이터를 저장할 수 있다 (중복허용)
상속도 List
  -ArrayList
  -LinkedList
  -Vector
     - Stack
  모든 데이터를 저장할 수 있다

Set

  Set
  가변길이형
검색의 기능이 없으며, 중복데이터를 저장할 수 없다 (중복비허용)
상속도 Set
  -HashSet
  모든 데이터를 저장할 수 있다

Map

  Map
  이차원배열의 구조를 가진다 (행,열)
가변길이형
열은 2개 (Key, Value) , 행이 증가한다
키와 값의 쌍
키를 가지고 값을 검색한다
key 중복될 수 없다 (유일)
value 중복될 수 있다
상속도 Map
  -HashTable
  -HashMap
  모든 데이터를 저장할 수 있다

 List 사용

  Generic을 사용하지 않았을 때
1. 생성 List list = new ArrayList(); //<E> 사용X 모든 객체를 저장할 수 있다
2. 값추가 list.add(new Integer(10)); //객체
list.add(20); //정수값 ==> list.add(new Integet(20));로 자동변경해줌
list.add(new Integer(30));
list.add("월요일"); //문자열값 ==> list.add(new String("월요일"));
3. 크기 (방의 갯수) list.size(); //4
4. 값얻기

▶ Error 발생
▶ 해결 : Generic
배열명.get(int index);
list.get(0); //10

모든방의 값을 얻기
for(int i=0; i<list.size(); i++){
  list.get(i)*100; //연산시 Error - 값의 데이터형이 다르기 때문
}

○ List 사용

  List 사용
Generic _ 위의 문제해결
  JDK 1.5 에서부터 추가
입력되는 데이터형의 형제한
문법 <데이터형> : 선언된 데이터형으로만 추가 가능
객체화 자식클래스만의 method를 잘 사용하지 않기 때문에 1-2 is a 관계 객체화를 주로 사용
1. 자식 부모의 모든 method&변수, 자식의 모든 method&변수 모두 사용가능
ArrayList<E>al = new ArrayList<E>();    //<E>: Generic_기본형데이터형은 사용할 수 없다

//<참조형데이터형>/Wrapper class만 사용가능
예: ArrayList<String> al = new ArrayList<String>();
    ArrayList<String> al = new ArrayList<>(); //JDK 1.7에서부터는 생성자의 Generic생략가능
2. 부모
is a관계 객체화
부모의 모든 method&변수 사용가능 (자식의 자원 사용불가)

List
<E> list = new ArrayList<E>(); 
예: List<Integer> list = new ArrayList<Integer>();
    List<Integer> list = new ArrayList<>();
List 사용법
1. 생성 List<String> list = new ArrayList<>();
2. 값추가 list.add(E o); //E : element => Generic으로 변경 , o : Object
list.add("Today");
list.add("is");
list.add("Monday");
list.add("is");
//중복값은 저장할 수 있다
3. 방의 크기  list.size(); //4 (반환형 int=방의 갯수를 int갯수만큼 만들 수 있다)
4. 값얻기 = 검색가능 인덱스를 사용하여 값 얻기
list.get(0); //Today (설정한 Generic으로 반환)
get() method 반환형

5. 리스트가 비었는지 list.isEmpty(0); //false
6. 리스트 방의 값 삭제 1. 모든 방의 값 삭제
list.clear();

2. 특정 방의 값 삭제 : 삭제된 이후 방들의 인덱스 변경
  2-1 인덱스로 삭제 
  list.remove(인덱스);  
  list.remove(0); //Today삭제-> is의 index가 0

  2-2 방의 내용 삭제
  list.remove(객체);  
  list.remove("Today");  //유일하면 그대로 삭제
  list.remove("is"); //중복되면 가장 처음 일치하는 방의 값만 삭제
remove() method

7. 일괄처리 for(int i=0; i<list.size(); i++){

  list.get(i);  //처음방부터 끝방까지 모든 방의 값 얻는다

}
8. List의 내용
배열로 복사

toArray(배열명)
toArray()
Generic을 사용하지 않고 복사하면 경고발생_eclipes (error발생될 수도있음)
1. List의 크기대로 배열생성
데이터형[] 배열명 = new 데이터형[List명.size()];
String[] ar = new Strina[list.size()];

2. List의 내용을 배열로 복사
List명.toArray(배열명);
list.toArray(ar);
List 의 상속도 List
  -ArrayList
  -LinkedList
  -Vector 
     - Stack
데이터의 크기를 알 수 없으며,
순차적으로 데이터를 추가할 때 사용
데이터를 중간에 넣을 때 효율이 떨어진다
ArrayList : Multi Thread에서 동시접근 가능(비동기화) ,속도빠름
Vector : Multi Thread에서 동시접근 불가능(동기화) ,속도느림
가변길이형, 
발생된 데이터를
기존데이터 사이에 추가할 때 사용
(순차적으로 추가도 가능)
LinkedList : 방의 앞뒤로 시작주소,끝주소끼리 연결되어있다

○ Stack

  • memory stack과는 관계없다
  • LIFO (Last Input First Output)
  • 동기화 
  • 1. is a 관계의 객체화를 하지 않는다(할 수는 있다)
  • 2. 부모의 클래스(Vector)의 method를 사용하지 않는다(할 수는 있다)
  • 1,2.의 이유 : Stack의 기능 위배
  Stack 의 사용법
부모의 method
제외하고 
Stack의 method만
사용해야한다

사용법 1) 생성
Stack<E> stack = new Stack<E>();
Stack<String> sta = new Stack<String>();

2) 값추가 (값 : item)
sta.push(값);
sta.push("A");
sta.push("B");
sta.push("C");
sta.push("D");

//A가 제일 아래에 깔리고 그 위로 쌓인다

3) Stack이 비었는지 (==item이 없을 때)
sta.empty();
==> 비었다면 true, 아니면 false

4) Stack 값얻기 (값을 꺼내면 Stack에서 사라짐)
sta.pop();
//제일 위에있는 값이 반환된다
sta.pop(); //->D가 반환되고 삭제된다
sta.pop(); //->C가 반환되고 삭제된다

◆ Stack에 item이 존재한다면 pop()사용
while( !sta.empty() ){ //모든 방의 값얻기
   sta.pop();
}


▼ 접은글: Vector, ArrayList, LinkedList 사용해보기 ▼

더보기
package day1116;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * List - ArrayList, Vector<br>
 * 검색의 기능이 있으며, 중복데이터를 저장할 수 있는 List의 사용<br>
 * 가변길이형 : 데이터의 추가, 삭제작업에 따라 방의 갯수가 변경된다<br>
 * @author owner
 */
public class UseList {

//	public UseList() {
//	
//	}//UseList
	
	/**
	 * Multi Thread 에서 동시접근 불가능 == 동기화 , 속도가 ArrayList보다 느리다
	 */
	public void UseVector() {
//1		//1. 생성 : Generic은 기본형을 사용할 수 없다 ==> 기본형대신 Wrapper class사용
		Vector<Integer> vec = new Vector<Integer>(3); //capacity의 크기는 size에 영향을 주지 않는다
		//기본 방의 크기, size로 방의 크기가 나오지 않는다, 데이터가 추가되면 방의 크기는 늘어난다
		List<String> list = new Vector<String>();
		
		System.out.println("Vector vec의 크기: " + vec.size());
		System.out.println("List list의 크기: " + list.size());
	
//2		//2. 값추가 : Generic으로 설정된 데이터형만 추가 가능
		//기본형 데이터형을 추가하면, JVM이 기본형데이터형에 대응되는 
		//Wrapper class를사용하여 객체를 만들고 추가해준다 == Autoboxing(JDK 1.5 에서부터 추가됨)
		vec.add(10); //vec.add(new Integer(20)); 으로 변경(Autoboxing)된다
		vec.add(20);
		System.out.println("Vector vec의 크기: " + vec.size());
		vec.add(30); 
		vec.add(10); //capacity의 크기를 초과하더라도 방이 증가하여 추가된다
		System.out.println("Vector vec의 크기: " + vec.size());
		System.out.println(vec); //Object.toString() 를 Vector가 Override하여 주소가 아닌 값이 출력된다
		
		list.add("밍키");
		list.add("코비");
		list.add("빠니");
		list.add("찌니");
		list.add("포비");
		System.out.println("List list의 크기: " + list.size() +", " + list);
		
		//배열로 복사
		//배열을 리스트의 크기로 설정한다
//		int[] arr = new int[vec.size()]; //int와 Integer는 동일 데이터형이 아니다
		Integer[] arr = new Integer[vec.size()];
		String[] arr1 = new String[list.size()];
		//복사
		list.toArray(arr1);
		vec.toArray(arr);
		
//3		//3. 값 얻기 : Unboxing
		String name = list.get(0); //입력데이터형과 저장하는 데이터형이 같다면 Unboxing 동작 X
		System.out.println(name);
		
		//get의 반환형-Integer, 저장하는데이터형 int ==> Unboxing 동작
		int num = vec.get(0); 
		//기본형 Wrapper class가 Generic으로 설정되어있을 때 
		//기본형 데이터형으로 값을 얻으면 JVM이 Wrapper class에서 
		//기본형으로 값을 얻어내는 Unboxing을 수행한다
		//int num = vec.get(0).intValue(); 
		//== (Integer)vec.get(0).intValue(); //chain 형
		
		System.out.println(name + "/" + num);
		
		//4. 일괄처리
		for(int i=0; i<vec.size(); i++) {
			System.out.println(vec.get(i));
		}//end for
		
		for(int i=0; i<list.size(); i++) {
			System.out.println(list.get(i));
		}//end for
		
	//값 삭제
		//index
		vec.remove(1); //index 1번자리 값이 삭제
		list.remove(3); //index 3번자리 값이 삭제
		System.out.println(vec);
		System.out.println(list);
		//Object
//		vec.remove(new Integer(30)); //30이 삭제 //JDK 1.8까지만 사용
		vec.remove(Integer.valueOf(30)); //30이 삭제 //JDK 9이후에는 생성자가 비추천으로 변경되어 static method를 사용

		list.remove(new String("빠니")); //"빠니"가 삭제
		list.remove("포비"); //"포비"가 삭제

		System.out.println(vec);
		System.out.println(list);
		
		System.out.println("vec가 비었는지? " + vec.isEmpty());
		System.out.println("list가 비었는지? " + list.isEmpty());
		
		//모든 방의 값 삭제
		vec.clear();
		list.clear();
//		System.out.println(list.size()==0);//isEmpty() 와 같음_가독성저하
		System.out.println("vec가 비었는지? " + vec.isEmpty());
		System.out.println("list가 비었는지? " + list.isEmpty());
		
		System.out.println("----------배열에 복사한 내용-------------");
		for(int i=0; i<arr.length; i++) {
			System.out.println(arr[i]);
		}
		for(String value: arr1) {
			System.out.println(value);
		}
		
	}//UseVector
	
	
	/**
	 * Multi Thread 에서 동시접근 가능 == 비동기화 , 속도가 Vector보다 빠르다
	 */
	public void UseArrayList() {
//1		//1. 생성 : Generic은 기본형을 사용할 수 없다 ==> 기본형대신 Wrapper class사용
		ArrayList<Integer> al = new ArrayList<Integer>(3); //capacity의 크기는 size에 영향을 주지 않는다
		//기본 방의 크기, size로 방의 크기가 나오지 않는다, 데이터가 추가되면 방의 크기는 늘어난다
		List<String> list = new Vector<String>();
		
		System.out.println("ArrayList vec의 크기: " + al.size());
		System.out.println("List list의 크기: " + list.size());
	
//2		//2. 값추가 : Generic으로 설정된 데이터형만 추가 가능
		//기본형 데이터형을 추가하면, JVM이 기본형데이터형에 대응되는 
		//Wrapper class를사용하여 객체를 만들고 추가해준다 == Autoboxing(JDK 1.5 에서부터 추가됨)
		al.add(10); //al.add(new Integer(20)); 으로 변경(Autoboxing)된다
		al.add(20);
		System.out.println("ArrayList al의 크기: " + al.size());
		al.add(30); 
		al.add(10); //capacity의 크기를 초과하더라도 방이 증가하여 추가된다
		System.out.println("ArrayList al의 크기: " + al.size());
		System.out.println(al); //Object.toString() 를 ArrayList가 Override하여 주소가 아닌 값이 출력된다
		
		list.add("밍키");
		list.add("코비");
		list.add("빠니");
		list.add("찌니");
		list.add("포비");
		System.out.println("List list의 크기: " + list.size() +", " + list);
		
		//배열로 복사
		//배열을 리스트의 크기로 설정한다
//				int[] arr = new int[al.size()]; //int와 Integer는 동일 데이터형이 아니다
		Integer[] arr = new Integer[al.size()];
		String[] arr1 = new String[list.size()];
		//복사
		list.toArray(arr1);
		al.toArray(arr);
		
//3		//3. 값 얻기 : Unboxing
		String name = list.get(0); //입력데이터형과 저장하는 데이터형이 같다면 Unboxing 동작 X
		System.out.println(name);
		
		//get의 반환형-Integer, 저장하는데이터형 int ==> Unboxing 동작
		int num = al.get(0); 
		//기본형 Wrapper class가 Generic으로 설정되어있을 때 
		//기본형 데이터형으로 값을 얻으면 JVM이 Wrapper class에서 
		//기본형으로 값을 얻어내는 Unboxing을 수행한다
		//int num = al.get(0).intValue(); 
		//== (Integer)al.get(0).intValue(); //chain 형
		
		System.out.println(name + "/" + num);
		
		//4. 일괄처리
		for(int i=0; i<al.size(); i++) {
			System.out.println(al.get(i));
		}//end for
		
		for(int i=0; i<list.size(); i++) {
			System.out.println(list.get(i));
		}//end for
		
	//값 삭제
		//index
		al.remove(1); //index 1번자리 값이 삭제
		list.remove(3); //index 3번자리 값이 삭제
		System.out.println(al);
		System.out.println(list);
		//Object
//				al.remove(new Integer(30)); //30이 삭제 //JDK 1.8까지만 사용
		al.remove(Integer.valueOf(30)); //30이 삭제 //JDK 9이후에는 생성자가 비추천으로 변경되어 static method를 사용

		list.remove(new String("빠니")); //"빠니"가 삭제
		list.remove("포비"); //"포비"가 삭제

		System.out.println(al);
		System.out.println(list);
		
		System.out.println("al가 비었는지? " + al.isEmpty());
		System.out.println("list가 비었는지? " + list.isEmpty());
		
		//모든 방의 값 삭제
		al.clear();
		list.clear();
//				System.out.println(list.size()==0);//isEmpty() 와 같음_가독성저하
		System.out.println("al가 비었는지? " + al.isEmpty());
		System.out.println("list가 비었는지? " + list.isEmpty());
		
		System.out.println("----------배열에 복사한 내용-------------");
		for(int i=0; i<arr.length; i++) {
			System.out.println(arr[i]);
		}
		for(String value: arr1) {
			System.out.println(value);
			}
				
		
	}//UseArrayList
	
	public static void main(String[] args) {

		UseList ul = new UseList();
		System.out.println("Vector, ArrayList 사용");
		System.out.println("---------------------------");
		ul.UseVector();
		System.out.println("---------------------------");
		ul.UseArrayList();
		
		
	}//main

}//class

 


더보기
package day1117;

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

/**
 * LinkedList : <br>
 * -java.util.List 를 구현한 클래스<br> 
 * -일차원배열의 형식, 가변길이형<br>
 * -발생된 데이터가 기존의 데이터 사이에 들어가는 일이 많을 때
 * @author owner
 */
public class UseLinkedList {

	public UseLinkedList() {
		
		//1. 생성 : is a, 자식 둘다 가능
		LinkedList<String> ll = new LinkedList<String>();
		List<String> list = new LinkedList<String>();
		
		//2. 값추가 : 순차적 (Set은 무작위)
		ll.add("Java");
		ll.add("Oracle");
		ll.add("JDBC");
		
		list.add("Java");
		list.add("JSP");
		list.add("XML");
		list.add("JSON");

		System.out.println(ll + " / " + ll.size());
		System.out.println(list + " / " + list.size());
		
		//기존의 데이터 사이에 갑을 추가할 때 ArrayList, Vector보다 고효율
		list.add(1,"JDBC");
		list.add(1,"Oracle");
		System.out.println(list + " / " + list.size());
		
		list.remove(4);
		System.out.println(list + " / " + list.size());
		
		for(int i=0; i<list.size(); i++) {
			System.out.println(list.get(i));
		}//end for
		
	}//UseLinkedList
	
	public static void main(String[] args) {

		new UseLinkedList();
		
	}//main

}//class

▼ Stack 사용 ▼

package day1117;

import java.util.Stack;

/**
 * LIFO (Last Input First Output) 를 구현한 클래스<br>  
 * @author owner
 */
public class UseStack {

	public UseStack() {
		
		//1. 생성 : is a 관계의 객체화를 하지 않는다
		Stack<String> sta = new Stack<String>();
		//2. method 호출 : 부모의 method 사용하지 않는다
		//값(item) 추가
		sta.push("1 Java");
		sta.push("2 Oracle");
		sta.push("3 JDBC");
		sta.push("4 Java EE");
		
//		System.out.println(sta.pop());
		System.out.println(sta);
		System.out.println("Stack이 비었는가?: " + sta.empty());
		
		//모든 방의 값 얻기
		//후입선출 : 마지막에 입력된 값이 먼저 나온다 (ex:Ctrl+Z의 기능과 같다 <-> Ctrl+Y)
		while(!sta.empty()) {
			System.out.println(sta.pop()); 
		}//end while
		System.out.println("Stack이 비었는가?: " + sta.empty());
		
		
	}//UseStack
	
	public static void main(String[] args) {

		new UseStack();
		
		
	}//main

}//class


◎ Autoboxing

  • JDK 1.5 에서부터 추가
  • JCF에 기본형 데이터형의 값을 추가할 때 동작
  • 기본형 데이터형을 Wrapper class로 감싸서 입력하는 일 (기본형->객체)
  • JDK 1.8 까지는 Wrapper class 생성자를 사용하여 값을 넣지만, JDK 1.9부터는 static method를 사용
  • JDK 1.8 == Java SE 8 
  • JDK 1.8 : list.add(10); //list.add(new Integer(10));
  • JDK 1.9 : list.add(10); //list.add(Integer.intValue(10));

◎ Unboxing

  • JDK 1.5 에서부터 추가
  • JCF에서 입력된 기본형 데이터형을 얻을 때 동작
  • Wrapper class 로 입력된 데이터형을 기본형으로 풀어서 꺼내는 일 (객체->기본형)
  • int i = list.get(0); //int i = (Integer)list.get(0).intValue;

    stack 참조 heap
생성 List<Integer> list = new ArrayList<Integer>(); list :  l
(시작주소)
값추가 list.add(10); //Autoboxing 동작
   =add(new Integer(10))
list :  new Integer
10
값얻기 int i = list.get(0);
((Integer)list.get(0)).intValue() 가 i에 들어감 ==> Unboxing 동작
     

○ Set 사용

  Set 사용
  값이 순차적으로 입력되지 않는다
1. 생성 1-1 
HashSet<E> hs = new HashSet<E>();

1-2 is a 관계
Set<E> s = new HashSet<E>();
2. 값 추가 입력되는 값은 순차적으로 입력되지 않는다 (순서_index 없음)
중복값은 입력되지 않는다 (중복비허용)
set.add(값);
3. 크기 set.size();
4. 값 삭제 선택한 방의 값 하나 삭제 : index로 값을 삭제할 수 없다
set.remove(Object);

모든 방의 값 삭제
set.clear();
5. 값 얻기 X 검색불가 => java.util.Iterator 를 사용
Iterator 입력되는 대상의 제어권을 얻어 값을 얻는 일을 하는 객체(interface)
5. 값 얻기 (6~7)
(Iterator로)
Iterator 에 제어권 할당
Iterator<E> ita = Set.iterator();
6. 값이 존재하는지 6. while( ita.hasNext() ){ //다음요소(방)가 존재하는가?
  7. 값 = ita.next(); //값을 얻고 포인터를 다음으로 이동
  }
7. 값얻기

▼ 접은글 set 예제

더보기
package day1116;

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

/**
 * 검색의 기능이 없고, 중복값을 허용하지 않는 Set사용<br>
 * 입력값은 순차적으로 입력되지 않는다
 * @author owner
 */
public class UseSet {

	public UseSet() {
		
		//1. 생성
		Set<String> set = new HashSet<String>(); 
		//2. 값할당_순서가 없다
		set.add("sun");
		set.add("star");
		set.add("moon");
		set.add("earth");
		set.add("marth");
		set.add("marth");//중복데이터 추가 : 중복데이터는 추가되지 않는다
		set.add("moon");//중복데이터 추가
		
		//3. 값삭제
		set.remove("star");
		System.out.println(set.size() + "/" + set);
		
		//4. 검색 : Iterator를 사용
		Iterator<String> ita = set.iterator(); //Iterator에 데이터를 가진 Set의 제어권 넘겨줌
		
		while(ita.hasNext()) {//방이 존재하는지
			System.out.println(ita.next());//값을 얻고 포인터를 다음방 앞으로 이동
		}//end while
		
		
		
	}//UseSet
	
	public static void main(String[] args) {

		new UseSet();
		
	}//main

}//class