Отсортировать массив в JAVA (цифры + текст)

272
09 января 2018, 14:14

Как отсортировать массив по числам, которые идут перед URl. Допустим есть данные:

String a[] = {"3 badoo.com", "1 google.com", "70 stackoverflow.com", "14 vk.com"}

Чтобы стало после Array.sort(a) :

String a[] = {"1 google.com", "3 badoo.com", "14 vk.com", "70 stackoverflow.com"}
Answer 1

Парсить строку и задать собственный компаратор:

//метод, который вытаскивает из строки число
static Integer extractNumber(String s) {
    //считаем что строка начинается с числа и после числа идет пробел
    return Integer.valueOf(s.split(" ")[0]);
}
//сортировка
Arrays.sort(a, (String s1, String s2) -> extractNumber(s1).compareTo(extractNumber(s2)));

Как @Дмитрий уже написал в комментариях: то, что числа и адреса слеплены в строку выглядит неопрятно. При изменении формата придется искать по коду вручную прописанные индексы, сложно добавить обработку ошибок. При добавлении полей разбор строк может разрастись и пустить метастазы по коду. Т.ч. в долгосрочной перспективе имеет смысл создать для хранения информации класс с отдельными полями.

Answer 2

Вот более ОО решение. Для конвертации строк в список объектов я использовал стримы. Класс наследует интерфейс Comparable для возможности сортировки без использования отдельного Comparator'a и является Immutable(разницу между Immutable vs Mutable можно посмотреть тут)

public class Test {
    public static void main(String[] args) {
    String a[] = { "3 badoo.com", "1 google.com", "70 stackoverflow.com", "14 vk.com" };
    List<IndexedURL> indexedURLs = Stream.of(a).map(IndexedURL::getInstance).collect(Collectors.toList());
    Collections.sort(indexedURLs);
    System.out.println(indexedURLs);
    }
}
final class IndexedURL implements Comparable<IndexedURL> {
    public final int index;
    public final String url; // или даже URL класс
    public IndexedURL(int index, String url) {
        this.index = index;
        this.url = url;
    }
    public int getIndex() {
        return index;
    }
    public String getUrl() {
        return url;
    }
    public static IndexedURL getInstance(String obj) {
       String[] split = obj.split(" ");
        try {
            if (split.length == 2) {
                return new IndexedURL(Integer.parseInt(split[0]), split[1]);
            } else {
                throw new IllegalArgumentException();
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("Cant parse obj from String :" + obj);
        }
    }
    @Override
    public int compareTo(IndexedURL o) {
        return Integer.compare(this.getIndex(), o.getIndex());
    }
    @Override
    public String toString() {
        return "IndexedURL [index=" + index + ", url=" + url + "]";
    }
    // eq and hash code

}

Также необходимо реализовать методы equals и hashCode для корректного использования объектов в коллекциях ссылка

READ ALSO
Ajax отправка POST запроса на сервлет (Java)

Ajax отправка POST запроса на сервлет (Java)

Проблема следующаяЕсть сервлет на сервере, который принимает данные в формате json

198
Изменить context проекта Spring

Изменить context проекта Spring

Изменяю context-root проекта через properties->Web Project Settings с training на SpringMVCНо приложение всё равно работает только по этому адресу, почему?

165
Исключение при загрузке данных из xml

Исключение при загрузке данных из xml

Я создал JavaFX проект и в контроллере главного окна реализую метод, в котором при нажатии на кнопку должно создаться новое модальное окно, но при...

163
Почему Presenter не пересоздается вместе с Activity

Почему Presenter не пересоздается вместе с Activity

Не могу понять как работает MvpPresenterПочему когда Activity пересоздается, то MvpPresenter все еще живет

165