2011-12-15 2 views
3

Использование Коллекций для сортировки отличное, намного лучше для меня, чем использование Компаратора, поскольку у меня есть несколько значений, которые являются одинаковыми, и я бы предпочел, чтобы они не были просто выброшены в корзину. Но у Коллекций есть своя собственная проблема, кажется, что повторяющиеся числа групп из 2+ будут меньше, чем их фактические меньшие счетные части.Использование Коллекций для сортировки значений

Пример: эти клавиши и значения («katy 1», «mark 9», «john» 2" , "алиса 11", "Джозия 22", "Крис 44") и сортируют их следующим образом

Алиса 11 Kąty 1 John 2 Джозии 22 Криса 44 Mark 9

Вместо правильного порядка katy 1 john 2 mark 9 alice 11 josiah 22 mark 44

Как я могу это исправить?

ответ

4

Поскольку вы передаете строки, коллекция не имеет способ сообщить, как вы хотите интерпретировать эти строки (т. е. сортировать по числу, присутствующему внутри строки). Вы должны быть более ясными.

У вас есть два варианта в основном:

Вариант 1: Создать новый тип данных для инкапсуляции имя и номер и осуществить сравнение по номеру:

public class Person implements Comparable<Person> { 

    private String name; 
    private int number; 

    public Person(String name, int number) { 
     this.name = name; 
     this.number = number; 
    } 

    public int compareTo(Person p) { 
     if(this.number > p.number) return 1; 
     if(this.number < p.number) return -1; 
     return 0; 
    } 
} 

Тогда:

List<Person> persons = new ArrayList<Person>(); 
persons.add(new Person("alice", 11)); 
persons.add(new Person("katy", 1)); 
// etc. 
Collections.sort(persons); 

Вариант 2: Поверните строку в пару с ключом и поместите ее внутри TreeMap, которая автоматически сохраняет значения, упорядоченные по ключу:

TreeMap<Integer, String> map = new TreeMap<Integer, String>(); 
map.put(11, "alice"); 
map.put(1, "katy"); 
// etc. 
+0

Работал отлично, спасибо – ChrisD3

0

Лучшим вариантом было бы реорганизовать ваш код для разделения строк и целых чисел.

Если вы не можете или не хотите этого, вы должны предоставить свой собственный компаратор. Что-то вроде

@Override 
public int compare(String o1, String o2) { 
    Integer i1 = Integer.parseInt(o1.replaceAll("[^0-9]", "")); 
    Integer i2 = Integer.parseInt(o2.replaceAll("[^0-9]", "")); 
    return i1.compareTo(i2); 
} 

Затем вы можете использовать Collections.sort(List, Comparator)

List<String> list; // ... 
Collections.sort(list, new YourComparator()); 
0

Вы должны написать свой собственный компаратор. Если вы хотите сравнить String как число, вам нужно преобразовать его в число. В противном случае «22» < «4», хотя 22> 4.

Однако я не вижу, как вы получаете первый заказ с компаратором по умолчанию.

1

Я думаю, вы должны создать класс Person, который реализует сопоставимый интерфейс

class Person implements Comparable<Person >{ 

     String name; 
     Integer number; 
     public int compareTo(Person o) { 

     return number.compareTo(o.number); 
    } 

} 
0

проверить этот пример

Редактировать

public static void main(String arg[]){ 

    List<String> l = Arrays.asList(new String[]{"katy 1","mark 9","john 2","alice 11","josiah 22","chris 44"}); 

    Collections.sort(l, new Comparator<String>() { 
     public int compare(String x, String y) { 
      Integer a = Integer.parseInt(x.substring(x.indexOf(" ")).trim()); 
      Integer b = Integer.parseInt(y.substring(y.indexOf(" ")).trim()); 
      return a.compareTo(b); 
     } 
    }); 
    System.out.println(l.toString()); 
} 
+1

Почему это так сложно? Класс Integer отлично способен выполнить свое сравнение –

+0

@ JohanSjöberg да, вы правы. На самом деле я не знаю об этом спасибо за очищение концепции – Pratik

2
  1. Хранить данные в виде Map<String, Integer> - не втиснуть два типа данных в одну строку.
  2. Получить запись установить в список и отсортировать его
  3. Поместите отсортированный запись установить в упорядоченном Карта

Вот код, который будет делать это:

public static void main(String[] args) { 
    // Set up and load the map 
    Map<String, Integer> nameAgeMap = new HashMap<String, Integer>(); 
    nameAgeMap.put("katy", 1); 
    nameAgeMap.put("chris", 44); 
    nameAgeMap.put("alice", 11); 
    nameAgeMap.put("josiah", 22); 
    nameAgeMap.put("john", 2); 

    // Create-and-load a List of entries 
    List<Map.Entry<String, Integer>> entries = new ArrayList<Map.Entry<String, Integer>>(nameAgeMap.entrySet()); 
    // Sort the list using a custom Comparator that compares the ages 
    Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() { 
     public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { 
      return o1.getValue().compareTo(o2.getValue()); 
     }}); 

    // Load the entries into a Map that preserves insert order 
    Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>(); 
    for (Map.Entry<String, Integer> entry : entries) 
     sortedMap.put(entry.getKey(), entry.getValue()); 

    // All done - let's see what we got 
    System.out.println(sortedMap); 
} 

Выход:

{katy=1, john=2, alice=11, josiah=22, chris=44} 
1

Сортировка для значений $ в порядке возрастания. если вам это нужно в порядке убывания, пожалуйста, замените переменные i1 и i2

public static void main(String[] args) { 



    List<String> l_oTestList = new ArrayList<String>(); 
    l_oTestList.add("$10000 - $12000"); 
    l_oTestList.add("$50 - $100"); 
    l_oTestList.add("$10000 - $12000"); 
    l_oTestList.add("$100 - $150"); 
    l_oTestList.add("$150 - $200"); 
    l_oTestList.add("$200 - $250"); 
    l_oTestList.add("$0 - $10"); 
    l_oTestList.add("$10 - $20"); 
    l_oTestList.add("$20 - $50"); 
    l_oTestList.add("$250 - $500"); 
    l_oTestList.add("$500 - $750"); 
    l_oTestList.add("$750 - $1000"); 
    l_oTestList.add("$1000 - $1250"); 
    l_oTestList.add("$1250 - $10000"); 
    List<String> l_oTestList1 = sort(l_oTestList); 
    System.out.println(l_oTestList1.toString()); 
} 

private static List<String> sort(List<String> pTestList) { 
    Collections.sort(pTestList, new Comparator<String>() { 
     public int compare(String o1, String o2) { 
      Integer i1 = Integer.parseInt(o1.replace("$", "").substring(0,o1.indexOf("-")-2).trim()); 
      Integer i2 = Integer.parseInt(o2.replace("$", "").substring(0,o2.indexOf("-")-2).trim()); 
      return (i2 > i1 ? -1 : (i2 == i1 ? 0 : 1)); 
     } 
    }); 
    return pTestList; 
} 
Смежные вопросы