본문 바로가기
[즐거운 자바 강좌] 정리

[즐거운 자바] 섹션 5 - 배열 Arrays클래스

by haeyoon 2024. 3. 31.

[Arrays]

 - 배열을 다룰때 사용하는 유틸리티

 - java.util 패키지에 포함되어 있다

 

1. 배열 복사

[예제1] 배열 전체 복사

public class Array14 {
    public static void main(String[] args) {
        int[] copyFrom = {1,2,3};

        int[] copyTo = java.util.Arrays.copyOf(copyFrom, copyFrom.length);
        for (int c : copyTo) {
            System.out.println(c);
        }
        System.out.println("-----------");

        int[] copyTo2 = java.util.Arrays.copyOf(copyFrom, 5);
        for (int c: copyTo2){
            System.out.println(c);
        }
        System.out.println("-----------");

        int[] copyTo3 = copyFrom;
        for (int c: copyTo3){
            System.out.println(c);
        }
    }
}

출력:

 

깊은 복사(Deep Copy) vs 얕은복사(Shallow Copy)

 - 깊은 복사: 실제 값을 복사 

 - 얕은 복사: 주소 값을 복사 → 같은 배열을 참조

int[] copyTo = java.util.Arrays.copyOf(copyFrom, copyFrom.length);   VS   int[] copyTo3 = copyFrom;  차이점

if (copyTo==copyFrom){
            System.out.println("copyTo==copyFrom");
        }else {
            System.out.println("copyTo!=copyFrom");
        }
 
 if (copyTo3==copyFrom){
            System.out.println("copyTo3==copyFrom");
        }else {
            System.out.println("copyTo3!=copyFrom");
        }

출력:

copyTo!=copyFrom

copyTo3==copyFrom 

 

→ copyTo는 copyFrom을 복사한 배열이지만(깊은 복사), copyTo3 와 copyFrom은 같은 배열을 참조한다(얕은 복사)

[예제2] 배열 일부 복사

import java.util.Arrays;
//java.lang 패키지의 클래스는 import를 사용하지 않아도 사용 가능

public class Array15 {
    public static void main(String[] args) {
        char[] copyFrom = {'h', 'e', 'l', 'l', 'o', '!'};
        //char[] copyTo = java.util.Arrays.copyOfRange(copyFrom,1,3);
        char[] copyTo = Arrays.copyOfRange(copyFrom,1,3); //이때는 import문이 필요

        for (char c : copyTo){
            System.out.println(c);
        }
    }
}

  import문 자동 생성하는 단축키(Windows): Alt + Enter

→  출력: 

 


2. 배열 비교

Arrays.compare( x , y );

→  비교결과 양수, 0, 음수 출력됨

   - 양수: x - y > 0 인 경우 = x배열이 y배열의 보다 큰 경우 (값이 큰경우 / 배열이 많은 경우)

   - 0: x - y == 0 인 경우 = x배열이 y배열과 같은경우

   - 음수: x - y < 0 인 경우 = x배열이 y배열의 값보다 작은 경우

[코드] 숫자 배열 비교

import java.util.Arrays;

public class Array16 {
    public static void main(String[] args) {
        int[] array1 = {1,2,3,4,5};
        int[] array2 = {1,2,3,4,5};
        int[] array3 = {1,2,3,4,6};
        int[] array4 = {1,2,3,4,4};
        
        int compare2 = Arrays.compare(array1, array2);
        int compare3 = Arrays.compare(array1, array3);
        int compare4 = Arrays.compare(array1, array4);

        System.out.println(compare2);
        System.out.println(compare3);
        System.out.println(compare4);
    }
}

 

→  출력:


3. 배열 정렬

Arrays.sort(array);  // 오름차순 정렬

import java.util.Arrays;

public class Array17 {
    public static void main(String[] args) {
        int[] array = {5,4,3,1,2};

        Arrays.sort(array); //오름차순 정렬

        for (int i : array){
            System.out.println(i);
        }
        int i = Arrays.binarySearch(array, 4);
        System.out.println(i);
    }
}

  출력: 

 

Arrays.binarySearch( array , i);

정렬된 배열 array에서 i가 몇번째 index에 있는지 return

[원리 예시]

1-100사이에서 랜덤 숫자인 32를 가장 빠르게 맞추는 경우. 숫자 하나를 말하면 해당숫자가 정답보다 큰지 작은지 알려준다.

Q1. 50? (= 1-100의 중간 숫자) → DOWN

Q2. 25? (= 1-49의 중간 숫자) → UP

Q3. 27? (= 26-49의 중간 숫자) → UP

...

해당 예시처럼 중간값을 말하면서 정답인 숫자와 가까워지는 방식으로 정답을 찾음 

→ 그러기 위해서는 배열이 정렬되어 있어야함

 

[예제]여러 item가진 배열 비교

[코드1] 내부에서 이름순서대로 정렬

import java.util.Arrays;

public class Array172 {
    public static void main(String[] args) {
        Item[] items = new Item[5];
        items[0] = new Item("java", 5000);
        items[1] = new Item("파이썬", 4000);
        items[2] = new Item("C#", 4500);
        items[3] = new Item("자바스크립트", 6000);
        items[4] = new Item("Dart", 2000);

        //sort(Object[]) - Object는 모든 객체의 조상이니까, 어떤 객체의 배열이든 올 수 있다.
        Arrays.sort(items);

        for (Item item : items){
            System.out.println(item);
        }
    }
}

//Comparable은 어떤 Item이 큰지, 작은지 기준을 정하는 interface
class Item implements Comparable{
    //파라미터로 들어온 Object와 내 자신을 비교하는 메소드
    //CompareTo에는 Object를 받아들이도록 했지만 실제로는 Item이 들어온다.
    @Override
    public int compareTo(Object o) {
        Item d = (Item)o;
        return this.name.compareTo(d.name); //양수, 0, 음수
    }

    private String name;
    private int price;

    public Item(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    //출력하기 위해
    @Override
    public String toString() {
        return "Item{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

출력: 

 

[추가 설명]

Arrays.sort(items); 만 실행시 Exception in thread "main" java.lang.ClassCastException 오류 발생

 

어떤 기준으로 sort될지 모름 → compareTo에 item 오브젝트를 넣음

→ 파라미터로 들어온 o를 Item으로 형변환 시킴

→ 파라미터로 들어온 d의 name(=d.name)과 자기자신의 이름(=this.name)을 비교

 

[코드2] 내부에서 가격 오름차순으로 정렬

... 동일 코드 ...

@Override
public int compareTo(Object o) {
    Item d = (Item)o;
    return this.price - d.price; //양수, 0, 음수
}

출력:

 

[코드3] 외부에서 이름순서대로 정렬

import java.util.Arrays;
import java.util.Comparator;

public class Array172 {
    public static void main(String[] args) {
        Item[] items = new Item[5];
        items[0] = new Item("java", 5000);
        items[1] = new Item("파이썬", 4000);
        items[2] = new Item("C#", 4500);
        items[3] = new Item("자바스크립트", 6000);
        items[4] = new Item("Dart", 2000);

        //sort(Object[]) - Object는 모든 객체의 조상이니까, 어떤 객체의 배열이든 올 수 있다.
        Arrays.sort(items, new ItemSorter());

        for (Item item : items){
            System.out.println(item);
        }
    }
}

class ItemSorter implements Comparator{
    //compare 메소드 오버라이딩
    @Override
    public int compare(Object o1, Object o2) {
        Item item1 = (Item)o1;
        Item item2 = (Item)o2;
        return item1.getName().compareTo(item2.getName());
    }
}

class Item{
    private String name;
    private int price;

    public Item(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    //출력하기 위해
    @Override
    public String toString() {
        return "Item{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

ItemSorter 생성

 

[코드4] 메소드가 1개인 람다 표현식

import java.util.Arrays;
import java.util.Comparator;

public class Array172 {
    public static void main(String[] args) {
        Item[] items = new Item[5];
        items[0] = new Item("java", 5000);
        items[1] = new Item("파이썬", 4000);
        items[2] = new Item("C#", 4500);
        items[3] = new Item("자바스크립트", 6000);
        items[4] = new Item("Dart", 2000);

        Arrays.sort(items, (item1, item2) -> item1.getName().compareTo(item2.getName()));

        for (Item item : items){
            System.out.println(item);
        }
    }
}

class ItemSorter implements Comparator{
    //compare 메소드 오버라이딩
    @Override
    public int compare(Object o1, Object o2) {
        Item item1 = (Item)o1;
        Item item2 = (Item)o2;
        return item1.getName().compareTo(item2.getName());
    }
}

//Comparable은 어떤 Item이 큰지, 작은지 기준을 정하는 interface
class Item{
    private String name;
    private int price;

    public Item(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    //출력하기 위해
    @Override
    public String toString() {
        return "Item{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}