본문 바로가기

백엔드개발자 준비하기

[백엔드개발자 준비하기] 컬렉션

리스트 순서O 중복O (키-순서대로인덱스-값으로 값 판단)
셋(집합) 순서X 중복X
맵 순서X 키중복X 값중복O 

 

[리스트]
배열은 자료형이지만 리스트는 클래스 객체이다
리스트 내부에 메소드가 전부 정의되어 있어서 그것을 사용하는 것 ex)size
처음 생성할 때 자료형을 설정해주는데 앞쪽에 데이터타입을 정해두면 그 자료형으로 사용 가능하다(원래는 뒤쪽에도 데이터타입 설정하여야 하는데 생략가능)
new ArrayList<>와 같이 어디 담지 않고 혼자 생성할 때는 <>안에 자료형을 꼭 설정해주어야 함 그러나 이렇게 사용할 경우 따로 담은 곳이 없어서 새로 생성할 때마다 다 다른공간에 담기므로 리스트를 사용하는 의미가 없다

처음 생성할 때 제네릭 타입을 사용할 것 같으면
내부의 메소드를 사용할 때 필요한 자료형으로 다운캐스팅 하여 사용가능(잘 안씀)

리스트는 넣는만큼 공간이 유동적으로 늘어남 길이도 계속된 추가 및 삭제에도 유동적

배열에서는 6개의 배열 중 첫번째 인덱스를 삭제하면 갯수는 6개 그대로고 첫번째 인덱스에 null이 들어가는 형식인데 리스트는 첫번째 인덱스를 삭제하면 갯수가 5개로 바뀌고 한칸씩 당겨지며 정렬까지 다시해줌

리스트랑 셋은 상위에 컬렉션이 있고 그 안에 add 메소드가 구현되어있음 그걸 각자 들고와서 오버라이드 해서 사용함
맵은 컬렉션이 아니라 put을 사용함
셋은 값을 꺼내려면 전체 반복을 돌려서 내가 원하는 값이 나올때까지 진행해야함
셋은 키값을 따로 지정하기 않기때문에 넣고 빼고할때 시간이 단축된다 다른 두개에 비해 속도가 빠르다

 

[예시]

public class ArrayListMain {
	
	public static void main(String[] args) {
		List<String> strList = new ArrayList<>();
	
		// *값 추가
		strList.add("java");
		strList.add("python");
		System.out.println(strList);
		
		// 값 원하는 위치에 추가
		strList.add(1, "android");
		System.out.println(strList);
		
		// *해당 인덱스의 값을 추출
		System.out.println(strList.get(0));
		String lang = strList.get(1);
		System.out.println(lang);
		
		// 리스트에 해당 값이 있는지 확인(T, F)
		System.out.println(strList.contains("C++"));
		System.out.println(strList.contains(lang));
		
		// 값 수정
		strList.set(2, "javascript");
		System.out.println(strList);
		
		// *값 삭제
		strList.remove("android");
		System.out.println(strList);
		strList.remove(1);
		System.out.println(strList);
		
		// *리스트의 크기 확인
		System.out.println(strList.size());
		
		// 리스트가 비었는지 확인
		System.out.println(strList.isEmpty());
		
		// 리스트 초기화
		strList.clear();
		System.out.println(strList.isEmpty());
		
		/* 
		 * *배열을 리스트로 변환
		 * Array.asList(배열);
		 */
		String[] langs = {"java", "C++", "python", "javascript"};
		List<String> tempList = Arrays.asList(langs);
		strList.addAll(tempList);
		strList.addAll(2, tempList);
		System.out.println(strList);
		
		// *해당 값의 위치(index) 왼쪽부터 찾기
		int findindexLeft = strList.indexOf("python");
		System.out.println(findindexLeft);

		// *해당 값의 위치(index) 오른쪽부터 찾기
		int findindexRight = strList.lastIndexOf("java");
		System.out.println(findindexRight);
		
		// fromIndex 부터 toIndex 전까지 부분만 리스트를 추출
		List<String> subList = strList.subList(1, 4);
		System.out.println(subList);
		
		System.out.println();
		
		///////////////////////////////////////////////////////////////////
		
		strList.set(1, "java");
		System.out.println(strList);
		strList.subList(strList.indexOf("java") +1, strList.size()).indexOf("java");
		
		
		///////////////////////////////////////////////////////////////////
		
		// =============<< 반복 >>=============
		// 일반 반목문
		for (int i = 0; i < strList.size(); i++) {
			System.out.println("[" + i + "] :" + strList.get(i));
		}
		System.out.println();
		
		// forEach
		for(String str : strList) {
			System.out.println("[값] : " + str);
		}
		System.out.println();
		
		// 람다식 forEach
		strList.forEach(str -> System.out.println("[값2] : " + str));
		System.out.println();
		
		// 반복자
		// 넥스트 하면 무조건 그 다음값을 꺼냄 그래서 한바퀴 돌고 다시 쓰려면 다시 값을 넣어줘야 함
		Iterator<String> iterator = strList.iterator();
		while(iterator.hasNext()) {
			String lang2 = iterator.next();
			System.out.println("[값3] : " + lang2);
		}
		
		iterator = strList.iterator();
		while(iterator.hasNext()) {
			String lang2 = iterator.next();
			System.out.println("[값3] : " + lang2);
		}
	}
}

 

[셋]

셋은 겟 메소드가 없다
따라서 포이치 문을 돌려서 전부 비교를 해야한다
순서가 없다
중복이 되지 않는다
애드 올을 사용하여 리스트를 받아 넣을수도 있다
마찬가지로 리스트 내에 중복값이 있더라도 중복값을 제거하고 넣는다
맵은 컬렉션을 상속받지 않기때문에 사용불가능하다

이터레이터
이터레이터 안에 셋의 변수들을 넣어서 해즈 넥스트를 사용하여 다음이 있는지 확인하고 차례차례 꺼내 사용한다

 

[예시]

public class SetStringMain {

	public static void main(String[] args) {
		Set<String> setStr = new HashSet();
		List<String> listStr = new ArrayList<>();
		
		listStr.add("임나영");
		listStr.add("이강용");
		listStr.add("임나영");
		listStr.add("임나영");
		
		System.out.println(listStr);

		setStr.add("김상현");
		setStr.add("강대협");
		setStr.add("손지호");
		setStr.add("최해혁");
		setStr.addAll(listStr);

		System.out.println(setStr);
		String searchName = "손지호";

		for (String name : setStr) {
			if (name.equals(searchName)) {
				System.out.println(name);
			}
		}
		
		Iterator<String> iterator = setStr.iterator();
		while(iterator.hasNext()) {
			String n = iterator.next();
			if(n.equals(searchName)) {
				System.out.println(n);
			}
		}
	}
}


[맵]
맵은 순차적으로 도는게 아니라서 포문을 사용할수 없다
또한 배열이나 리스트도 아니라서 포이치문도 사용할수 없다
따라서 셋을 사용하여 배열형태로 만들어줘야한다
키셋은 키값만 셋으로 만들어주는 것 따라서 키셋을 사용하여 키값을 셋으로 만들면 해당 셋에서 키값따라 벨류값을 얻어낼수 있다 
ex) Map.keySet(), Map.get(키값)

해시맵이라서 키값에 해시코드 사용
해시코드값은 알파벳으로 정렬이 되기 때문에 순서대로 출력됨
문자열처럼 글자의 조합으로 키값이 있으면 순서대로 출력되지 않음(무조건 키값의 해시코드에 대한 정렬로 나옴)

엔트리셋을 사용하면 키값과 벨류를 꺼내면 통채로 들고옴
맵에 있는 것을 전부 꺼내면 그것들은 전부 엔트리로 이루어진 셋이고
하나를 꺼내면 그것은 엔트리이다

맵으로 벨류값에 오브젝트를 넣어놓으면 모든 자료형이 사용가능하다(벨류에 리스트를 넣을수도 있음)
만약 그렇게 넣어놓은 것들을 꺼내서 사용하려면 그것들의 자료형은 오브젝트로 업캐스팅 되어있는 상황이기 때문에 다시 다운캐스팅 하여 사용하여야 함

 

[예시]

public class HashMapTest {

	public static void main(String[] args) {
		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put("username", "aaa");
		dataMap.put("password", "1234");
		dataMap.put("name", "김준일");
		dataMap.put("email", "aaa@gmail.com");
		
		List<String> hobby = new ArrayList();
		hobby.add("골프");
		hobby.add("축구");
		hobby.add("농구");
		hobby.add("음악감상");
		
		dataMap.put("hobbys", hobby);
		
		System.out.println(dataMap);
		
		List<String> list = (List<String>) dataMap.get("hobbys");
		System.out.println(list.get(0));
	}
}