본문 바로가기

Java

Java(16) - 컬렉션, 제네릭, ArrayList, LinkedList

728x90
반응형

1) 컬렉션

   1-1) 제네릭(Generic)

   1-2) 컬렉션 프레임워크

   1-3) ArrayList

   1-4) LinkedList

2) 예제 풀이

 

 

 

 

1) 컬렉션

1-1) 제네릭(Generic)

 

 

 

 

 

 

 

1-2) 컬렉션 프레임워크

 

 

 

 

 

 

1-3) ArrayList

 

 

 

1-4) LinkedList

 

LinkedList는 헤더는 인덱스 0번의 주소값을 가지고 있고, 각 배열의 인덱스는 자신의 다음번째 인덱스의 값을 가리키는 주소값을 가지고 있다!

따라서 중간에 새로운 값을 넣을 경우, 주소값만 이어주면 되기에 데이터 삽입 면에서 훨씬 용이하다는 장점이 있다!

 

 

 

 

2) 예제 풀이

패키지 chapter12.object

Calendar_Test.class

package chapter12.object;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class Calendar_Test {

	public static void main(String[] args) {
		GregorianCalendar today = new GregorianCalendar();
		System.out.printf("%d년 %d월 %d일 %s %d시 %d분 %d초",
				today.get(Calendar.YEAR),
				today.get(Calendar.MONTH) + 1,
				today.get(Calendar.DATE),
				today.get(Calendar.AM_PM) == Calendar.AM ? "오전" : "오후",
				today.get(Calendar.HOUR),
				today.get(Calendar.MINUTE),
				today.get(Calendar.SECOND));
		System.out.println();
		System.out.println("=================");
		
		GregorianCalendar today2 = new GregorianCalendar();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 M월 d일 a hh:mm:ss");
		String result = sdf.format(today2.getTime());
		System.out.println(result);
		System.out.println("=================");
		
		LocalDate today3 = LocalDate.now();
		LocalTime now = LocalTime.now();
		System.out.printf("%d년 %d월 %d일 %d시 %d분 %d초",
				today3.getYear(),
				today3.getMonthValue(),
				today3.getDayOfMonth(),
				now.getHour(),
				now.getMinute(),
				now.getSecond());

	}

}

 

 

 

Record_Test.class

package chapter12.object;

record Member(String name, int memberCode) {}

/*
     record
     불변(immutable) 객체를 쉽게 생성할 수 있도록 하는 유형의 클래스
       - 모든 필드에 final 선언
       - 필드 값(멤버 변수)을 모두 포함한 생성자
       - 접근자 메서드(getter)
       
     * 자동생성(자동으로 만들어주는 메서드)
       - 생성자 메서드
       - getters 메서드
       - equals 메서드
       - hashCode 메서드
       - toString 메서드
     
     * 레코드 제한
       - 레코드는 암묵적으로 final 클래스(상속불가)이며, abstract 선언 불가
       - 다른 클래스를 extends(상속) 받을 수 없음
       - 인터페이스 구현(implements)은 가능
     
     * (중요 포인트) 멤버 변수를 필드 값이라고 부른다!!(멤버 변수와 필드 값은 같은 말이다.)
*/

public class Record_Test {

	public static void main(String[] args) {
		Member member = new Member("홍길동", 1234);
		System.out.println(member);
		System.out.println(member.name());
		System.out.println(member.memberCode());

	}

}

 

 

 

 

패키지 chapter13.generic

Generic_Test1.class

package chapter13.generic;

class Coffee {}
class Juice {}

class BeverageBox {
	// 여기서 "Object"는 최상위 클래스이다!
	private Object[] beverage; // Object 형 배열("Object Type"만 들어가는 배열)
	
	public BeverageBox(Object[] beverage) {
		this.beverage = beverage;
	}
	
	public Object getBeverage(int index) {
		return beverage[index];
	}
}

class BeverageBox2<T> {
	private T[] beverage;
	// static T t;  // --> "static"에서 사용 불가
	
	public BeverageBox2(T[] beverage) {
		this.beverage = beverage;
		// T t = new T();  // --> T 타입으로 인스턴스 생성 불가
	}
	
	public T getBeverage(int index) {
		return beverage[index];
	}
}

public class Generic_Test1 {

	public static void main(String[] args) {
		Coffee[] arr = {
				new Coffee(),
				new Coffee()
		};
		BeverageBox box = new BeverageBox(arr);
		Coffee coffee = (Coffee) box.getBeverage(0);
		// Juice juice = (Juice) box.getBeverage(1);
		
		BeverageBox2<Coffee> box2 = new BeverageBox2<Coffee>(arr);
		Coffee coffee2 = box2.getBeverage(0);
		// Juice juice2 = box2.getBeverage(1); // 제네릭을 통해 위에서 이미 Coffee 타입으로 정의하겠다고 하였기에 Juice 등의 다른 테이터 타입을 지정할 시 컴파일 시점에서 에러를 출력한다!

	}

}

 

 

 

Generic_Test2.class

package chapter13.generic;

import java.util.ArrayList;

public class Generic_Test2 {

	public static void main(String[] args) {
		// ArrayList는 다른 타입이어도 배열에 해당 요소가 들어갈 수 있다!
		// generic 타입을 명시하지 않을 경우
		ArrayList arNum = new ArrayList();
		arNum.add(1);
		arNum.add("문자열");
		
		int value = (int) arNum.get(0);
		// int temp = (int) arNum.get(1);  // 해당 라인은 에러 코드(err)이다. 그렇기에 맞는 타입을 신경써줘야 함.
		
		// generic 타입을 명시할 경우
		ArrayList<Integer> arNum2 = new ArrayList<Integer>();
		arNum2.add(1);
		// arNum2.add("문자열");  // 컴파일 시점에서 타입 체크 후 에러 발생
		int value2 = arNum2.get(0);
		System.out.println(value2);

	}

}

 

 

 

 

Generic_Test3.class

package chapter13.generic;

import java.util.ArrayList;

class Fruit {}
class Apple extends Fruit {}
class Banana extends Fruit {}

class FruitBox<T> {
	ArrayList<T> fruits = new ArrayList<>();
	
	public void add(T fruit) {
		this.fruits.add(fruit);
	}
}

class FruitBox2<T, U> {
	ArrayList<T> apples = new ArrayList<>();
	ArrayList<U> bananas = new ArrayList<>();
	
	public void add(T apple, U banana) {
		apples.add(apple);
		bananas.add(banana);
	}
}

public class Generic_Test3 {

	public static void main(String[] args) {
		// generic 타입에서도 다형성의 원리가 그대로 적용된다!
		FruitBox<Fruit> box = new FruitBox<>();
		box.add(new Fruit());
		box.add(new Apple());
		box.add(new Banana());
		
		// 복수 generic 타입 사용
		FruitBox2<Apple, Banana> box2 = new FruitBox2<>();
		box2.add(new Apple(), new Banana());
		box2.add(new Apple(), new Banana());

	}

}

 

 

 

Generic_Method1.class

package chapter13.generic;

class Point<T, V> {
	T x;
	V y;
	
	Point(T x, V y) {
		this.x = x;
		this.y = y;
	}
	
	public T getX() {
		return x;
	}
	public V getY() {
		return y;
	}
}

public class Generic_Method1 {

	// Integer, Double은 둘 다 Number 클래스의 자식 클래스로 상속 관계이다!
	public static void main(String[] args) {
		Point<Integer, Double> p1 = new Point<Integer, Double>(0, 0.0);
		Point<Integer, Double> p2 = new Point<>(10, 10.0);
		
		double rect = Generic_Method1.makeRectangle(p1, p2);
		System.out.println("두 점으로 만들어진 사각형의 넓이: " + rect);

	}
	
	// 아래 메서드가 "generic method"이다! --> 따라서 "generic type"을 사용하겠다는 것을 static 키워드 뒤에 "<T, V>"로 반드시 명시해야 한다!(안쓰면 에러를 발생시킨다.)
	static <T, V> double makeRectangle(Point<T, V> p1, Point<T, V> p2) {
		double left = ((Number) p1.getX()).doubleValue();
		double right = ((Number) p2.getX()).doubleValue();
		double top = ((Number) p1.getY()).doubleValue();
		double bottom = ((Number) p2.getY()).doubleValue();
		
		double width = right - left;
		double height = bottom - top;
		
		return width * height;
	}

}

 

 

 

패키지 chapter14.collection

ArrayList_Test1.class

package chapter14.collection;

import java.util.ArrayList;

public class ArrayList_Test1 {

	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>();  // List<Integer> list = new ArrayList<>();  --> 이렇게 코드를 작성해도 코드가 동일하게 동작함!
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(2, 5);  // index 2에 5의 값을 추가
		for (int i = 0; i < list.size(); i++) {
			System.out.print(list.get(i) + " ");
		}
		System.out.println();
		
		list.remove(0);  // index 0의 값을 제거
		for (Integer i : list) {
			System.out.print(i + " ");
		}
		System.out.println();
		
		// index 1의 요소 return
		System.out.println("get(index): " + list.get(1));
		// list의 사이즈 return
		System.out.println("size(): " + list.size());

	}

}

 

 

 

 

ArrayList_Test2.class

package chapter14.collection;

import java.util.ArrayList;
import java.util.Arrays;

public class ArrayList_Test2 {

	public static void main(String[] args) {
		ArrayList<Integer> arNum = new ArrayList<>(Arrays.asList(1, 2, 3));
		ArrayList<Integer> arNum2 = new ArrayList<>(Arrays.asList(4, 5, 2));
		ArrayList<Integer> arNum3 = new ArrayList<>(Arrays.asList(1, 2));

		// addAll - 합집합(여기서 말하는 합집합은 대상이 되는 두 개의 ArrayList의 요소를 모두 가져와서 출력하는 것을 의미함)
		System.out.print("합집합 => ");
		ArrayList<Integer> arNumAdd = new ArrayList<>(arNum);
		arNumAdd.addAll(arNum2);
		for (Integer i : arNumAdd) {
			System.out.print(i + " ");
		}
		System.out.println();

		// removeAll - 차집합
		System.out.print("차집합 => ");
		ArrayList<Integer> arNumRemove = new ArrayList<>(arNum);
		arNumRemove.removeAll(arNum2);
		for (int i = 0; i < arNumRemove.size(); i++) {
			System.out.print(arNumRemove.get(i) + " ");
		}

		// retainAll - 교집합
		System.out.print("\n교집합 => ");
		ArrayList<Integer> arNumRetain = new ArrayList<>(arNum);
		arNumRetain.retainAll(arNum2);
		for (Integer i : arNumRetain) {
			System.out.print(i + " ");
		}

		// containsAll - 부분집합
		System.out.print("\n부분집합 => ");
		ArrayList<Integer> arNumContain = new ArrayList<>(arNum);
		if (arNumContain.containsAll(arNum2)) {  // arNum2는 arNum의 부분집합이 아닌 반면 arNum3는 arNum의 부분집합이다!
			System.out.println("부분집합 O");
		} else {
			System.out.println("부분집합 X");
		}

	}

}

 

 

 

 

ArrayList_Test3.class

package chapter14.collection;

import java.util.ArrayList;

record Student(String name, int stdNum) {}

public class ArrayList_Test3 {

	public static void main(String[] args) {
		ArrayList<Student> stList = new ArrayList<>();
		stList.add(new Student("홍길동", 20241001));
		stList.add(new Student("이순신", 20241002));
		stList.add(new Student("강감찬", 20241003));
		
		for (int i = 0; i < stList.size(); i++) {
			System.out.println(stList.get(i));
		}

	}

}