개발을 하다 보면 배열을 정렬하거나 할 일이 꽤 많다.
그럴 떄마다 반복문을 돌면서 값을 비교해서 인덱스를 교체하고 하는 것도 방법이지만
코드가 길어지고 시간이 더 많이 소요된다.
오늘은 배열과 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---------------");
}
}
문자열 배열 정렬도 크게 다르지 않지만 문자열은 오브젝트이므로
.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());
});
'Java' 카테고리의 다른 글
JPA 시작하기 (0) | 2022.03.08 |
---|---|
Java]메서드 오버로딩말고 파라미터를 여러개 받아보자. (0) | 2022.02.23 |
Java 회전된 문자열인지 확인하기 (0) | 2022.01.30 |
Log4j 보안 이슈 (0) | 2021.12.13 |
spring,java]JPA를 이용한 API서버 (0) | 2021.11.30 |
댓글