Java

Java 문자 + 숫자로 이루어진 문자열 정렬

요술공주밍키 2023. 3. 22. 21:49

 문제 직면

회사에서 특정 폴더 내에 이미지들을 업로드해야 하는 일이 있었기 때문에 아무 생각 없이 코드를 작성했다.

File dir = new File(path);
String[] list = dir.list();

위와 같이 작성하니 나중에 이미지의 순서가 뒤죽박죽이 되어버린 것이다.

 

 첫번 째 해결책

해당 문제를 해결하기 위해 Arrays.sort를 사용하였다.

File dir = new File(path);
String[] list = dir.list();

Arrays.sort(list);

for(String data : list) {
	log.info("Data={}", data);
}

정렬은 성공적으로 잘되었지만 한 가지 문제가 남아있었다.

데이터가 "문자열"이기 때문에 숫자가 제대로 정렬되지 않는것.

 

예를 들어

"1", "2", "10", "140", "45", "6" 

이런 형식의 데이터가 있다고 했을 때 단순히 Arrays.sort()를 사용한다면

"1", "10", "140", "2", "45", "6"

이런 식으로 정렬이 된다. 이래서는 제대로 정렬을 했다고 할 수 없다.

 

 두 번째 해결책

그래서 나타난 해결책이 Comparator를 사용하는 것이었다.

Comparator는 Java에서 제공하는 인터페이스 중 하나로, 두 개의 객체를 비교하여
정렬 순서를 결정하는 데 사용됩니다. 정렬할 객체의 클래스에서 정렬 기준을 구현하는
Comparable 인터페이스가 없거나, 기본적인 정렬 순서와는 다른 방식으로
객체를 정렬해야 할 경우에 Comparator를 사용합니다.

위 내용은 ChatGPT를 통해 알아냈다.  ChatGPT 사랑해요 당신 없음 못살아 ㅠㅠ

 

package egovframework.CNPECMJava.cmm;

import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NaturalOrderComparator implements Comparator<String> {

	private static final Pattern PATTERN = Pattern.compile("(\\D*)(\\d*)");
    
    public int compare(String s1, String s2) {
        Matcher m1 = PATTERN.matcher(s1);
        Matcher m2 = PATTERN.matcher(s2);

        while (m1.find() && m2.find()) {
            String nonDigit1 = m1.group(1);
            String nonDigit2 = m2.group(1);
            if (nonDigit1.compareTo(nonDigit2) != 0) {
                return nonDigit1.compareTo(nonDigit2);
            }

            String digitStr1 = m1.group(2);
            String digitStr2 = m2.group(2);
            if (digitStr1.isEmpty() || digitStr2.isEmpty()) {
                return digitStr1.compareTo(digitStr2);
            }

            long digit1 = Long.parseLong(digitStr1);
            long digit2 = Long.parseLong(digitStr2);
            if (digit1 != digit2) {
                return Long.compare(digit1, digit2);
            }
        }
        return s1.length() - s2.length();
    }
}

위처럼  클래스를 하나 생성하여 Comparator를 가져온 뒤 원하는 정렬 방식으로 구현해 준다.

 

그리고 Arrays.sort()를 사용한다.

File dir = new File(path);
String[] list = dir.list();

Arrays.sort(list, new NaturalOrderComparator());

for(String data : list) {
	log.info("Data={}", data);
}

이러면 정상적으로 정렬이 되는 것을 확인할 수 있다.