본문 바로가기
Java

JAVA]배열,ArrayList,List 스트림 정렬 및 타입 변환 방법 정리

by 완기 2022. 2. 19.
728x90
반응형

개발을 하다 보면 배열을 정렬하거나 할 일이 꽤 많다.

 

그럴 떄마다 반복문을 돌면서 값을 비교해서 인덱스를 교체하고 하는 것도 방법이지만 

코드가 길어지고 시간이 더 많이 소요된다.

 

오늘은 배열과 ArrayList List 등 배열을 정렬하는 방법을 소개한다.

 

이 방법엔 Stream을 사용하였으니 만약 모른다면 여기를 참고하면 좋습니다.

 

그리고 Stream은 java 8 이상부터 사용 가능하니 참고하시길 바랍니다.


1.Primitive 배열 정렬

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        System.out.println("case 1 : Arrays.sort(arr)");
        int[] arr = {1, 9, 4, 3, 2, 6, 8, 5, 3, 2, 5, 8, 1, 12, 11, 11, 11, 15, 25, 36, 456};
        Arrays.sort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println("\n--------");

        System.out.println("case 2 : array => array  dinstinct and sorted ");
        int[] arr2 = {1, 9, 4, 3, 2, 6, 8, 5, 3, 2, 5, 8, 1, 12, 11, 11, 11, 15, 25, 36, 456};
        int[] sorted = Arrays.stream(arr2).distinct().sorted().toArray(); // 스트림 객체 생성 => 중복 제거 => 정렬 => int[]로 변환.
        for (int num : sorted) {
            System.out.print(num + " ");
        }
        System.out.println("\n--------");

        System.out.println("case 3 : array => ArrayList dinstinct and sorted ");
        ArrayList<Integer> list = (ArrayList<Integer>) Arrays.stream(arr2).distinct().sorted().boxed().collect(Collectors.toList());
        // int에서 Integer로 변환하기 때문에 boxed()메서드가 꼭 호출되어야함.
        //collect(Collectors.toList()) 는 컬렉션에 사용하고 List<Integer>를 리턴하기 때문에 타입 캐스팅을 해줘야함.
        for (int num : list) {
            System.out.print(num + " ");
        }
        System.out.println("\n--------");

        System.out.println("case 4 : ArrayList => array");
        int[] arrayListToArray = list.stream().mapToInt(i -> i).toArray();
        //mapToInt를 통해 Collection을 primitive 타입으로 변환 -> toArray로 리턴.
        for (int num : arrayListToArray) {
            System.out.print(num + " ");
        }
        System.out.println("\n--------");
    }
}

위 결과는 4가지의 경우를 나타낸다.

1.Arrays.sort를 사용한 정렬

2.Stream을 이용한 array => array

3.Stream을 이용한 array => ArrayList

4.Stream을 이용한 ArrayList => ArrayList

 

결과

결과에서도 볼 수 있듯이 어느 방법을 사용하던 결과는 동일하다. 

변환해야 하는 타입에 따라 사용하면 된다.

(1번 케이스는 중복 제거를 깜빡하고 안했다.)

 

 


2.String 배열 정렬

 

String 배열 정렬도 위 int 배열과 크게 다르지 않다.

public static void main(String[] args) {
        String[] arr = {"studentA", "studentB", "studentC", "studentD", "studentA", "studentA", "studentB", "studentR", "studentS", "studentG", "ace"};

        System.out.println("case 1 : Arrays.sort() => 첫 번째 문자를 기준으로 정렬");
        Arrays.sort(arr);
        for (String val : arr) {
            System.out.print(val + " ");
        }
        System.out.println("\n---------------");

        System.out.println("case 2 : Stream을 이용한 정렬");
        String[] arr2 = {"studentA", "studentB", "studentC", "studentD", "studentA", "studentA", "studentB", "studentR", "studentS", "studentG", "ace"};
        String[] distinctedArr2 = Arrays.stream(arr2).distinct().sorted().toArray(String[]::new);// 문자열 배열은 오브젝트 이므로 .toArray(String[]::new)사용.
        for (String val : distinctedArr2) {
            System.out.print(val + " ");
        }
        System.out.println("\n---------------");

        ArrayList<String> list = (ArrayList<String>) Arrays.stream(arr2).distinct().sorted().collect(Collectors.toList());
        System.out.println("case 3 : array => ArrayList");
        for (String val : list) {
            System.out.print(val + " ");
        }
        System.out.println("\n---------------");
	}
}

문자열 배열 정렬도 크게 다르지 않지만 문자열은 오브젝트이므로

300x250
.toArray(String[]::new)

를 사용하여 String[]로 리턴한다.

:: 연산자가 궁금하다면? 

 

 


3.Object ArrayList 정렬

Object로 된 ArrayList는 인덱스가 특정 값이 아니라 비교하기 애매할 수 있다.

 

객체가 가진 값을 기준으로 배열을 정렬하려면 Comparator을 사용하면 된다.

class Member {
        private String name;
        private int age;

        public Member() {
        }

        public Member(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return "Member{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        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;
        }
    }

 

일단 테스트를 위해 Member 클래스를 간단하게 만들었고,

 

public class Main {
	public static void main(String[] args) {
        Main main = new Main();
        ArrayList<Member> members = new ArrayList<>(Arrays.asList(
                main.new Member("studentA", 28),
                main.new Member("studentB", 30),
                main.new Member("studentC", 30),
                main.new Member("studentD", 25)));

        Collections.sort(members, new Comparator<Member>() {
            @Override
            public int compare(Member o1, Member o2) {
                if (o1.getAge() != o2.getAge())
                    return o1.getAge() > o2.getAge() ? 1 : -1;
                else
                    return o1.getName().compareTo(o2.getName());
            }
        });

        for (Member member : members) {
            System.out.println(member.toString());
        }
    }
}

ArrayList를 초기화하면서 값을 할당했다.

학생 A는 26살 

B, C는 30살로 동갑.

D는 25살로 가장 어릴 때 정렬하는 방법이다.

 

Collections.sort(members, new Comparator<Member>() {
            @Override
            public int compare(Member o1, Member o2) {
                if (o1.getAge() != o2.getAge())
                    return o1.getAge() > o2.getAge() ? 1 : -1;
                else
                    return o1.getName().compareTo(o2.getName());
            }
        });

Comparator의 인터페이스 compare를 Override 하여 직접 정렬 기준을 정한다.

 

if문에서 각 객체별로 나이가 같지 않다면 나이 순으로 오름차순으로 정렬한다.

나이가 같다면 이름으로 오름차순으로 정렬한다.

 

결과

 

여기서 만약 역 정렬을 하고싶다면 1과 -1의 순서를 바꿔주면 된다.

 

결과

 

만약 나이가 같을 때, 이름 기준으로 역정렬을 한다면?

마찬가지로 o2와 o1을 교체해준다.

 

 

결과

바로 위 이미지와 다르게 학생 B, C가 위치가 바뀌었다.

 

Collections.sort의 표현을 람다로 바꾸면 더 간결하게 코드를 작성할 수 있다.

Collections.sort(members, (o1, o2) -> {
    if (o1.getAge() != o2.getAge())
        return o1.getAge() > o2.getAge() ? -1 : 1;
    else
        return o2.getName().compareTo(o1.getName());
});

 

728x90
728x90

댓글