자바

[Java] Collections - List

Atriel 2023. 11. 22. 16:07

List 계열 주요 메서드

 

 

ArrayList

실제 배열을 기반으로 구현되어 있지만, 기존의 배열의 불편함만 없앤 컬렉션 List의 후손으로

초기 저장용량은 10으로 자동 설정 / 따로 지정 가능

저장 용량을 초과한 객체들이 들어오면 자동으로 증가 / 고정도 가능

동기화(Synchronized)를 제공하지 않음

→ 성능상 좋아짐!

 

(둘다 상속 받아서 쓰면 됨)

1.Comparable

객체에 상속받아서 compareTo() 메소드를 오버라이딩

→ 한개의 정렬만 가능

 

2.Comparator

Comparator를 상속받아 compare()메소드를 오버라이딩

→ 여러 개의 정렬 가능

 

Alt + shift + S로 간단하게 Member 클래스 생성

 

package com.multi.ex02.collections_list;

//은행 정보

//Comparable : 정렬을 지원하는 interface

public class Member implements Comparable<Member> {
	private String id;
	private String name;
	private int age;
	private double account; // 계좌 잔액
	public Member() {
		super();
	}
	public Member(String id, String name, int age, double account) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.account = account;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getAccount() {
		return account;
	}
	public void setAccount(double account) {
		this.account = account;
	}
	@Override
	public String toString() {
		return "Member [id=" + id + ", name=" + name + ", age=" + age + ", account=" + account + "]";
	}
	
	//객체를 비교시 정렬 기준을 정하는 메소드
	@Override
	public int compareTo(Member o) { // compareTO : 작으면 -1, 같으면 0, 크면 1
		// id 기준으로 오름차순 정렬
		return id.compareTo(o.getId());
		
		// id 기준으로 내림차순 정렬
		//return o.getId().compareTo(id);
	}
}

 

 

ListBasic 클래스

package com.multi.ex02.collections_list;

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

public class ListBasic {
//	ArrayList - ★★★★★ 추천
//	 -> 주로 ArrayList '만' 사용하는데, 이유는 DB에서 데이터를 담고 탐색 용도로 많이 활용함
//	- 장점 : 탐색속도가 빠르고, 메모리를 적게 차지한다. 
//	- 단점 : 삽입, 삭제, 수정이 느리다. 

//	LinkedList
//	 -> 삽입 삭제가 빈번하지 않으면 사용하지 않음. -> 이럴 경우가 많이 없거나 다른 컬랙션(Map)을 사용함
//	- 장점 : 삽입, 삭제, 수정이 빠르다.
//	- 단점 : 탐색속도가 느리고, 메모리를 많이 차지한다.

//	Vector
//	-> Thread safe 할때 사용하나 더 좋은 컬랙션이 많다. 잘 안쓴다.
	
	public static void main(String[] args) {
		Member[] memberArray = new Member[3];
		memberArray[0] = new Member("testID1", "피카츄", 23, 60000.212);
		memberArray[1] = new Member("testID2", "이상해씨", 32, 53123.233);
		memberArray[2] = new Member("testID3", "꼬부기", 25, 41212.322);
		//memberArray[3] = new Member("testID4", "파이릿", 28, 31552.12);
		
		// 배열의 단점
		// 1. 배열의 크기를 지정해야하고, 크기보다 커지면 새로운 배열을 생성하고 복사 필요
		// 2. 중간에 데이터 삽입/삭제가 어렵다. -> 반드시 빈데이터를 메꿔야한다!
		// 3. 복사도 어렵고, 사용자 실수가 많았다. 
		// 결론 : 프로그래머라면 누구든 고통 받았다.
		
		//// List
		
		//1. 초기화
		// - 정석적인 사용법은 List<> 로 타입을 선언하는것 (or ArrayList<>)
		List<String> strList = new ArrayList<>(); // 문자열 배열,		 	1. Type이 생략된 초기화 문
		List<Integer> intList = new ArrayList<Integer>(); // 숫자 배열, 		2. Type이 생략되지 않은 자바 1.6이전 문법
		ArrayList<Member> memberList1 = new ArrayList<>(); //				3. 컬렉션 이름이 생략되지 않은 형태
		LinkedList<Member> memberList2 = new LinkedList<>(); //					-> 컬렉션의 고유 메소드를 사용할때
		
		memberList2.addFirst(null);  //Deque의 고유 메서드 사용가능
		memberList2.addLast(null);
		
		// 권장 문법
		List<Member> list = new ArrayList<>();
		
		
		
		// 2. 배열에서 List로 변환하는 방법
		// 1) Array.asList() 사용, 제네릭 사용
		List<Member> mList1 = Arrays.asList(memberArray);  // 읽기 전용! 추가, 수정, 삭제가 불가능하다.
		List<Member> mList2 = new ArrayList<>(Arrays.asList(memberArray)); //컬렉션으로 다시 생성해야 한다.
		
//		mList1.add(new Member("TestID4", "야돈", 22, 41212.22)); //Error : UnsupportedOperationException, 읽기전용!
		mList2.add(new Member("TestID4", "고라파동", 25, 31414.1592));
		
		System.out.println(mList1);
		System.out.println(mList2);
		
		// 2) 고전적인 알고리즘 방법
		List<Member> mList3 = new ArrayList<>();
		// Advanced for loop
		for(Member m : memberArray) {
			mList3.add(m);
		}
		System.out.println("mList3 : " + mList3);
		
		// 3) 고전적인 알고리즘 방법2
		List<Member> mList4 = new ArrayList<>();
		// index for loop
		for(int i = 0; i < memberArray.length; i++) {
			mList4.add(i, memberArray[i]); // index를 지정하여 추가
		}
		System.out.println("mList4 : " + mList4);
		
		//출력하는 방법
		//List 의 특징은 toString의 객체정보를 모두 출력할 수 있다. ->출력하면 정보를 볼수 있음
		System.out.println(mList4);
		System.out.println(mList4.toString().replace("],", "],\n"));
		
		//순회 하면서 데이터 출력하는 방법
		for(Member m : mList4) {
			System.out.println(m);
		}
		System.out.println("------------------------------------");
		
		for(int i = 0; i < mList4.size(); i++) {
			System.out.println(mList4.get(i));
		}
		
	}
}

 

 

ListBasic2 클래스

package com.multi.ex02.collections_list;

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

public class ListBasic2 {
	public static void main(String[] args) {
		// 1.선언법
		List<Member> list = new ArrayList<>();
		
		// 2. add를 통한 데이터 삽입
		list.add(new Member("TestID3", "홍길순3", 44, 11110.1));
		list.add(new Member("TestID4", "홍길순4", 21, 143.1));
		list.add(new Member("TestID2", "홍길순2", 22, 100.1));
		list.add(new Member("TestID5", "최길순", 32, 4400.1));
		list.add(new Member("TestID6", "홍길순", 25, 10550.1));
		list.add(new Member("TestID7", "홍길순", 21, 10550.1));
		list.add(new Member("TestID8", "홍길순", 25, 20550.1));
		list.add(new Member("TestID1", "김길순", 25, 10550.1));
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		
		// 2.1 addAll - 컬렉션을 통체로 추가할때
//		list.addAll(list); // 2번 복제된다...
		
		// 3. add메소드의 index를 활용하는 방법
		list.add(0, new Member("TestID9", "홍길순9", 24, 234723));
		
		// -> 0번째 index로 들어가고 ,기존 index들은 알아서 뒤로 이동이 된다.
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		// ! 주의점 : 기존 size를 고려하여 최대 크기 안쪽으로만 삽입 가능
//		list.add(10, new Member("TestID9", "홍길순9", 24, 234234.1));
//		list.add(list.size() - 1, new Member("TestID9", "홍길순9", 24, 234234.1));
//		System.out.println("------------------------------------------------------------");
		
		// 4. list 크기 가져오기
		System.out.println(list.size());
		
		// 5. index로 원하는 순서의 객체 가져오는 방법
		Member member1 = list.get(0);
		System.out.println(member1);
		System.out.println(list.get(3));
		System.out.println(list.get(3).getName());
		System.out.println("------------------------------------------------------------");
		
		// 6. 특정 객체가 list에 존재하는지 확인하는 방법
		// -> 잘 사용하지 않음
		Member member2 = list.get(0);
		System.out.println(list.contains(member1));
		
		// 객체에서 특정 이름을 가진 사람을 찾는 방법
		for(Member m : list) {
			if(m.getName().equals("홍길동")) {
				System.out.println("홍길동 : " + m);
			}
		}
		
		// 7. 특정 객체 삭제하는 방법
		// 1) remove - index로 접근
		Member member3 = list.remove(3);
		System.out.println(member3);
		// 2) remove - 객체로 접근
		boolean result = list.remove(member2);
		System.out.println(result); // true -> 삭제성공
		
		// 8.clear : 데이터 전부 삭제
		//list.clear();
		System.out.println(list.size());
		
		// 9. indexOf : 객체에 해당하는 index 반환
		System.out.println(list.indexOf(member1));
		
		// 10. isEmpty : 비어있는지확인
		System.out.println(list.isEmpty());
		System.out.println(list.size() == 0);
		
		// 11. set : 추가가 아닌 교체
		System.out.println("--------------------------변경 전--------------------------");
		System.out.println(list.toString().replace("],", "],\n"));
		
		
		list.set(0, member2);
		System.out.println("--------------------------변경 후--------------------------");
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		
		// 12. subList : 자르기 용도
		List<Member> list2 = list.subList(0, 3); // index 0부터 3까지 잘라 새로운 컬렉션에 저장
		System.out.println(list2.toString().replace("],", "],\n"));
		
		// ■ 정렬 하는 방법들 ★
		System.out.println("정렬 전");
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		
		// 0. 기본형 + 문자열 의 list일 경우에는 오름차순으로 정렬 가능
		List<Integer> intList = new ArrayList<>();
		intList.add(1);
		intList.add(2);
		intList.add(3);
		
		Collections.sort(intList);
		System.out.println(intList);
		
		// 1. 객체에 Comparable을 구현하여 정렬하는 방법
		Collections.sort(list);
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		
		// 2. Comparator를 구현해 정렬
		// - 장점 : 다양한 방법으로 정렬 기준을 정할수 있음
		System.out.println("나이순 정렬");
		// list.sort 사용법
		// 익명 클래스로 Comparator를 구현하는 방법
		list.sort(new Comparator<Member>() {

			@Override
			public int compare(Member o1, Member o2) {
				return Integer.compare(o1.getAge(), o2.getAge()); //오름차순
//				return Integer.compare(o2.getAge(), o1.getAge()); //내림차순
			}
		});
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		
		System.out.println("이름순 정렬");
		// Collections.sort()
		Collections.sort(list, new Comparator<Member>() {
			@Override
			public int compare(Member o1, Member o2) {
				return o1.getName().compareTo(o2.getName());
			}
		});
		System.out.println(list.toString().replace("],", "],\n"));
		System.out.println("------------------------------------------------------------");
		
		// 3. 람다식 정렬 방법(Java 8 이상)
		// 익명 클래스나 함수를 람다식으로 바꿔 쉽게 표현가능
		// - (01, 02) -> (returnValue) : 람다식 표현
		// - 생소해서 문법 가독성이 살짝 떨어짐
		System.out.println("계좌 잔액순 정렬");
		list.sort((o1, o2) -> (Double.compare(o1.getAccount(), o2.getAccount()))); //오름차순
		list.forEach((m) -> System.out.println(m));
		
		// 4. Stream(= 대용량 데이터 처리 기술)을 통한 정렬 (DB에서 쿼리로 대부분 처리해서 많이 쓸일 없음)
		System.out.println("나이순으로 정렬");
		List<Member> newList = list.stream().sorted((o1, o2) 
				-> (Integer.compare(o1.getAge(), o2.getAge()))).collect(Collectors.toList());
		
		newList.forEach((m) -> System.out.println(m));
		
		// 이름 - 나이 - 계좌 순으로 정렬
		System.out.println("이름 - 나이 - 계좌순 정렬");
		list.sort(new Comparator<Member>() {
			@Override
			public int compare(Member o1, Member o2) {
				int result = o1.getName().compareTo(o2.getName());
				if(result == 0) {
					result = Integer.compare(o1.getAge(), o2.getAge());
				}
				if(result == 0) {
					result = Double.compare(o1.getAccount(), o2.getAccount());
				}
				return result;
			}
		});
		list.forEach((m) -> System.out.println(m));
		
	}
}