Java고급문법_2_Collection

소정·2023년 2월 2일
0

Java

목록 보기
20/23

Collection

자료구조를 구현한 Java의 API 클래스들 대량의 데이터를 효율적으로 관리하기 위한 것
데이터의 주소값들을 저장함

순서인덱스 번호중복종류
ListOOOVector / ArrayList/ LinkedList
SetXXXHashSet / TreeSet
MapX인덱스 번호 대신 keykey - X / value - OHashMap / Hashtable / TreeMap

List

[1] ArrayList

이름에서도 티가 나듯 ArrayList는 배열의 특성을 가지고 있다
메모리에 연속적으로 등록하고 데이터의 삽입/삭제 시 내부에서 자동으로 배열 복사한다
데이터 저장은 연속적, 접근은 인덱스를 통해 한다
검색 속도가 빠른 장점과 데이터 추가/삭제 할땐 느리다는 단점이있다

List 활용 메소드

import java.util.*;

public class ListTest {

	public static void main(String[] args) {
		
		//List 인터페이스를 구현한 하위 클래스 3개 : Vector, ArrayList, LinkedList
		//3개 모두 사용문법은 거의 같음 단지 성능 차이
		
		//List list = new List(); //error : 인터페이스는 직접 객체생성 불가
		
		// List이터페이스를 구현한 하위클래스를 객체로 생성하여 사용
		ArrayList<String> list = new ArrayList<>();
		
		//[1]ArrayList클래스가 데이터를 제어하기 위해 만들어놓은 기능 (메소드) 실슴
		//ArrayList는 내부적으론 배열이다 
		//->내부적으로 배열을 복사하는 것을 알아서 하는것뿐 
		
		//1. 요소의 개수 : .size()
		int size = list.size();
		System.out.println("요소 개수 : " + size);
		
		//2. 요소의 추가 : .add()
		String s = new String("hong");
		list.add(s); //주소값 대입
		
		list.add("kim");
		list.add("ccc");
		System.out.println("요소 개수 : " + list.size());
		
		//3. 요소 얻어오기 : .get()
		String s1 = list.get(0);
		System.out.println(s1);
		System.out.println(list.get(1)+"\n");
		
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		
		//4. 요소 석제하기 : .remove()
		list.remove(0);
		System.out.println("요소 개수 : " + list.size());
		
		System.out.println(list.get(0));
		System.out.println(list.get(1)); //데이터 삭제 후 숏팅 자동으로 됨
		System.out.println();
		
		//5. 특정 위치에 요소 추가하기 : .add(index, element)
		list.add(0, "ddd");
		System.out.println("요소 개수 : " + list.size());
		System.out.println(list.get(0));
		System.out.println(list.get(1));
		System.out.println(list.get(2));
		
		//6. 제거할때 인덱스 번호가 아니라 객체의 주소값(참조변수)로 제거 가능
		String sss = new String("Test");
		list.add(sss);
		System.out.println("요소 개수 : " + list.size());
		list.remove(sss);
		System.out.println("요소 개수 : " + list.size());
		System.out.println();
		
		//7. 요소 모두를 한번에 깨끗이 제거 : .clear()
		list.clear();
		System.out.println("요소 개수 : " + list.size());
		System.out.println();
		
		//8. 리스트가 비어있는지 확인하는 메소드 : .isEmpty()
		System.out.println(list.isEmpty());
		System.out.println();
		
		//9. 중복된 데이터 허용(특징)
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		System.out.println("요소 개수 : " + list.size()); // => 3개
		System.out.println();

		//10. list 안에 특정 요소가 있는지 여부[true/ false] : .contains()
		System.out.println(list.contains(sss));
		System.out.println(list.contains("aaa"));
		
		//11. *다른 리스트*의 요소들을 한 번에 추가하기 : .addAll()
		list.clear();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		
		ArrayList<String> list2 = new ArrayList<>();
		list2.add("sam");
		list2.add("robin");
		
		list.addAll(list2);
		System.out.println("요소 개수 : " + list.size()); // => 5개
		
		//12. 반복문 없이 단순히 요소값 console창에서 보고싶으면 toString() 기능 사용
		System.out.println(list.toString()); //=> [aaa, bbb, ccc, sam, robin]
		
		//13. 다른 리스트의 요소들과 같은 요소들을 모두 제거하기 : .removeAll()
		ArrayList<String> list3 = new ArrayList<>();
		list3.add("bbb");
		list3.add("sam");
		
		list.removeAll(list3);
		System.out.println(list.toString()); // => [aaa, ccc, robin]
		
		//14. 다른 리스트의 요소들과 같은 요소들만 남기고 나머지 모두 제거 : .retainAll()
		ArrayList<String> list4 = new ArrayList<>();
		list4.add("aaa");
		list4.add("robin");

		list.retainAll(list4);
		System.out.println(list.toString()); // => [aaa, robin]
		
		//15. 특정 요소들이 모두 포함되어 있는지 여부 : .containsAll()
		ArrayList<String> list5 = new ArrayList<>();
		list5.add("aaa");
		list5.add("robin");
		list5.add("kkk");
		
		System.out.println(list.containsAll(list5));// => false
				
		
		//16. 특정 요소가 몇번째에 있는지.. 인덱스 번호 리턴 :.indexOf()
		System.out.println(list.indexOf("robin"));
		System.out.println(list.indexOf("kim")); // => -1
		
		list.add("aaa");
		list.add("sss");
		System.out.println(list.toString()); //=> [aaa, robin, aaa, sss]
		
		System.out.println(list.indexOf("aaa")); // => 0
		System.out.println(list.lastIndexOf("aaa")); // => 2
		
		
		//17. 특정 요소값 변경 : set
		list.set(0, "lee");
		System.out.println(list.toString()); // => [lee, robin, aaa, sss]
		
		
		System.out.println();
		
		//18. 요소들을 순차적으로 얻어오기
		//1) for문
		for (int i = 0; i < list.size(); i++) {
			String t = list.get(i);
			System.out.println(t);
		}
		
		System.out.println();
		
		//2) 확장포문
		for(String t : list) {
			System.out.println(t);
		}
		
		
		System.out.println();
		
		//19. 경우에 따라서는 list를 배열로 변환하는 경우
		//list를 배열로 변환
		//toArray = 내부적으로 배열에 복사함
		String[] arr = new String[list.size()]; //리스트 개수와 같은 크기 배열
		list.toArray(arr); //리스트의 요소값을 배열에 복사
		
		System.out.println(list.toString());
		
		//배열객체의 요소값들을 문자열로 내보내는 static 메소드
		System.out.println(Arrays.toString(arr));
		
		//19-1. 배열 -> list
		String[] bbb = new String[] {"sam", "bin", "hong"};
		//ArrayList<String> list7 = (ArrayList<String>) Arrays.asList(bbb); //java.lang.ClassCastException
		//오류 이유 => Arrays.asList 는 지가 진짜 ArrayList인지 LinkedList인지 뭔지 모름
		//타입캐스팅을 해도 오류남
		//때문에 그것의 조상인 List로 받아야함!
		List<String> list7 = Arrays.asList(bbb);
		System.out.println(list7.toString());

Array와 ArrayList의 차이점

Array

  • 데이터 삽입/삭제 시 위치를 직접 이동시켜야함
  • 한번 정해진 배열의 크기변경은 불가함

ArrayList

  • 데이터 삽입/삭제 시 위치 자동 이동
  • 크기 변경이 유동적임

[2] LinkedList

사용방법은 arrayList와 같음
성능의 차이가 있음 빈번하게 요소를 추가/삭제를 할때 속도가 빠르다 => ArrayList 성능이 지금은 많이 향상돼서 굳이 고민하지않고 그냥 arrayList쓴다

단점 : 특정 요소값을 얻어올 때는 느리다
특정요소를 찾아와 하면 그 위치로 바로 못가고 0번부터 찾아가야됨 -> 검색할때 시간 오래걸림

내부적으로 LinkedList은 실제로 옆에 있지않지만 preview와 next를 들고 있어서 연결된 거 처럼 있다
새로 추가 삭제되면 preview와 next의 주소값만 바꾸면 된다 => 속도가 빠름

LinkedList<String> linkList = new LinkedList<>();
		
linkList.add("aaa");
linkList.add("bbb");
linkList.add("ccc");
		
linkList.remove(1);
		
System.out.println(linkList.toString());
		
//LinkedList에만 있는 메소드
linkList.addFirst("sam");
linkList.addLast("robin");
System.out.println(linkList.toString());

[3] Vector

ArrayList와 완전 같음
ArrayList와 딱 하나 다른점 -> 동기화 처리가 되어있다 -> add가 되는 도중 delete되는 것을 막을 수 있다

Vector<String> vector = new Vector<>();	
vector.add("aaa");
System.out.println(vector.toString());

참고사항
ArrayList, LinkedList, Vector 클래스 모두 List 인터페이스를 구현한 클래스다
즉, List인터페이스는 위 3개클래스의 부모가 됨
부모참조변수로 자식객체를 참조할 수 있음 [up casting]

List<String> listL = null;
		
listL = new ArrayList<>();
listL = new LinkedList<>();
listL = new Vector<>();
//일부러 이렇게 쓰는 경우 많음 나중에 확장되거나 변경될 경우를 대비해서



Set

순서 X, 인덱스 X, 중복 X

[1] HashSet

데이터 넣고 뺄땐 성능 최고, 성능이 가장 우수

[2] TreeSet

값의 오름차순으로 저장되어짐 - 성능 중간쯤


내가 먼저 저장한 값보다 작으면 왼쪽 크면 오른쪽에 저장
읽을 땐 맨 앞에 있는 노드부터 읽음 (꼭지점 부터 읽는 거 아님)



import java.util.*;


public class SetTest {

	public static void main(String[] args) {

		//Set : 순서 X, 인덱스 X, 중복 X
		
		//Set<String> set = new Set(); //error 인터페이스는 객체생성 불가
		
		//Set인터페이스를 구현한 하위클래스
		//HashSet, TreeSet , LinkedHashSet
		
		//[1] HashSet
		//데이터 넣고 뺄땐 성능 최고
		
		//HashSet<String> set = new HashSet<>(); //성능이 가장 우수
		//TreeSet<String> set = new TreeSet<>(); //값의 오름차순으로 저장되어짐 - 성능 중간쯤 
		//내가 저장한 값보다 작으면 왼쪽 크면 오른쪽에 저장

		LinkedHashSet<String> set = new LinkedHashSet<>(); //값을 저장한 순서대로 - 성능 최하
		
		
		//1. 요소추가
		set.add("aaa");
		set.add("eee");
		set.add("ccc");
		set.add("ddd");
		set.add("bbb");
		set.add("ccc"); //중복데이터를 추가해보기 - 무시됨
		
		//2. 요소 출력 및 요소값 확인
		System.out.println(set.size() + " : " + set.toString());
		// => 5 : [aaa, ccc, bbb, eee, ddd]
		
		//3. 요소값을 얻어오는 기능 .get() 이 없음
//		set.get(); // error - why? 인덱스번호가 없어서 못찾아옴
		
		//일반적으로는 set의 요소 하나를 얻어오기보다는
		//모든 요소들을 순차적으로 얻어오는 경우가 많음
		
		//순차적으로 요소값을 얻어오기
		//1) for이용 불가! - 인덱스번호 없어서
		
		//2) 확장 for 가능
		for(String t : set) {
			System.out.println(t);
		}
		
		System.out.println();
		
		//3) iterator(반복자) 이용
		Iterator<String> datas =set.iterator();
		System.out.println(datas.next());
		
		while(datas.hasNext()) {
			String s = datas.next();
			System.out.println(s);
		}
		
		System.out.println();
		
		//4) 배열로 변환하여 접근
		String[] aaa = new String[set.size()];
		set.toArray(aaa); //index가 생겨서 for문 돌릴 수 있게됨
		
		System.out.println(aaa[0]);
		System.out.println(aaa[1]);
		System.out.println(aaa[2]);
		
		
		
		
		
		//사용자 정의 클래스를 set요소로 사용해보기
		//중복 체크 될까?
		HashSet<Person> p = new HashSet<>();
		p.add(new Person("sam",20));
		p.add(new Person("sam",20));
		
		System.out.println(p.size()); //2개 
		
		//set은 중복값을 허용안하는데
		//Set이 객체가 중복되었다고 판단하는 기준은.
		//그 객체의 기능메소드 중 .hashCode()와 .equals()메소드의 결과가 같을때임.
		
		
		HashSet<String> set2 = new HashSet<>();
		
		set2.add(new String("aa"));
		set2.add(new String("aa"));

		System.out.println(set2.size());
		
		
	}

}

class Person{
	String name;
	int age;
	
	////////두개를 오버라이드 해서 만들면 내가 원하는 것으로 중복체크/////////
	@Override
	public int hashCode() {
		return age;
	}
	
	@Override
	public boolean equals(Object obj) {
		Person p =(Person)obj;
		return this.name.equals(p.name);
	}
	//////////////////////////////
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
}

[3] LinkedHashSet



Map

Map : key - value 쌍(Entry라 부름)으로 데이터 저장

import java.util.*;
import java.util.Map.Entry;

public class MapTest {

	public static void main(String[] args) {

		//Map : key - value 상으로 데이터 저장 (Entry라 부름)
		
		//Map도 인터페이스에서 바로 객체생성 불가능
		//Map 인터페이스를 구현한 하위 클래스들
		//HashMap, TreeMap, LinkedHashMap, HashTable
		
		//[1] HashMap
		//HashMap <key, value>
		//가장 성능이 좋음
		//HashMap<String, String> map = new HashMap<>();
		
		//[2] TreeMap
		//key값을 오름차순으로 저장
		//성능 중간 정도
		//TreeMap<String, String> map = new TreeMap<>();
		
		//[3] LinkedHashMap
		//저장된 순서 대로 
		//성능 최하
		//TreeMap<String, String> map = new TreeMap<>();
		
		//[4] HashTable
		// HashMap과 동일 , 동기화 처리가 되어 있음
		TreeMap<String, String> map = new TreeMap<>();

		
		//1. 요소추가
		map.put("name", "sam");
		map.put("id", "abcd");
		map.put("passWd", "1234");
		map.put("kkk", "sam"); //데이타 중복, 키값 x => 추가
		map.put("kkk", "hong"); //키값 중복되면 새로 추가되지 않고 그 위치값의 값이 변경됨
		
		//2. 요소개수
		System.out.println("요소 개수: "+map.size());
		
		//3. 요소 얻어오기
		System.out.println(map.get("name"));
		System.out.println(map.get("id"));
		System.out.println(map.get("passWd"));
		System.out.println(map.get("kkk"));
		System.out.println();
		
		//4. 순서대로 요소값 출력
		//1) for문 불가 - index번호 없어서
		
		//2) 확장 for문 불가 - 내부적으로 key값을 제어할 방법이 없음
		
		//3) 키 값들만 Set객체로 우선 얻어와서 반복문으로 처리
		Set<String> keys = map.keySet(); 
		
		//3.1) key들을 가진 Set 컬렉션 객체를 반복문으로 접근
		for(String t : keys) {
			System.out.println(map.get(t));
		}
		System.out.println();
		
		//3.2) key들을 가진 Set 컬렉션 객체의 반복자 iterator 이용
		Iterator<String> datas = keys.iterator();
		while (datas.hasNext()) {
			String k = datas.next();
			System.out.println(map.get(k));
		}
		System.out.println();
		
		//4) Map객체를 Set 객체로 변환하여 접근
		//Map의 요소객체(키 - 밸류)인 Entry들을 가진 Set으로 변환
		Set<Entry<String, String>> entries = map.entrySet();
		for(Entry<String, String> t : entries) {
			System.out.println(t.getKey()+ ":" + t.getValue());
		}
		
		//5. 요소삭제
		map.remove("kkk");
		System.out.println(map.toString());
		
		System.out.println();
		///////////////////////////////////////
		//키값을 그냥 정수 숫자로 할 수도 있음
		HashMap<Integer, String> map2 = new HashMap<>();
		map2.put(1, "aaa");
		map2.put(2, "aaa");
		map2.put(3, "aaa");
		
		//사용자 정의 클래스를 value로 사용 할 수 있음
		HashMap<String, Person> map3 = new HashMap<>();
		map3.put("사장", new Person("sam", 50));
		map3.put("부장", new Person("kim", 50));
		map3.put("과장", new Person("lee", 50));
		
		
		
		
	}

}

[1] HashSet

가장 성능이 좋음

[2] TreeSet

key값을 오름차순으로 저장, 성능 중간 정도

[3] LinkedHashSet

저장된 순서 대로, 성능 최하

[4] HashTable

HashMap과 동일 , 동기화 처리가 되어 있음



CollectionsClass

Collections Class의 유용한 static 기능 메소드

Collections.sort()와 Collections.shuffle()

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

public class CollectionsClass {

	public static void main(String[] args) {
		
		ArrayList<String> datas = new ArrayList<>();
		datas.add("name");
		datas.add("nice");
		datas.add("hello");
		datas.add("put");
		datas.add("good");
		datas.add("ios");
		System.out.println(datas.toString());
		
		//1) Collections.sort() : 오름차순 정렬
		Collections.sort(datas);
		System.out.println(datas.toString()); 
		
		//2) Collections.shuffle() : 요소 뒤집기
		//random 대신~쓰면 개 편함
		Collections.shuffle(datas);
		System.out.println(datas.toString()); 
		
		
	}
	
}

Iterator 인터페이스

  • 컬렉션에 저장된 일부데이터만 사용하는 것이 아니라 모든 데이터를 사용할 때 편리한 객체
  • 저장된 데이터의 위치 정보를 포함한 커서 존재, 인덱스 사용 하지 않고도 데이터에 접근
  • 모든 데이터에 순차적으로 접근할 목적으로 사용하는 iterator을 컬렉션뷰(Collection View) 라고 한다

interator 메서드

메서드설명
hasNext()커서 다음 요소가 있는지 확인
next()커서 다음 요소 반환 후 다음으로 아동
remove()커서 다음 요소 삭제

사용 예시

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

interator<String> iter = list.interator();
while(iter.hasNext()){
	system.out.println(iter.next());
}
profile
보조기억장치

0개의 댓글