티스토리 뷰

반응형

카톡을 보게 되면, 한글 -> 영문 -> 특수문자 순으로 정렬을 합니다. 지난 번 프로젝트 하면서 동일한 요구사항이 있었는데, 생각보다 머리아프더라고요. 그냥 문자열순으로 정렬하면 그 순서가 안나오니까요.

그래서 이번에 아스키 코드를 보면서 그걸 하나하나 확인하면서 작업을 했습니다. 우선은 해당 문자가 어떤 종류인지 알아야겠지요.그래서 그걸 확인하는 UTIL을 하나 만들었습니다.


/**
 * 문자 관련 유틸
 */
public class CharUtil {
    public static boolean isEnglish(char ch){
        return (ch >= (int)'A' && ch <= (int)'Z')
                || (ch >= (int)'a' && ch <= (int)'z');
    }

    public static boolean isKorean(char ch) {
        return ch >= Integer.parseInt("AC00", 16) 
                && ch <= Integer.parseInt("D7A3", 16);
    }

    public static boolean isNumber(char ch) {
        return ch >= (int)'0' && ch <= (int)'9';
    }

    public static boolean isSpecial(char ch) {
        return (ch >= (int)'!' && ch <= (int)'/') // !"#$%&'()*+,-./
                || (ch >= (int)':' && ch <= (int)'@') //:;<=>?@
                || (ch >= (int)'[' && ch <= (int)'`') //[\]^_`
                || (ch >= (int)'{' && ch <= (int)'~'); //{|}~
    }
}

그리고 정렬하는데 필요한 compare 메서드를 구현했습니다. 여러 객체에서 쉽게 가져다 쓸 수 있게 static 하게 만들었어요.


/**
 * 한글 > 영어 > 숫자 > 특수문자 순서 정렬 객체
 */
public class OrderingByKoreanEnglishNumbuerSpecial {
    private static final int REVERSE  = -1;
    private static final int LEFT_FIRST  = -1;
    private static final int RIGHT_FIRST  = 1;

    public static Comparator<String> getComparator() {
        return  new Comparator<String>() {
            public int compare(String left, String right) {
                return OrderingByKoreanEnglishNumbuerSpecial.compare(left, right);
            }
        };
    }

    /**
     * 한글 > 영어 > 숫자 > 특수문자 순서 비교 함수
     * @param left
     * @param right
     * @return
     */
    public static int compare(String left, String right) {

        left = StringUtil.upperCase(left).replaceAll(" ", "");
        right = StringUtil.upperCase(right).replaceAll(" ", "");

        int leftLen = left.length();
        int rightLen = right.length();
        int minLen = Math.min(leftLen, rightLen);

        for(int i = 0; i < minLen; ++i) {
            char leftChar = left.charAt(i);
            char rightChar = right.charAt(i);

            if (leftChar != rightChar) {
                if (isKoreanAndEnglish(leftChar, rightChar)
                    || isKoreanAndNumber(leftChar, rightChar)
                    || isEnglishAndNumber(leftChar, rightChar)
                    || isKoreanAndSpecial(leftChar, rightChar)) {
                    return (leftChar - rightChar) * REVERSE;
                } else if (isEnglishAndSpecial(leftChar, rightChar)
                    || isNumberAndSpecial(leftChar, rightChar)) {
                    if (isEnglish(leftChar) || isNumber(leftChar)) {
                        return LEFT_FIRST;
                    } else {
                        return RIGHT_FIRST;
                    }
                } else {
                    return leftChar - rightChar;
                }
            }
        }

        return leftLen - rightLen;
    }

    private static boolean isKoreanAndEnglish(char ch1, char ch2) {
        return (isEnglish(ch1) && isKorean(ch2))
                || (isKorean(ch1) && isEnglish(ch2));
    }

    private static boolean isKoreanAndNumber(char ch1, char ch2) {
        return (isNumber(ch1) && isKorean(ch2))
                || (isKorean(ch1) && isNumber(ch2));
    }

    private static boolean isEnglishAndNumber(char ch1, char ch2) {
        return (isNumber(ch1) && isEnglish(ch2))
                || (isEnglish(ch1) && isNumber(ch2));
    }

    private static boolean isKoreanAndSpecial(char ch1, char ch2) {
        return (isKorean(ch1) && isSpecial(ch2))
                || (isSpecial(ch1) && isKorean(ch2));
    }

    private static boolean isEnglishAndSpecial(char ch1, char ch2) {
        return (isEnglish(ch1) && isSpecial(ch2))
                || (isSpecial(ch1) && isEnglish(ch2));
    }

    private static boolean isNumberAndSpecial(char ch1, char ch2) {
        return (isNumber(ch1) && isSpecial(ch2))
                || (isSpecial(ch1) && isNumber(ch2));
    }
}

비슷한 요구사항을 개발하는데 참고해 보시면 좋을 듯 합니다.

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함