프로그래밍/- java

컬렉션 프레임웍( List , Set, Map ), Iterator , Comparable , Comparator

즐겁게 하하하 2022. 2. 3. 09:11
728x90
Collections 인터페이스
1. 채우기, 복사, 정렬 , 검색 :: fill() , copy() , sort() , binarySearch() 등


2. 컬렉션 동기화
List syncList = Collections.synchronizedList( new ArrayList( ... ) );
Set syncSet = Collections.synchronizedSet( new Set( ... ) );


3. 변경불가 컬렉션 만들기
static List = unmodifiableList( List list );
static Set = unmodifiableSet( Set s );


4. 싱클톤 컬렉션 만들기 ( 객체 1개만 저장 )
static List = singletonList( Object o );
static Set = unmodifiable( Object o );
static Map = unmodifiableMap( Object key , Object value );


5. 한종류의 객체만 저장하는 컬렉션 만들기
static List = checkedCollection( list , String.class );
List
저장순서0 , 중복0
데이터 저장에 배열을 이용한다.
ArrayList( 동기화 안되어있음 ) ,
LinkedList ,
Vector( 동기화 되어있음 ) ,
Stack
★ ArrayList VS LinkedList 속도 비교
=> 읽기 : ArrayList 빠름
=> 순차적으로 추가 삭제 : ArrayList 빠름
=> 비순차적으로 추가 삭제 : LinkedList 빠름


★ ArrayList :: 배열기반
0 - 1 - 2 >> ( 이동 ) - 4 - 5
└ 3 ┘
장점 : 접근시간이 짧다.
단점 : 크기를 변경 할 수없다.
데이터 추가 삭제를 위해선 다른 데이터를 옮겨야함
But 끝 추가와 끝 삭제는 빠르다.


★ linked list ( 기차 ) :: 연결기반
0 - 1 - 2 - 4 - 5
└ 3 ┘
장점 : 불연속적으로 존재하는 데이터를 연결
단점: 접근성이 나쁘다.( 징검다리 한방향으로 이동 )
0 > 1 > 2 > 3 > 4 > 5


★ double linked list
단점: 접근성이 나쁘다.( 징검다리 처럼 앞뒤로 이동 )
0 <> 1 <> 2 <> 3 <> 4 <> 5


Set
저장순서x, 중복x
HashSet
- 같은 객체가 없으면 저장, 있으면 pass
- equals, hashCode을 overriding하지 않으면 비교작업이
제대로 작동하지 않음
- 정렬 해야 하는경우 LinkedList 이용해야함.


LinkedHashSet
- 순서 유지됨


TreeSet
- 범위 검색과 정렬에 유리 , 추가삭제에 시간 大
- 이진트리는 모든 노드가 최대 2개의 하위 노드 갖음
- 부모보다 작은건 왼쪽 , 큰건 오른쪽에 저장
- Comparable 또는 Comparator를 호출해서 비교
- 결과가 자동으로 정렬되어 나옴.
- 전위 중위 후위 순회법이 있으며,
중위순회하면 오름차순 정렬된다.
Map
키와 값의 쌍으로 이루어진 집합
저장순서X
키는 중복x , 값은 중복0
HashMap( 동기화 안되어있음 )
- 해싱기법으로 데이터 저장, 검색이 빠르다.


Hashtable( 동기화 되어있음 )
TreeMap
LinkedHashMap
- 순서 유지됨
해싱 : 해쉬함수를 이용하여 데이터를 저장 & 검색
해시코드 : 저장위치
해시테이블 : 배열과 링크드 리스트가 조합된 형태
검색 과정
1. 키로 해시 함수를 호출해서 해시코드를 얻는다.
2. 해시코드에 대응하는 링크드 리스트를 배열에서 찾는다.
3. 링크드 리스트 에서 키와 일치하는 데이터를 찾는다.
collections 인터페이스 메서드 ( 공통 사용 )
List , Set 인터페이스 메서드
Set 인터페이스 메서드
TreeSet 메서드
Map 인터페이스 메서드
====  ArrayList ====
class Ex11_1 {
	public static void main(String[] args) {

		ArrayList list1 = new ArrayList(10);
		list1.add(new Integer(5));
		list1.add(new Integer(4));
		list1.add(new Integer(2));
		list1.add(new Integer(0));
		list1.add(new Integer(1));
		list1.add(new Integer(3));

		ArrayList list2 = new ArrayList(list1.subList(1,4)); 
		print(list1, list2); 
		
		   // list1:[5, 4, 2, 0, 1, 3]
		   // list2:[4, 2, 0]
		 
		Collections.sort(list1);	// list1과 list2를 정렬한다.
		Collections.sort(list2);	// Collections.sort(List l)
		print(list1, list2); 
		
		   // list1:[0, 1, 2, 3, 4, 5]
		   // list2:[0, 2, 4] 
		
		System.out.println("list1.containsAll(list2):"  + list1.containsAll(list2));
		//list1.containsAll(list2):true
		 
		list2.add("B");
		list2.add("C");
		list2.add(3, "A");
		print(list1, list2);
		
		  // list1:[0, 1, 2, 3, 4, 5]
		  // list2:[0, 2, 4, A, B, C]
		
		list2.set(3, "AA");
		print(list1, list2);
		
		  // list1:[0, 1, 2, 3, 4, 5]
		  // list2:[0, 2, 4, AA, B, C]
		
		// list1에서 list2와 겹치는 부분만 남기고 나머지는 삭제한다.
		System.out.println("list1.retainAll(list2):" + list1.retainAll(list2));
		//list1.retainAll(list2):true
		
		//(★중요) list1.remove(2);  // index 2 삭제
		list1.remove(new Integer(2)); // 2을 삭제		
		
		print(list1, list2);
		 
		  // list1:[0, 4]
		  // list2:[0, 2, 4, AA, B, C]
		 
		//  list2에서 list1에 포함된 객체들을 삭제한다.
		for(int i= list2.size()-1; i >= 0; i--) {
			if(list1.contains(list2.get(i)))
				list2.remove(i);
		}
		print(list1, list2);
		 
		    // list1:[0, 4]
			// list2:[2, AA, B, C]
		 
	} // main의 끝

	static void print(ArrayList list1, ArrayList list2) {
		System.out.println("list1:"+list1);
		System.out.println("list2:"+list2);
		System.out.println();		
	}
} // class
====  HashSet  ====
- 같은 객체가 없으면 저장, 있으면 pass
- equals, hashCode을 overriding하지 않으면 비교작업이 제대로 작동하지 않음
- 정렬이 필요한 경우 LinkedList 이용

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

class Ex11_11 {
	public static void main(String[] args) {
		HashSet set = new HashSet();

		set.add("abc");
		set.add("abc"); // 중복이라 저장안됨
		set.add(new Person("David",10)); 
		set.add(new Person("David",10)); // 중복 제거 안됨

		System.out.println(set); // [abc, David:10, David:10]
		// equals() 와 hashCode()를 오버라이딩 해야 HashSet이 바르게 동작
		
		List list = new LinkedList(set); // LinkedList(Collection c)
		Collections.sort(list); // set은 정렬이 불가능 하므로 Collections.sort(List list)
		System.out.println(list);
		
	}
}

class Person { 
	String name;
	int age;

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String toString() {
		return name +":"+ age;
	}
	 
	public int hashCode() {  
		return Objects.hash(name , age);
	}
 
	public boolean equals(Object obj) {  
		if( !(obj instanceof Person ) ) return false; 
		Person p = (Person)obj; 
		// 나 자신 this 의 이름과 나이를 p 와 비교
		return this.name.equals(p.name) && this.age == p.age;
	} 
}
HashSet
====  TreeSet  ====
1. Set set = new TreeSet( new TestComp() );

2. Set set = new TreeSet(); 
2. set.add( new Test() );

class Test implements Comparable {
  public int compareTo( Object o ){
     return -1;
  }
}

class TestComp implements Comparator {
  public int compare( Object o1 , Object o2){
    return 1;
  }
}
====  HashMap ====
class Ex11_17 {
	public static void main(String[] args) {
		HashMap map = new HashMap();
		map.put("김자바", 90);
		map.put("김자바", 100);
		map.put("이자바", 100);
		map.put("강자바", 80);
		map.put("안자바", 90);

		Set set = map.entrySet();
		Iterator it = set.iterator();

		while(it.hasNext()) {
			Map.Entry e = (Map.Entry)it.next();
			System.out.println("이름 : "+ e.getKey() + ", 점수 : " + e.getValue());
		}

		set = map.keySet();
		System.out.println("참가자 명단 : " + set);

		Collection values = map.values();
		it = values.iterator();

		int total = 0;
		
		while(it.hasNext()) {
			int i = (int)it.next();
			total += i;
		}

		System.out.println("총점 : " + total);
		System.out.println("평균 : " + (float)total/set.size());
		System.out.println("최고점수 : " + Collections.max(values));
		System.out.println("최저점수 : " + Collections.min(values));
	}
}

Iterator , ListIterator(양방향) , Enumeration
  => 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화
  => 컬렉션에 저장된 데이터를 접근하는데 사용되는 인터페이스
  => Enumeration은 Iterator의 구버전
  => 1회용, 재사용시 다시 선언
 
  1.Iterator , ListIterator
  boolean hasNext : 읽어올 요소가 남아있는지 확인 있으면 true; 없으면 false;
  Object  next()  : 다음 요소를 읽어온다. next() 를 호출하기 전에 hasNext()를 호출해서
                    읽어올 요소가 있는지 확인하는게 안전하다.

	  List list = new ArrayList();
	  Iterator it = list.iterator(); :: 객체를 반환 ( 1회용, 재사용시 다시 선언 )
	  while( it.hasNext() ){ //boolean
		 System.out.println( it.next() );
	  }
 
 2.Enumeration
 boolean  hasMoreElements() : 읽어올 요소가 남아있는지 확인 있으면 true;  없으면 false; 
 Objet    nextElement()     : 다음 요소를 읽어온다. 

 3. Map 에는 iterator() 가 없다. keySet() , entrySet() , Values() 호출해야.
      Map map = new HashMap();
      Iterator it = map.entrySet().iterator();
import java.util.*;
class Ex11_5 {
	public static void main(String[] args) {
		//ArrayList list = new ArrayList();
		Collection list = new ArrayList();  //Collection 인터페이스 의 자손
		
		list.add("1");
		list.add("2");
		Iterator it = list.iterator();
		while(it.hasNext()) {
			Object obj = it.next();
			System.out.println(obj);
		}

//		======  Collection 접근 표존화 X =====
//		for (int i = 0; i < list.size(); i++) {
//			Object obj = list.get(); 
// 			ㄴ 메소드 get()이(가) Collection 유형에 대해 정의되지 않았습니다.
		
//			System.out.println(obj);
//		}  
	} // main
}

★ Comparable  , Comparator : 객체 정렬에 필요한 메서드를 정의한 interface
  왼쪽大 : 양수  / 같다 : 0  /  오른大 : 음수
  Comparable : 기본 정렬기준 구현
  Comparator : 기본 정렬 기준 외 다른 기준으로 정렬하고자 할 때
  sort() : 두 대상에 대하여 1) 비교 2) 자리바꿈

   Comparable :  int compareTo( Object o ); :: 주어진 객체o를 자신과 비교 
   Comparator :  int compare( Object o1 , Object o2 ); :: 두 객체를 비교 
 
public final class Integer extends Number implements Compatable{
   public int compareTo( Integer anotherInteger ){
	  int v1 = this.value;
	  int v2 = anotherInteger.value;
	  return ( v1 < v2 ? -1 : (v1 == v2 ? 0 : 1 ));
   }
}
 
import java.util.*;
class Ex11_7 {
	public static void main(String[] args) {
		String[] strArr = {"cat", "Dog", "lion", "tiger"};

		Arrays.sort(strArr); // String의 Comparable구현에 의한 정렬
		System.out.println("strArr=" + Arrays.toString(strArr));

		Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 구분안함
		System.out.println("strArr=" + Arrays.toString(strArr));

		Arrays.sort(strArr, new Descending()); // 역순 정렬
		System.out.println("strArr=" + Arrays.toString(strArr));
	}
}

class Descending implements Comparator { 
	public int compare(Object o1, Object o2){
		if( o1 instanceof Comparable && o2 instanceof Comparable) {
			Comparable c1 = (Comparable)o1;
			Comparable c2 = (Comparable)o2;
			return c1.compareTo(c2) * -1 ; // -1을 곱해서 기본 정렬방식의 역으로 변경한다.
						                // 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 된다.
		}
		return -1;
	} 
}
 
★ 람다식을 이용한 출력
import java.util.*;

class Ex14_4 {
	public static void main(String[] args) 	{
		ArrayList<Integer> list = new ArrayList<>();
		for(int i=0;i<10;i++)
			list.add(i);

		//============ list의 모든 요소를 출력
		System.out.println("Sysout  ::  "+ list);
		
		System.out.print("forEach ::  ");
		list.forEach(i->System.out.print(i+","));
		
		System.out.println("Iterator ::  ");
		Iterator<Integer> it = list.iterator();
		while( it.hasNext() ) {
			System.out.println(it.next());
		}

		//============ list에서 2 또는 3의 배수를 제거한다.
		list.removeIf(x-> x%2==0 || x%3==0);
		System.out.println(list);

		 // ============list의 각 요소에 10을 곱한다.
		list.replaceAll(i->i*10);
		System.out.println(list);

		Map<String, String> map = new HashMap<>();
		map.put("1", "1");
		map.put("2", "2");
		map.put("3", "3");
		map.put("4", "4");

		 // ============ list의 각 요소에 10을 곱한다.map의 모든 요소를 {k,v}의 형식으로 출력한다.
		System.out.println("Iterator ::  ");
		Iterator it2 = map.entrySet().iterator();
		while( it2.hasNext() ) {
			System.out.println(it2.next());
		}
		
		map.forEach((k,v)-> System.out.print("{"+k+","+v+"},"));
		System.out.println();
	} 
}
 

 

 

 

 

728x90