java

Array 사용법

윤만석 2024. 3. 13. 21:16

1. 배열의 비교

 

1-1. 기본자료형에대한 배열의 비교

package Devide_And_Conquer;

import java.util.Arrays;

public class Main {
	public static void main(String args[]) {
		int[]a= {1,2,3,4};
		int[]b= {1,2,3,4};
		System.out.println(a==b);
		System.out.println(a.equals(b));
		//위 둘은 참조값을 비교
		//false
		//false
		int[]c=Arrays.copyOf(a,a.length);
		//Arrays 의 copyOf메소드는 새로운 배열을 생성하는 메소드이다 마찬가지로
		System.out.println(a==c);
		System.out.println(a.equals(c));
		//false
		//false
		
		//따라서 기본형을 가지는 배열의 내용을 비교할땐 Arrays의 equals메소드를 사용한다.
		System.out.println(Arrays.equals(a, b));
		System.out.println(Arrays.equals(a, c));
		//true
		//true
	}
}

 

 

1-2. 인스턴스 배열 비교

class num{
	int num;
	num(int r){
		num=r;
	}
	@Override
	public boolean equals(Object obj) {
		if(this.num==((num)obj).num) {
			return true;
		}
		return false;
	}
}
public class Main {
	public static void main(String args[]) {
		num[] a = new num[3];
		a[0]=new num(1);
		a[1]=new num(2);
		a[2]=new num(3);
		
		num[] b = new num[3];
		b[0]=new num(1);
		b[1]=new num(2);
		b[2]=new num(3);
		
		System.out.println(a==b);
		System.out.println(a.equals(b));
		//당연히 false false
		System.out.println(Arrays.equals(a, b));
		//내부 인스턴스들이 모두 다릅니다 따라서 
		//eqauls를 새로 오버라이딩해야합니다.
	}
}

똑같이 Arrays.equals를 사용하면 되지만, 여기서는 내부인스턴스들의 참조값이 모두 다르기때문에 false가 나옵니다.

데이터를 비교하기 위해서 Object클래스의 equals 매소드를 오버라이딩 해야합니다 

 

아니 Arrays.equals 매소드를 오버라이딩해야하는게 아닌가? 왜 갑자기 Object 클래스의 equals 매소드가 나오지 ?

 

왜냐하면 Object 클래스의 equals 매소드가 비교기준을 제공하기 때문입니다.

 

마치 C++에서 sort 함수의 3번째 인자로사용할 function, 즉

비교하기위해 클래스 안에서 연산자<를 오버로딩하는것처럼요

#include <iostream>
#include <vector>
#include <algorithm>

// 사용자가 정의한 객체
class MyClass {
public:
    int value;
    MyClass(int v) : value(v) {}

    // 비교 연산자 오버로딩 >> 클래스 안에서 연산자를 오버로딩합니다
    bool operator<(const MyClass& other) const {
        return value < other.value;
    }
};

int main() {
    // 사용자가 정의한 객체를 담은 벡터 생성
    std::vector<MyClass> vec = {MyClass(3), MyClass(1), MyClass(2)};

    // 객체를 정렬
    std::sort(vec.begin(), vec.end());

    // 정렬된 객체 출력
    for (const auto& obj : vec) {
        std::cout << obj.value << " ";
    }
    std::cout << std::endl;

    return 0;
}

 

 

2. 배열의 정렬

c++에서는 밥먹듯이 쓰던건데.. sort(a.begin(),a.end(),compare)

java에서도 지원합니다.

 

public class Main {
	public static void main(String args[]) {
		int[]a= {5,4,3,2,1};
		Arrays.sort(a);
		for(var r:a) {
			System.out.println(r);
		}
	}
}

기본타입형 배열같은경우 sort가 오름차순으로 잘 됩니다.

 

만약에 어떠한 클래스의 인스턴스배열인경우

import java.util.Arrays;

class num{
	int num;
	num(int r){
		num=r;
	}
}
public class Main {
	public static void main(String args[]) {
		num[]a=new num[5];
		a[0]=new num(5);
		a[1]=new num(4);
		a[2]=new num(3);
		a[3]=new num(2);
		a[4]=new num(1);
		Arrays.sort(a);
		for(var r:a) {
			System.out.println(r.num);
		}
	}
}
//class Devide_And_Conquer.num cannot be cast to class java.lang.Comparable (Devide_And_Conquer.num is in module Divide_And_Conquer of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')

에러가 발생합니다.

sort메소드는 Object배열에대해 오버로딩이 되어있는데, 

interface Comparable{
int compareTo(Object o)
}

//이 추상메소드의 구현을 통해 인스턴스 순서를 판단합니다.
//o가 작다면 양수 반환
//o가 같다면 0 반환
//o가 크다면 음수 반환

이를통해 다시 작성해보면

class num implements Comparable{ //comparable 마커인터페이스를 구현합니다
	int num;
	num(int r){
		num=r;
	}
	@Override  //메소드 compareTo 오버라이딩
	public int compareTo(Object o) { 
		if(this.num > ((num)o).num) return 1;
		else return -1;
	}
}
public class Main {
	public static void main(String args[]) {
		num[]a=new num[5];
		a[0]=new num(5);
		a[1]=new num(4);
		a[2]=new num(3);
		a[3]=new num(2);
		a[4]=new num(1);
		Arrays.sort(a);
		for(var r:a) {
			System.out.println(r.num);
		}
	}
}