본문 바로가기
JAVA/JAVA Note

[JAVA Note] 18. Object

by objade 2022. 11. 6.

 

1. Object 클래스

1) 특징

① 자바의 모든 객체 Object 클래스인스턴스

Object 는 자바에 있는 모든 클래스최상위 슈퍼 클래스

→ 자바의 모든 클래스는 Object 클래스상속받게 되어있음

→ 따로 슈퍼클래스를 지정하지 않으면 자동으로 extends Object 상태임

Object 클래스에 정의된 메서드는 모든 클래스가 오버라이딩 할 수 있음

  * , final제외

④ 자바의 모든 객체 Object 타입으로 참조할 수 있음.

  Object의 배열도 예외가 아님

import java.lang.Object;

class A /*extends Object */{}
class B extends A {}

public class Ex01 {
	public static void main(String[] args) {
		A ob = new B();
		System.out.println(ob.getClass().toString());
		
		B ob2 = (B) ob;
		System.out.println(ob.equals(ob2));
		
		Object ob3 = ob;	// A
		Object ob4 = ob2;	// B
        
       		System.out.println(ob3.getClass());	
		System.out.println(ob4.getClass());
		
		System.out.println(ob3.equals(ob4));
	}
}

 

- 참조업캐스팅 되어도 객체 자신의 정보는 변하지 않음

import java.util.Comparator;
import java.util.Scanner;

class Test extends Object {
	private String str;
	
	public Test(String str) {
		this.str = str;
	}
	
	public String getStr() {
		return str;
	}
	
	@Override
	public String toString() {
		return "비밀";
	}
}

public class Ex02 {
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		Test ob = new Test("휴강");
		
		Runtime rt = Runtime.getRuntime();
		int[] arr = {2, 7, 8, 4, 6};
		
		Comparator<Double> cmp = (a, b) -> (int)(b - a);
		
		Object[] t1 = { sc, ob, rt, arr, cmp };
		
		Object target = t1;

 

- 예시 문제) 위의 코드에서, target으로 시작하여 휴강이라는 문자열을 화면에 출력해보기

 ~ 1

System.out.println(((Test)((Object[])target)[1]).getStr());

~ 2

Object[] t2 = (Object[])t1;
		
for(int i = 0; i < t2.length; i++) {
	if(t2[i] instanceof Test) {
		Test t3 = (Test)t2[i];
		System.out.println(t3.getStr());
	}
}

 

2) Object 클래스의 메서드

toString()

- 객체문자열 형태변환해서 반환해줌

class MyNumber extends Object {
	
	int num;
	
	public MyNumber(int num) {
		this.num = num;
	}

	@Override
	public String toString() {		
		return String.valueOf(num);	
	}

* valueOf() static 메서드이기 때문에 객체없이 클래스에서 바로 호출할 수 있음

 

equals()

- 서로 다른 두개의 객체가 일치하는지를 비교하여 반환해줌

@Override
	public boolean equals(Object obj) {		
		if(obj instanceof MyNumber) {		
			return this.num == ((MyNumber)obj).num;
		}	
		return false;	
	}
}

- this obj를 비교하여, 일치하면 true를 반환하고, 아니면 false를 반환함

- 비교대상 obj의 클래스가 같으면 비교함

- 클래스가 다르면 비교할 필요없이 false를 반환

public class Ex03 {
	public static void main(String[] args) {
		
		MyNumber n1 = new MyNumber(10);		
		MyNumber n2 = new MyNumber(10);	
		
		System.out.println("n1 : " + n1);
		System.out.println("n2 : " + n2);
		System.out.println("n1 == n2 : " + (n1 == n2));		
		// 두 변수가 같은 대상을 바라보는가?
		System.out.println("n1.equals(n2) : " + n1.equals(n2)); 
		// 두 변수의 내용이 같은가?
	}
}

- new 연산자를 사용했다면, 새로운 공간에 객체를 생성함

 

2. Collection

1) Collection Framework

: 다수의 데이터관리하기 위해 자료저장할 수 있는 구조

- 자바는 이 구조를 여러 클래스로 만들어두었고, 편의를 위한 메서드도 준비되어 있음

→ 어떤 종류의 컬렉션이 있는지, 어떻게 사용하는 것인지 익히고, 적재적소에 활용할 수 있도록 연습할 것.

 

2) 종류

List : index로 값에 접근하고, 중복허용

* 배열과의 차이점 : 크기자동으로 조절

Set : index 개념이 없고, 중복허용하지 않음

  Map : index 대신 key 라는 형식을 이용하여 (Value)에 접근함

key value매핑 되어있음

→ 이때, key중복허용하지 않고, value중복허용

import java.util.List;			
import java.util.Map;				
import java.util.Set;

- 각 컬렉션의 특징만을 담고 있는 인터페이스import

- 이 인터페이스들을 구현(implement) 하여 만들어진 하위 클래스들을 이용함

- ArrayList, HashSet, HashMap

List ob1;
Set ob2;
Map ob3;

 

3. List

: 크기변경할 수 있는 배열

1) 특징

- 배열유사하게 사용할 수 있음

- 리스트(및 컬렉션)에는 자료형에 상관없이 모든 데이터 추가할 수 있음

- 리스트에서 어떤 자료형처리할 지를 명시해주는 것이 안전함. → 제네릭 타입

(ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized)

import java.util.ArrayList;	

public class Ex05 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();	
		System.out.println("리스트의 크기 : " + list.size());
		
		list.add(10);
		list.add(20);
		list.add("APPLE");
		list.add(20);		// 중복된 데이터 추가
		
		System.out.println("리스트의 크기 : " + list.size());
		System.out.println(list); 
        
        	Object v1 = list.get(0);	// arr[0]
		Object v2 = list.get(1);	// arr[1]
		System.out.println(v1);
		System.out.println(v2);
	}
}

 

 

~ Human 타입의 클래스 만들기

import java.util.ArrayList;

class Human {
	private String name;
	private int age;
	
	public Human(String name, int age) {
		
		this.name = name;
		this.age = age;
	}
	
	public void show() {
		System.out.printf("이름 : %s, 나이 : %d살\n", name, age);
	}

	@Override
	public String toString() {
		return String.format("이름 : %s, 나이 : %d살", name, age);
	}
}

 

 

~ 리스트 만들기

public class Ex06 {
	public static void main(String[] args) {	
		ArrayList list1 = new ArrayList();
		list1.add(10);
		list1.add(20);
		list1.add(3.14);
		
		Human ob1 = new Human("이지은", 30);
		list1.add(ob1);

		System.out.println(list1);

- 배열과 달리 리스트는 서로 다른 자료형의 데이터도 받을 수 있음

ArrayList list2 = new ArrayList();
		
Human ob2 = new Human("홍진호", 41);
		
list2.add(ob1);
list2.add(ob2);
		
System.out.println(list2)

- 이때, ob1 Object업캐스팅이 됨.

- 따라서 객체를 호출하기 위해서는 Human 타입으로 다운캐스팅을 해줘야함.

for(int i = 0; i < list2.size(); i++) {
	Human element = (Human)list2.get(i);	
	element.show();
}

→ 내부 원소(element) Object 타입이면, 객체 메서드를 호출하기 위해 일일이 다운캐스팅을 해야함

 

 

2) 제네릭 타입

 : 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법

- 특정 클래스객체만 저장하는 리스트

- 지정한 타입의 클래스슈퍼클래스가 됨

- 자바 1.5에서 새로 추가된 문법임

- 배열, 리스트 모두 가능

ArrayList<Human> list3 = new ArrayList<Human>();
		
list3.add(ob1);
list3.add(ob2);
	
for(int i = 0; i < list3.size(); i++) {		
	list3.get(i).show();
} System

3) 향상된 for문

: index 사용하지 않는 for문

* forEach라고도 하지만, 함수이름과 중복되기 때문에 헷갈릴 수 있음

- Iterable 한 타입에 대해서 적용할 수 있음 (배열 포함)

- 배열, 리스트 모두 가능

for(Human element : list3) {	
element.show();
} System.out.println();.out.println();

- list forEach 함수가 별도로 존재함 (리스트만 가능)

list3.forEach(element -> element.show());

- 람다식 : (매개변수) -> {실행할 내용}

- list3의 각각의 요소를 element라고 할 때, element.show()를 호출해라.

 

 

- toString이 오버라이딩 되어 있다면, System.out.println을 전달할 수도 있음

list3.forEach(System.out::println);

- : : 

→ 객체 내부의 println을 찾아서 전달해라.

- list3의 각 요소를 System.out 객체 내부의 println 메서드의 인자로 전달한다.

 

 

4) Comparator

- Comparator 인터페이스에는 미구현 추상 메서드하나

함수형 인터페이스

 

~ Item 클래스 생성

import java.util.ArrayList;
import java.util.Comparator;

class Item {
	String name;
	int price;
	
	Item(String name, int price) {
		this.name = name;
		this.price = price;
	}
	
	@Override
	public String toString() {
		
		return String.format("%s : %,d원", name, price);
	}
}

 

~ 비교하는 객체를 만들어서 사용해보기

class MyComparator implements Comparator<Item> {	

	@Override
	public int compare(Item o1, Item o2) {
		return o1.price - o2.price;	
		
	}
}

- o1.price - o2.price > 0 o1.price > o2.price

- 반환값이 0보다 큰지 아닌지에 따라서 자리바꿈을 판별한다.

 

 

~ 리스트에 값 저장하기

 ① 정수 리스트

public static void main(String[] args) {
		
	ArrayList<Integer> list1 = new ArrayList<Integer>();
	ArrayList<Item> list2 = new ArrayList<Item>();
		
	list1.add(2);
	list1.add(7);
	list1.add(8);
	list1.add(4);
	list1.add(6);
    
	System.out.println(list1);
	list1.sort(null);
	System.out.println(list1);

 

② Item 객체 리스트

	list2.add(new Item("오레오", 2000));
	list2.add(new Item("몽쉘", 3000));
	list2.add(new Item("초코파이", 2500));
	list2.add(new Item("오예스", 2700));
	list2.add(new Item("빅파이", 2900));

	list2.forEach(System.out::println);

 

 

- 가격 순 오름차순 정렬

MyComparator implement Comparator의 객체를 생성하여 전달

System.out.println("가격 오름차순 정렬");
MyComparator priceCmp = new MyComparator();
list2.sort(priceCmp);
		
list2.forEach(System.out::println);

 

- 이름 순 오름차순 정렬

→ 익명 클래스 활용

System.out.println("이름 오름차순 정렬");
list2.sort(new Comparator<Item>() {

	@Override
	public int compare(Item o1, Item o2) {
		return o1.name.compareTo(o2.name);		
		}
	});
		
	list2.forEach(System.out::println);
	System.out.println();

 

- 가격 순 내림차순 정렬

→ 람다식

System.out.println("가격 내림차순 정렬");

list2.sort((o1, o2) -> {	
	return o2.price - o1.price;	
});
		
list2.forEach(System.out::println);
System.out.println();

- 매개변수가 2개라서 소괄호는 생략 불가능

- 실행 내용과 실행 결과가 한줄이기 때문에 중괄호와 return은 생략할 수 있음

 

 

* 배열로 만들었을 경우

~ 정수 비교 기능을 가진 MyIntegerComparator 생성

import java.util.Comparator;

class MyIntegerComparator implements Comparator<Integer> {

	@Override
	public int compare(Integer o1, Integer o2) {
		return o1 - o2;
	}
}

~ 배열 출력 함수

static void showArray(Integer[] arr) {
	System.out.print("[");
	for(int i = 0; i < arr.length; i++) {
		System.out.print(arr[i]);
		System.out.print(i != arr.length - 1 ? ", " : "]\n");
	}
	System.out.println();
}

~ 배열 선택정렬 함수

static void mySort(Integer[] arr, MyIntegerComparator cmp) {

	for(int i = 0; i < arr.length - 1; i++) {
		for(int j = i + 1; j < arr.length; j++) {
				
			if(cmp.compare(arr[i], arr[j]) > 0) {  
			// if(arr[i] > arr[j])
				Integer tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}

~ 메인 함수

public static void main(String[] args) {
	Integer[] arr = { 2, 7, 8, 4, 6 };
	showArray(arr);
		
	MyIntegerComparator cmp = new MyIntegerComparator();
		
//	list.sort(cmp);	// list는 this, 0번째 매개변수
	mySort(arr, cmp);
	showArray(arr);
}

~ 정렬 예시

① 정수의 정렬

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

public class Ex09 {
	public static void main(String[] args) {
		Integer[] arr = { 2, 7, 8, 4, 6 };
		List<Integer> list1 = Arrays.asList(arr);
		System.out.println("list1 : " + list1);
		
		// 오름차순 정렬
		list1.sort((a, b) -> a - b);
		System.out.println("오름차순 정렬 후 list : " + list1);
		
		// 내림차순 정렬
		list1.sort((a, b) -> b - a);
		System.out.println("내림차순 정렬 후 list : " + list1);

* 이때, 원본 리스트의 순서를 저장해두고 싶다면, 새로운 리스트에 원본 리스트를 복사해두면 됨.

Integer[] arr = { 2, 7, 8, 4, 6 };
List<Integer> list1 = Arrays.asList(arr);
System.out.println("list1 : " + list1);
		
// 복사본
List<Integer> list2 = new ArrayList<Integer>(list1);
System.out.println("원본을 복사한  list2 : " + list2);
System.out.println();

② 문자열의 정렬

String[] arr3 = {"나비", "다람쥐", "가방", "라디오"};
List<String> list3 = Arrays.asList(arr3);
		
// 문자열 오름차순
list3.sort((a, b) -> a.compareTo(b));
System.out.println(list3);
		
// 문자열 내림차순
list3.sort((a, b) -> b.compareTo(a));
System.out.println(list3);

 

5) Comparable

public static void main(String[] args) {
		
	String[] arr = { "이지은", "홍진호", "나단비", "유재석", "김종국" };
	List<String> list = Arrays.asList(arr);
		
	System.out.println(list);	
	list.sort(null);	
	System.out.println(list);

-  Comparator를 전달하지 않았는데, 왜 정렬이 되는가?

 StringComparable한 클래스이기 때문임

 

~ (다른 Item2 ) 비교가 가능한 클래스 Item2 만들기

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

class Item2 implements Comparable<Item2> {		
	String name;	
	int price;
	
	Item2(String name, int price) {
		this.name = name;
		this.price = price;
	}
	
	@Override
	public String toString() {
		
		return String.format("%s : %,d원", name, price);
	}

	@Override
	public int compareTo(Item2 o) {	// Item2의 compareTo
		return this.name.compareTo(o.name);	// String의 compareTo
		
	}
}

- Item2의 객체 this Item2의 또다른 객체 o를 비교하려면, this name o name을 비교하여 그 차이를 int로 반환하면 됨

 

~ Comparable 객체의 CompareTo 메서드 테스트

ArrayList<Item2> list2 = new ArrayList<Item2>();
		
list2.add(new Item2("오레오", 2000));
list2.add(new Item2("몽쉘", 3000));
list2.add(new Item2("초코파이", 2500));
list2.add(new Item2("오예스", 2700));
list2.add(new Item2("빅파이", 2900));
		
System.out.println("원본");
list2.forEach(System.out::println);
System.out.println();
		
System.out.println("이름순 정렬");		
list2.sort(null);
list2.forEach(System.out::println);
System.out.println();

 

 

~ 실습 예제) 브랜드별 치킨 정렬하기

- Food 클래스 만들기

import java.util.ArrayList;
import java.util.List;

class Food implements Comparable<Food>{

	String brand;
	String menu;
	int price;
	
	public Food(String brand, String menu, int price) {
		this.brand = brand;
		this.menu = menu;
		this.price = price;
	}

	@Override
	public int compareTo(Food o) {
		
		return o.price - this.price;
	}
	
	@Override
	public String toString() {
		return String.format("%s - %s (%,d원)", brand, menu, price);
	}
}

~ Food 객체와 리스트 생성

public static void main(String[] args) {
		
	Food f1 = new Food("굽네치킨", "고추바사삭", 21000);
	Food f2 = new Food("BBQ", "황금올리브", 19000);
	Food f3 = new Food("굽네치킨", "깐풍치킨", 22000);
	Food f4 = new Food("교촌치킨", "허니콤보", 20000);
	Food f5 = new Food("KFC", "핫크리스피", 21200);
		
	List<Food> list = new ArrayList<Food>();
	list.add(f1);
	list.add(f2);
	list.add(f3);
	list.add(f4);
	list.add(f5);
		
	System.out.println("정렬을 하지 않았을 때");
	list.forEach(food -> System.out.println(food));
	System.out.println();

 

- 기본정렬 시 가격 내림차순으로 정렬하기

System.out.println("가격 내림차순 정렬");
list.sort(null);			
list.forEach(food -> System.out.println(food));
System.out.println();

 

 - 브랜드 기준 오름차순으로 정렬하기

System.out.println("브랜드 오름차순 정렬");
		
list.sort((o1, o2) -> o1.brand.compareTo(o2.brand));
list.forEach(food -> System.out.println(food));

* 람다식의 괄호와 중괄호를 생략하지 않은 경우

list.sort((o1, o2) -> { return o1.brand.compareTo(o2.brand); });

'JAVA > JAVA Note' 카테고리의 다른 글

[JAVA Note] 20. 예외  (0) 2022.11.16
[JAVA Note] 19. Collection  (1) 2022.11.16
[JAVA Note] 17. 추상화  (0) 2022.11.06
[JAVA Note] 16. 추상클래스  (0) 2022.11.02
[JAVA Note] 15. 상속  (0) 2022.11.02

댓글