2016-07-04 1 views
2

У меня, например, этот многомерный массив:Как отсортировать многомерный массив строк по одному столбцу в целочисленном значении в java?

String [] [] Массив = новый String [10] [2];

В первом столбце у меня есть строки, которые в моем случае являются именами пользователей, но во втором столбце у меня есть строки, которые должны представлять целые числа. Теперь я хочу, чтобы отсортировать массив как это:

Before: 

Petter 543 
John 276 
Jay 1879 
Alf 5021 
etc. 

After: 

Alf 5021 
Jay 1879 
Petter 543 
John 276 
etc. 

Так что я хочу, самое высокое значение в верхней и самой низкой в ​​нижней части, но не испортить имена. Все, что я нашел до сих пор, это то, как отсортировать все целые многомерные массивы или только строковые многомерные массивы, а не как просто отсортировать второй столбец на основе целых чисел.

однажды я получил его отсортирован, но это был отсортирован в «буквенного» способом:

Так 1000 был высокий балл 12 был второй самый высокий балл и был самый низкий балл 999999.

Как 1 представляет «a», а 9 представляет «z».

ответ

3

Использование Java 8 потоков:

String[][] out = Arrays.stream(names) 
    .sorted(Comparator.comparing(x -> -Integer.parseInt(x[1]))) 
    .toArray(String[][]::new); 
3

Если человек и идентификатор связаны каким-либо образом, то лучше было бы создать, что модели их (POJO) класс, сделать что POJO класс сопоставимыми, определить список из POJO и использование Коллекции # сортировать по сортируется в соответствии с требуемыми критериями ...

другая вещь, чтобы рассмотреть, что у вас есть массив 2 Строки х мерной String [] [] но ваш вопрос состояния

... Как отсортировать многомерный массив строк по одному столбцу в целого значения в java?

, что означает, что вам необходимо рассмотреть, чтобы разобрать строку в целое ... (так же, как хороший намек)

public class MyPojo implement Comparator<MyPojo>{ 

private String name; 

private String id; 
...implements the method of the comparator 

} 

сделай в главном тестовом классе

List<MyPojo> mList = new ArrayList<MyPojo>(); 
mList.add(...); 
mList.add(...); 
mList.add(...); 



Collections.sort(mList); 
System.out.println(mList) 
+0

Я взгляну на это! – creativecreatorormaybenot

2

Моим советом было бы взять второй столбец 2D-массива и поместить его в свой собственный целочисленный массив. Затем вызовите Arrays.sort() на этом массиве. Наконец, поместите вновь отсортированный массив обратно в 2D-массив как строковые значения.Вот то, что она должна выглядеть,

int arr = new int[10]; 
String[][] copy = new String[10][2]; 
for(int i = 0; i < array.length; i++){ 
    arr[i] = Integer.parseInt(array[i][1]); 
    System.arraycopy(array[i], 0, copy[i], 0, array[i].length); 
} 
Arrays.sort(arr); 
for(int i = 0; i < array.length; i++){ 
    array[i][1] = String.valueOf(arr[i]); 
} 

//fixing the names 
for(int i = 0; i < copy.length; i++){ 
    for(int j = 0; j < array.length; j++){ 
     if(copy[i][1] == array[j][1]){ 
      array[j][0] = copy[i][0]; 
      break; 
     } 
    } 
} 

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

+0

Да, но теперь имена прищурены, и у Альфа есть оценка 120, если у него было до одного из 5000, которого я не хочу. – creativecreatorormaybenot

+0

@creativecreatorormaybenot я вижу, моя ошибка. Чтобы решить проблему с именем, я подумал о создании копии 2D-массива, чтобы после сортировки значений int вы могли вернуться и исправить имена соответственно, увидев, где значения int менялись. Таким образом, вы можете переназначить имя так, чтобы его значение соответствовало значению int. –

2

перебирает массив до его сортирует и поменять каждый раз, когда это не так.

public static void main(String[] args) { 
    String[][] array = new String[4][2]; 
    array[0][0] = "Petter"; array[0][1] = "543"; 
    array[1][0] = "John"; array[1][1] = "276"; 
    array[2][0] = "Jay"; array[2][1] = "1879"; 
    array[3][0] = "Alf"; array[3][1] = "5021"; 

    System.out.println(Arrays.deepToString(array)); // [[Petter, 543], [John, 276], [Jay, 1879], [Alf, 5021]] 

    sortArrayByScore(array); 

    System.out.println(Arrays.deepToString(array)); // [[Alf, 5021], [Jay, 1879], [Petter, 543], [John, 276]] 
} 

public static void sortArrayByScore(String[][] array) { 
    String tmpName, tmpScore; 
    boolean sorted = false; 

    while (!sorted) { 
     sorted = true; 
     for (int i = 0 ; i < array.length - 1 ; i++) { 
      if (Integer.parseInt(array[i][1]) < Integer.parseInt(array[i+1][1])){ 
       sorted = false; 
       // SWAP NAMES 
       tmpName = array[i][0]; 
       array[i][0] = array[i+1][0]; 
       array[i+1][0] = tmpName; 

       // SWAP SCORES 
       tmpScore = array[i][1]; 
       array[i][1] = array[i+1][1]; 
       array[i+1][1] = tmpScore; 
      } 
     } 
    } 

} 
+1

Я буду defenitly смотреть на это, когда у меня есть время, чтобы сделать, но на данный момент ответ krzyk действительно хорош! – creativecreatorormaybenot

1

Используйте компаратор для сортировки элементов в массиве. В вашем случае у вас есть массив массивов, поэтому вам нужен компаратор для массива. Вы можете использовать массив Comparator of String, который принимает значение 2-го элемента.

public class SomeComparator implements Comparator<String[]> { 
    /** 
    * Assumes each row is length 2 and the 2nd String is really a number. 
    */ 
    @Override 
    public int compare(String[] row1, String[] row2) { 
     int value1 = Integer.parseInt(row1[1]); 
     int value2 = Integer.parseInt(row2[1]); 
     // compare value2 first to sort descending (high to low) 
     return Integer.compare(value2, value1); 
    } 
} 

Тогда вы можете сортировать используя Arrays.sort как этот

String[][] data = newData(); // or however you get your data 
Arrays.sort(data, new SomeComparator()); 
+0

Использование компаратора является правильным, но стилистически было бы лучше либо встроить определение компаратора с помощью lambdas, либо взять маршрут OO, и определить сравнимую POJO для хранения данных, как предложил другой комментатор. –

+1

Привет @IgnatiusNothnagel - Я предпочитаю извлекать код для вспомогательного метода или класса для повторного использования и тестирования. Копирование данных в POJO, сортировка и копирование будут работать, но кажется ненужной работой, так как данные могут быть отсортированы на месте. – pmcevoy12

+0

Это имеет смысл, особенно в отношении тестирования. –

0

Вы можете использовать компаратор, который сортирует внутренний String [] элементов на целое значение второго элемента, вместо использования строка по умолчанию сортировка:

Arrays.sort(array, (o1, o2) -> Integer.valueOf(o2[1]).compareTo(Integer.valueOf(o1[1]))); 

Здесь используется синтаксис лямбда, чтобы сделать то же самое, как будет достигнуто за счет:

Arrays.sort(data, new Comparator<String[]>() { 
    @Override 
    public int compare(String[] o1, String[] o2) { 
     return Integer.valueOf(o2[1]).compareTo(Integer.valueOf(o1[1])); 
    } 
}); 
+0

Чтобы уточнить: Хотя то, что я написал выше, будет работать, я считаю, что более элегантно определять Comparable POJO для хранения данных, как предложил другой комментатор, если у вас нет хорошей производительности или других причин этого не делать. –

+1

Вот что я намеренно искал! – creativecreatorormaybenot

Смежные вопросы