2015-01-09 2 views
1

Есть много вопросов, связанных с этим, что предлагает использовать Comparator для сравнения и сортировки данных, и я уже пытаюсь это сделать и изо всех сил пытаюсь заставить его работать, t сообщите это как дубликат.различные способы сортировки ArrayList из HashMap <String, String>

У меня есть ArrayList из HashMap<String, String>

ArrayList<HashMap<String, String>> 

и имеющие данные в этом списке в этой форме,

title, link и number ключи.

{ {title="",link="",number=}, {title="",link="",number=}, {title="",link="",number=} } 

Пример,

{ {title,link,number = 8}, {title,link,number = 1}, {title,link,number = 3} } 

должна быть изменена на

{ {title,link,number = 1}, {title,link,number = 3}, {title,link,number = 8} } 

, и я хотел, чтобы разобраться, что на основе числа, я попробовал это,

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

public class SortData implements Comparator<ArrayList<HashMap<String, String>>> 

метод, который автоматически реализуется в том,

@Override 
    public int compare(ArrayList<HashMap<String, String>> lhs, 
      ArrayList<HashMap<String, String>> rhs) { 


     return 0; 
    } 

Теперь этот метод предлагается использовать два ArrayList из Hashmap для сравнения, но так как у меня есть только один ArrayList, который должен быть отсортирован так, что должно я использую для второго arraylist?

мой Список_массивов зовут SecondArray, и я хочу, чтобы сравнить значения каждого его со следующим значением,

@Override 
     public int compare(ArrayList<HashMap<String, String>> lhs, 
       ArrayList<HashMap<String, String>> rhs) { 

       lhs = SecondArray; 
       rhs = // How to compare to the next value of the same Array ? 
      return 0; 
     } 

Как я должен сравнить тот же ArrayList со следующим значением?

Update: каждый элемент списка Массив имеет три пары ключ/значение, один из них является числом, я хочу, чтобы отсортировать ArrayList на основе этого числа, что означает, пар ключ/значение, которое имеет самое низкое число должно быть первым в списке массивов.

+4

Как может HashMap есть данные '{{название, ссылка, номер}, {название, ссылка, номер}, {название, ссылка, номер}} '? Карты являются ключевыми = значение ... –

+0

Что именно вы хотите отсортировать? И что именно вы хотите выполнить, сортируя? Это звучит как проблема [xy] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – chancea

+0

Вы хотите отсортировать ArrayLists из hashmaps или вы хотите отсортировать хэш-файлы внутри ArrayList? Потому что то, что вы пытаетесь сделать, заключается в том, чтобы собрать arraylist для arraylist, что означало бы, что вы хотите отсортировать arraylist arraylists hashmaps ... Кажется, сложнее. O_o – Gladhus

ответ

0

как о не использовании Comparator класса и просто реализации пузырь сортировка?

что-то вроде этого,

for (int c = 0; c < (yourArrayList.size() - 1); c++) { 
      for (int d = 0; d < (yourArrayList.size() - c - 1); d++) { 

       if (Integer.parseInt(yourArrayList.get(d).get("number")) > Integer 
         .parseInt(yourArrayList.get(d + 1).get("number"))) { 

        temporary = yourArrayList.get(d); 
        yourArrayList.set(d, yourArrayList.get(d + 1)); 
        yourArrayList.set(d + 1, temporary); 

       } 
      } 
     } 

Посмотрите на этот пример,

import java.util.ArrayList; 
import java.util.HashMap; 

public class Main { 

    public static void main(String[] args) { 

     ArrayList<HashMap<String, String>> yourArrayList = 
       new ArrayList<HashMap<String, String>>(); 

     HashMap<String, String> myHashMap = new HashMap<String, String>(); 

     myHashMap.put("title", "first Title"); 
     myHashMap.put("date", "This is 1st date"); 
     myHashMap.put("number", "5"); 
     yourArrayList.add(0, myHashMap); 

     myHashMap = new HashMap<String, String>(); 

     myHashMap.put("title", "Second Title"); 
     myHashMap.put("date", "This is 2nd date"); 
     myHashMap.put("number", "2"); 
     yourArrayList.add(1, myHashMap); 

     myHashMap = new HashMap<String, String>(); 

     myHashMap.put("title", "Third Title"); 
     myHashMap.put("date", "This is 3rd date"); 
     myHashMap.put("number", "7"); 
     yourArrayList.add(2, myHashMap); 

     myHashMap = new HashMap<String, String>(); 

     myHashMap.put("title", "Fourth Title"); 
     myHashMap.put("date", "This is 4th date"); 
     myHashMap.put("number", "0"); 
     yourArrayList.add(3, myHashMap); 

     System.out.println("================="); 
     System.out.println("BEFORE SORTING"); 
     System.out.println("================="); 

     for (int i = 0; i < yourArrayList.size(); i++) { 
      System.out.println(yourArrayList.get(i)); 
     } 

     HashMap<String, String> temporary; 

     for (int c = 0; c < (yourArrayList.size() - 1); c++) { 
      for (int d = 0; d < (yourArrayList.size() - c - 1); d++) { 

       if (Integer.parseInt(yourArrayList.get(d).get("number")) > Integer 
         .parseInt(yourArrayList.get(d + 1).get("number"))) { 

        temporary = yourArrayList.get(d); 
        yourArrayList.set(d, yourArrayList.get(d + 1)); 
        yourArrayList.set(d + 1, temporary); 

       } 
      } 
     } 

     System.out.println("================="); 
     System.out.println("AFTER SORTING"); 
     System.out.println("================="); 

     for (int i = 0; i < yourArrayList.size(); i++) { 
      System.out.println(yourArrayList.get(i)); 
     } 

    } 

} 

выход,

================= 
BEFORE SORTING 
================= 
{date=This is 1st date, number=5, title=first Title} 
{date=This is 2nd date, number=2, title=Second Title} 
{date=This is 3rd date, number=7, title=Third Title} 
{date=This is 4th date, number=0, title=Fourth Title} 
================= 
AFTER SORTING 
================= 
{date=This is 4th date, number=0, title=Fourth Title} 
{date=This is 2nd date, number=2, title=Second Title} 
{date=This is 1st date, number=5, title=first Title} 
{date=This is 3rd date, number=7, title=Third Title} 

Вы можете проверить это здесь ->http://goo.gl/0M3rBf

+1

спасибо просто и эффективно: = 0 – Joe

+2

@ Сортировка пузырьков Джо очень далека от эффективной (см., Например, видео https://www.youtube.com/watch?v=ZZuD6iUe3Pc), но это действительно простой. Если вы ищете эффективное решение, используйте метод 'sort' по умолчанию, который использует эффективные алгоритмы (в настоящее время в большинстве случаев используется слегка оптимизированная версия слияния-сортировки), ваша единственная задача - предоставить код, который должен решить, нужно ли заменять два элемента (Компаратор), поэтому вам не нужно реализовывать алгоритм сортировки, основное задание - выбирать *, какие элементы следует сравнивать * (и меняться местами, если они находятся в неправильных положениях). – Pshemo

+0

, но мне просто нужно сортировать числа ... что может быть проще, чем реализация сортировки пузырьков? не лучше ли писать вложенный цикл вместо импорта всего нового класса? – Joe

1

При сортировке List из Map сек, где вы хотите отсортировать по ключу «номер» Я считаю, что вы должны использовать это вместо того, чтобы:

Collections.sort(myList, new Comparator<Map<String, String>>() { 
     @Override 
     public int compare(final Map<String, String> o1, final Map<String, String> o2) { 
      // Do your sorting... 
      return Integer.valueOf(o1.get("number")) 
          .compareTo(Integer.valueOf(o2.get("number"))); 
     } 
    }); 

Или, если вы используете Java 8 вы можете сортировать List из Map s, как это:

final List<Map<String, String>> sorted = 
    myList.stream() 
      .sorted((m1, m2) -> Integer.valueOf(m1.get("number")) 
            .compareTo(Integer.valueOf(m2.get("number")))) 
      .collect(Collectors.toList()); 
2

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

public class SortData implements Comparator<HashMap<String, String>> 
//           ^^^^^^^^^^^^^^^^^^^^^^^ 

не

public class SortData implements Comparator<ArrayList<HashMap<String, String>>> 
// this would sort collection of -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
// like List<ArrayList<HashMap<String, String>>> 

также при условии, что {title,link,number} ключи в вашей карте, ваш compare код должен вероятно выглядеть

public int compare(HashMap<String, String> o1, HashMap<String, String> o2) { 
    int nr1= Integer.parseInt(o1.get("number")); 
    int nr2= Integer.parseInt(o2.get("number")); 
    return Integer.compare(nr1, nr2); 
} 

Но если вы уверены, что карта будет удерживайте только значения для title, link и number то я бы создать отдельный класс для этой структуры, как

class Data{//you should also pick better name :) 
    private String title; 
    private String link;//you can also use URL here instead of String, 
    private int number; 
    //add getters and setters for each field like 
    public int getNumber(){ 
     return number; 
    } 
} 

Таким образом, ваш компаратор будет проще

public class SortData implements Comparator<Data>{ 

    @Override 
    public int compare(Data o1, Data o2) { 
     return Integer.compare(o1.getNumber(), o2.getNumber()); 
    } 
} 

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

Comparator<Data> numberComparator = (o1,o2)->Integer.compare(o1.getNumber(), o2.getNumber()); 

Если вы хотите, чтобы сократить свой код, который вы можете также использовать метод ссылки

COmparator<Data> numberComparator = Comparator.comparingInt(Data::getNumber); 

Так что теперь ваш список

List<Data> list = ... 

могут быть отсортированы как

list.sort(numberComparator); 

или

list.sort(Comparator.comparingInt(Data::getNumber)); 
+1

Woah, Lambdas бескомпромиссны. Не знал об этом – chancea

+2

@downvoter Если что-то не так с этим ответом, не стесняйтесь, дайте мне знать о том, чтобы я мог его исправить. В настоящее время ответ содержит объяснение проблемы и решения на основе кода OP и предложения о том, как улучшить его еще дальше. Я что-то пропустил? – Pshemo

+2

Lambdas - это весело! определенно лучший ответ. –

3

Изменить орудия для Comparator<Hashmap<String,String>> и использования:

public int compare(HashMap<String, String>> lhs, 
     HashMap<String, String>> rhs) { 
    return Integer.compare(Integer.parseInt(lhs.get("number")), 
     Integer.parseInt(rhs.get("number"))); 
} 

Я предполагаю, что вы имели в виду список (Hash) карт.

3

Я настоятельно рекомендую сделать класс данных удерживающего для 3 переменных и просто, что класс реализации Comarable (вы можете создать отдельный класс, который реализует Comparator как вы показали, но я считаю, что будет более сложным)

После того, как вы реализуете сопоставимые, вы можете использовать Collections.sort, чтобы просто отсортировать ваш список.

Здесь я выполнил короткий пример:

import java.util.*; 
import java.lang.*; 
import java.io.*; 

class Data implements Comparable<Data> 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     List<Data> data = new ArrayList<Data>(); 
     data.add(new Data("Title1", "Link1", 8)); 
     data.add(new Data("Title2", "Link2", 1)); 
     data.add(new Data("Title3", "Link3", 3)); 

     for(Data d : data) 
     { 
      System.out.print(d.getNumber() + " "); 
     } 

     System.out.println(); 

     Collections.sort(data); 

     for(Data d : data) 
     { 
      System.out.print(d.getNumber() + " "); 
     } 
    } 

    private String title; 
    private String link; 
    private int number; 

    public Data(){} 
    public Data(String title, String link, int number) 
    { 
     setTitle(title); 
     setLink(link); 
     setNumber(number); 
    } 
    public void setTitle(String title) 
    { 
     this.title = title; 
    } 

    public void setLink(String link) 
    { 
     this.link = link; 
    } 

    public void setNumber(int number) 
    { 
     this.number = number; 
    } 

    public String getTitle() 
    { 
     return title; 
    } 

    public String getLink() 
    { 
     return link; 
    } 

    public int getNumber() 
    { 
     return number; 
    } 

    @Override 
    public int compareTo(Data data) 
    { 
     return this.getNumber() - data.getNumber(); 
    } 
} 

Выход:

8 1 3 
1 3 8 

Вы можете попробовать это на Ideone

+0

Этот ответ имеет больше смысла +1, я постараюсь его понять ... Большое спасибо – Joe

+0

Мне нравится идея реализации 'Comparable', но стоит упомянуть, что это позволяет использовать только один способ сравнения. Роль «компаратора» заключается в предоставлении * дополнительных * способов сравнения наших данных. – Pshemo

+1

, если это проще сделать с простой сортировкой пузырьков, зачем внедрять 'Comparable' в первую очередь? –

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