Реализовать метод, принимающий (List<String[]> rows, int columnIndex) и сортирующий массивы строк(записи таблицы) по колонке

429
23 января 2017, 18:27

Есть интерфейс , в котором объявлен метод

void sort(List<String[]> rows, int columnIndex);

public interface IStringRowsListSorter {

/**
 * Сортирует переданный список записей (каждая запись - набор колонок) таблицы по указанной колонке по следующим правилам:
 * <ul>
 *  <li>в колонке могут быть null и пустые значения - строки с null-значениями должны быть первыми, затем строки с пустым значением, затем все остальные,</li>
 *  <li>строка бьется на подстроки следующим образом: выделяем непрерывные максимальные фрагменты строки, состоящие только из цифр, и считаем набором подстрок эти фрагменты и все оставшиеся от такого разбиения фрагменты строки</li>
 *  <li>при сравнении строк осуществляется последовательное сравнение их подстрок до первого несовпадения,</li>
 *  <li>если обе подстроки состоят из цифр - то при сравнении они интерпретируются как целые числа (вначале должно идти меньшее число), в противном случае - как строки,</li>
 *  <li>сортировка должна быть устойчива к исходной сортировке списка - т.е., если строки (в контексте указанных правил сравнения) неразличимы, то сортировка не должна менять их местами.</li>
 * </ul>
 *
 * @param rows список записей таблицы (например, результат sql select), которые нужно отсортировать по указанной колонке
 * @param columnIndex индекс колонки, по которой нужно провести сортировку
 */
void sort(List<String[]> rows, int columnIndex);

}

Нужно реализовать этот интерфейс в своем классе

public class Task1Impl implements IStringRowsListSorter, Comparator<String[]>{
    //реализация должна работать, как singleton. даже при использовании из нескольких потоков.
    public static final IStringRowsListSorter INSTANCE = new Task1Impl();
    @Override
    public void sort(final List<String[]> rows, final int columnIndex) {
//моя реализация

    }

Метод принимает в качестве параметров:

rows - таблицу. (List - это , как я понял, список массивов типа String! Я так понял, сама таблица ,например результат запроса)

columnIndex - номер поля в этой таблицы ( индекс колонки), по которой нужно провести сортировку. В нашей структуре это String, получается.

Я так понимаю, что сортировку сделать нужно Используя Comparator. то есть в классе должен быть переопределен:

    @Override     
public int compare(String[] o1, String[] o2) {}

МЫ по сути должны отсортировать записи в таблицах, что и передаем Comparator'у, но как ему объяснить что нужно, сортировать по строкам, ведь в Comparator мы не можем передать ещё и columnIndex -

      @Override     
            public int compare(String[] o1, String[] o2, int columnIndex) { 
     o1[columnIndex] < o2 [columnIndex]
}

Для работы с этим интерфейсом создал тестовый класс, такжу прошу просмотреть правильно ли сделал структуру для работы с массивом и её вывод через for each

public class TestIStringRowsListSorter {
   List<String[]> rows = new ArrayList<String[]>();
   public List<String[]> getStruct(){
       return rows;
   }
   public void init(){
    String[] query1 = new String[3]; //   массив строк - строка таблицы
    query1[0] = "Contact"; // 1а строка - 1а запись (1о поле)
    query1[1] = "1"; // 1а строка - 1а запись (1о поле)
    query1[2] = "Peter"; // 1а строка - 1а запись (1о поле)

    String[] query2 = new String[3];
    query2[0] = "Contact";
    query2[1] = "2";
    query2[2] = "Helga";
       rows.add(query1); // добавляем в тестовый Список из массивов строк 1 массив строк
       rows.add(query2); // добавляем в тестовый Список из массивов строк 1 массив строк

   }
   public void showInitStruct(){
            //разобраться как реализован НОВЫй с джава 1.5 способ перебора
       for (String[] tmp: rows){ //для каждого массива строк в списке
           System.out.println("String[] array number " + rows.indexOf(tmp));
           for (String column : tmp) // для каждой строки в массиве строк
           {
               System.out.println(column);
           }
       }
   }
   public String  goTest() {
       return "Sucefull";
   }
}

Логика-класс:

TestIStringRowsListSorter t = new TestIStringRowsListSorter();
        t.init();
        t.showInitStruct();

результат выполнения логики:

String[] array number 0
Contact
1
Peter
String[] array number 1
Contact
2
Helga

Последние 2 класса создал для упрощения работы. Вопрос, собственно в том, как сделать сортировку используя средства Java - реализовать Comparator, и отсортировать через стандартные методы коллекции, и если да, то как это сделать?

Answer 1

Внутри вашего sort создаёте анонимный компаратор String[], в котором внутри будет виден ваш параметр columnIndex (рекомендую ознакомится с информацией об области видимости в inner классах):

public void sort(final List<String[]> rows, final int columnIndex) {
        Collections.sort(rows, new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                return o1[columnIndex].compareTo(o2[columnIndex]);  
            }
        });
    }
READ ALSO
libgdx. Распознавание нарисованного символа [требует правки]

libgdx. Распознавание нарисованного символа [требует правки]

Доброго времени суток! Скажите, есть ли какой то классический подход/алгоритм к определению нарисованного символа, будь то круг или линия?...

307
Автоматическая прокрутка текста в Layout

Автоматическая прокрутка текста в Layout

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

439
Фрагмент создается несколько раз в PagerAdapter

Фрагмент создается несколько раз в PagerAdapter

Есть MainActivity в нем есть фрагменты (DrawerMenu), в одном из них есть раздел Истории, который содержит еще 4 фрагмента подкрепляю через ViewPagerAdapter (табы)Так...

348
Как спарсить страны ВК?

Как спарсить страны ВК?

Страны беру отсюда:

336