Как отсортировать строки в java, сначала нужно отобразить заглавные строки - PullRequest
0 голосов
/ 28 мая 2019

Необходимо сортировать строки в java с учетом регистра, но заглавные буквы должны отображаться первыми.

Что я пробовал:

List<String> l = Arrays.asList("aaa","AAA","AAA","aaa","BBB","ccc","CCC");
l.stream().sorted(String.CASE_INSENSITIVE_ORDER);
System.out.println(l);`

Выход:

[aaa, AAA, AAA, aaa, BBB, ccc, CCC]

Ожидаемый результат:

[AAA,AAA,aaa,aaa,BBB,CCC,ccc]

Ответы [ 4 ]

2 голосов
/ 28 мая 2019

Вы можете добавить второй компаратор для определения порядка после сравнения их без учета регистра.Второй компаратор размещается на основе символов.

List<String> l = Arrays.asList("a","A","A","a","B","c","C");
l.sort(String.CASE_INSENSITIVE_ORDER
          .thenComparing(Comparator.comparing(YourClass::isUpperCase)
             .reversed()));

private static boolean isUpperCase(String s) {
    return Character.isUpperCase(s.charAt(0));
}

Comparator.comparing использует вспомогательный метод для определения, является ли строка заглавной.Тип возврата этого метода - логический .Естественное упорядочение логического типа: false , за которым следует true .Следовательно, вы должны повернуть его вспять, чтобы сначала получить символы (строки) в верхнем регистре.

Примечание: Вы должны были использовать здесь символы, а не строки (если все строки имеют только однуперсонаж).Вспомогательный метод здесь просто проверяет первый символ в этой строке, который звучит странно!.

В качестве альтернативы, если у вас есть метод проверки нижнего регистра, вы можете упростить это как

l.sort(String.CASE_INSENSITIVE_ORDER
      .thenComparing(YourClass::isLowerCase));

private static boolean isLowerCase(String s) {
    return Character.isLowerCase(s.charAt(0));
}

ОБНОВЛЕНИЕ: (согласно обновлению ОП вопроса).

Если строка состоит из нескольких символов и если вы хотите сделать заказ, исходя из условия, что строки в верхнем регистре должны предшествовать первымдругие, вы можете сделать, как.

l.sort(String.CASE_INSENSITIVE_ORDER
        .thenComparing(YourClass::areAllCharactersLowerCase));

private static boolean areAllCharactersLowerCase(String s) {
    return s.chars()
            .mapToObj(c -> (char)c)
            .allMatch(Character::isLowerCase);
}

Примечание: При этом строки типа CCc и Ccc будут обрабатываться равными в соответствии с первым компаратором, а второй компаратор вернет false для обоих (обработка их)снова равный).Таким образом, они отображаются в том же порядке, что и во входных данных.


РЕДАКТИРОВАТЬ 2: На основе комментария OP

Что если он имеетСтроки, такие как ААа или ААА или ААА?

@ user7, тогда AAa, AaA, aAA должны быть в порядке.

Я предполагаю, что вы хотите упорядочить строки, сравнивая символ за символом, и строка с наиболее последовательным символом в верхнем регистре будет считаться перечисленной перед другими.

Приведенный ниже код сравнивает char-by-char и обрабатывает следующие сценарии

  • Если текущий символ String a имеет верхний регистр, а текущий символ String b в нижнем регистре, тогда String a предшествует b.
  • Если текущий символ String a имеет нижний регистр, а текущий символ String b в верхнем регистре,затем String b предшествует a
  • Иначе, оба имеют одинаковый символ. Продолжайте поиск.

Для одинаковых строк мы возвращаем 0 в конце.

 l.sort(String.CASE_INSENSITIVE_ORDER
        .thenComparing((a, b) -> {
            //String a and b are equal when compared ignoring case (and hence same length)
            for (int i = 0; i < a.length(); i++) {
                if (Character.isUpperCase(a.charAt(i)) && Character.isLowerCase(b.charAt(i))) {
                    return -1;
                } else if (Character.isLowerCase(a.charAt(i)) && Character.isUpperCase(b.charAt(i))) {
                    return 1;
                }
            }
            return 0;
        }));
1 голос
/ 28 мая 2019

Это пользовательская сортировка, а не сортировка с учетом регистра. Потому что при сортировке с учетом регистра все заглавные буквы будут стоять перед маленькими буквами. Следовательно, результат будет

AAA > BBB > CCC > aaa > bbb > ccc

Для реализации пользовательской сортировки вам необходимо использовать собственный компаратор, как показано ниже

import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class SortCapitalFirst {

    @Test
    public void runTest(){
        List<String> l = Arrays.asList("aaa","AAA","AAA","aaa","BBB","ccc","CCC");
        l.sort((o1, o2) -> {
            int compareIgnoreCaseResult = o1.compareToIgnoreCase(o2);

            if (compareIgnoreCaseResult != 0){
                return compareIgnoreCaseResult;
            }

            return o1.compareTo(o2);
        });
        System.out.println(l);
    }
}

 
0 голосов
/ 28 мая 2019

Следующий код поможет вам сортировать строки в CASE_INSENSITIVE_ORDER.Здесь вам нужно два раза отсортировать список.

public static void main(String[] args) {
  List<String> l = Arrays.asList("a", "A", "A", "a", "B", "c", "C");
  Collections.sort(l);
  Collections.sort(l, String.CASE_INSENSITIVE_ORDER);
  System.out.println(l);
}
0 голосов
/ 28 мая 2019
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortStrings {

    public static void main(String[] args) {
        Comparator<String> comparator = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if(o1 == null) {
                    return 1;
                }
                if(o2 == null) {
                    return -1;
                }
                int result = o1.compareToIgnoreCase(o2);
                if(result != 0) {
                    return result;
                }
                return o1.compareTo(o2);
            }
        };

        List<String> list = Arrays.asList("A","a","A","a", "B", "c","C");
        Collections.sort(list, comparator);
        System.out.println(list);
        // [A, A, a, a, B, C, c]

        List<String> list2 = Arrays.asList("Ab","a","AB", "A", "AbB", "a","B","c","C");
        Collections.sort(list2, comparator);
        System.out.println(list2);
        // compare length first
        // [A, a, a, AB, Ab, AbB, B, C, c]

        List<String> list3 = Arrays.asList("aaa","AAA","AAA","aaa","BBB","ccc","CCC");
        Collections.sort(list3, comparator);
        System.out.println(list3);
        // [AAA, AAA, aaa, aaa, BBB, CCC, ccc]
    }
}
...