2016-05-03 6 views
5

Итак, я работаю над функцией поиска по ширине и ширине для программы, над которой я работаю в школе, и когда я просматриваю исходящие ребра для данного узла, в силу того, как я просматриваю свои возможные края , это выглядит примерно так:Как я могу отсортировать ArrayList <ArrayList <String>>?

[[A, 1], [D, 1], [C, 2], [D, 2]] 

Но что я действительно хочу это:

[[A, 1], [C, 2], [D, 1], [D, 2]] 

Если первый индекс пары имя узла, что краевые точки к и второй индекс - это метка для ребра. По сути, я хочу пройти эти ребра по алфавиту, сначала по имени узла, затем по имени метки, но я не уверен, как это сделать, поскольку Collections.sort() не работает для 2D ArrayList. Любые указатели/идеи по хорошему методу сортировки этого? Всем спасибо!

EDIT: Я использую JRE 1.7 для этого задания, а не 1,8

+0

'[[А, 1], [D, 1], [C, 2], [D, 2]] 'не является допустимым примером для' ArrayList > ' Вы можете использовать' .stream(). Sorted() 'для сортировки по естественному порядку или даже для определения custom 'Comparator' –

+0

Вы можете использовать HashMap вместо ArrayList ... – RoiEX

+1

RoiEX, не мог использовать HashMap, так как он может иметь Ключ, который имеет разные значения или должен быть HashMap ... что делает довольно сложную структуру для чего-то простого. – jeorfevre

ответ

2

здесь полный рабочий код. Работа с выражением лямбда в java SDK8.

Как вы увидите, я добавил простой класс и компаратор. Это просто и мощно.

package com.rizze.test.labs.sof; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 

import org.junit.Test; 

public class SOF {  

    public static class Link { 
     public String name; 
     public int id; 

     public static Link build(String n, int i){ 
      Link l = new Link(); 
      l.name = n; 
      l.id=i; 
      return l; 
     } 

     public String toString(){ 
      return String.format("[%s , %d]", name,id); 
     }   
    }  

    @Test 
    public void test() { 

     List<Link> links = new ArrayList<Link>(); 

     //SSETUP [[A, 1], [C, 2], [D, 1], [D, 2]] 
     links.add(Link.build("D", 1)); 
     links.add(Link.build("A", 1)); 
     links.add(Link.build("D", 2)); 
     links.add(Link.build("C", 2)); 


     Collections.sort(links, new Comparator<Link>() {  
      @Override 
      public int compare(Link p1, Link p2) { 
       int ret = p1.name.compareTo(p2.name); 
       if(ret == 0) { 
        ret= p1.id - p2.id; 
       } 
       return ret;    
      }    
     }); 
     System.out.println(links);   
    }  
} 

// Консоль вывода

Before : [[D , 1], [A , 1], [D , 2], [C , 2]] 
Sorted: [[A , 1], [C , 2], [D , 1], [D , 2]] 

// GIST ссылка https://gist.github.com/jeorfevre/cbcd7dac5d7fabde6a16db83bdfb7ef5

2

@jeorfevre ответ совершенно нормально. Вы не упомянули версию Java, но я бы пошел со статическими методами Comparator.

Решение будет декларативным и даст вам больше контроля и ясность в сжатом виде:

public class Test { 
    public static class Edge { 
     private String name; 
     private int label; 
     public Edge(String name, int id) { 
      this.name = name; 
      this.label = id; 
     } 
     public String toString() { 
      return String.format("[%s , %d]", name, label); 
     } 
     public String getName() { return name; } 
     public int getLabel() { return label; } 
    } 


    public static void main(String[] args) { 
     List<Edge> edges = new ArrayList<>(); 
     edges.add(new Edge("D", 1)); 
     edges.add(new Edge("A", 1)); 
     edges.add(new Edge("D", 2)); 
     edges.add(new Edge("C", 2)); 

     Comparator<Edge> comparator = Comparator 
       .comparing(Edge::getName) 
       .thenComparing(Edge::getLabel); 

     edges.sort(comparator); 

     System.out.println(edges); 
    } 
} 

Если вы хотите обращенный заказ:

  Comparator<Edge> comparator = Comparator 
       .comparing(Edge::getName) 
       .thenComparing(Edge::getLabel) 
       .reversed(); 

дает вам:

[[D , 2], [D , 1], [C , 2], [A , 1]] 

И

выход: [[D, 1], [D, 2], [С, 2], [А, 1]]

+0

Это выглядит великолепно! Это в значительной степени то, что я думал о внедрении (класс Edge), и это дает мне немного больше информации о том, как я должен управлять своими краями. Мой следующий вопрос заключается в том, что я работаю с этими ребрами не внутри класса Edge, а в совершенно другом классе, где бы я поставил компаратор? Пойдет ли он во все функции, с которыми я сейчас работаю?Извинения, я относительно новичок в Java и очень новичок в компараторах. –

+0

Кроме того, у меня возникла проблема с командами Edge :: getName и Edge :: getLabel, потому что для этого назначения мой профессор хочет, чтобы мы использовали JRE 1.7, а не 1.8. Есть ли другой способ реализовать это с помощью JRE 1.7? –

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