Resolver: RecordSet >> List >> Ordenação

4 respostas
santoro

Pessoal eu tenho uma tabela - ID_MENU - DESCRICAO - ID_MENU_PAI

Percorro o RecordSet e guardo os dados em um List.

Porém se eu mando ler os dados:

public void imprimeLista(List lista)
	{
		for (int i=0; i< lista.size(); i++)
		{
			Menu m = new Menu();
			m = (Menu)lista.get(i);
			System.out.print(m.getId_menu()+" | ");
			System.out.println(m.getId_menu_pai());
		}
	}

Saída
1 | 0
2 | 1
3 | 2
4 | 0
5 | 1
6 | 0

onde 1 é um nó pai, 2 é filho de um, 3 é filho de 2, 4 é nó pai, cinco é filho de 1 e seis é nó pai…

bom como eu faço para ordenar esta lista da seguinte forma

onde:

estes são os dados
 |_ 1
     |_ 2
         |_3
     |_ 5
 |_ 4
 |_ 6

4 Respostas

B

Que banco tais usando ?? Não aceita consultas hierárquicas ?

santoro

Estou usando o Firebird

_fs

Sem tratar com objeto, mas direto com numeros fica ruim cara. Popule objetos que tem referências a seus pais e os pais tem uma coleção de filhos.

Por exemplo:

class Node {
    private Integer id;
    private Integer parentId;
    private Node parent;
    private List /*Node*/ children = new ArrayList();

    public Node( id, parentId ) {
        this.id = id;
        this.parentId = parentId );
    }

    public boolean isRoot() {
        return parentId == null;
    }

    public void addChild( Node child ) {
        children.add( child );
    }
    
    public Node getParent() {
        return parent;
    }

    public Integer getId() {
        return id;
    }

    public Integer getParentId() {
        return parentId;
    }
    
    public boolean equals( Object obj ) {
        if( obj instanceof Node ) {
            Node node = ( Node ) obj;
            if( node.id != null && id != null )
                return node.id.equals( id );
        }
        return false;
    }
}

class PopulatorPlus {
    public void populate() {
        Map map = new HashMap();
        // faz a consulta e cria objetos Node
        // e os coloca nomap ex: map.put( id, new Node( id, parentId ) );

        List rootNodes = new ArrayList();

        for( Iterator i = map.keySet().iterator(); i.hasNext() ) {
            Integer id = ( Integer ) i.next();
            Node node = ( Node ) map.get( id );
            Integer parentId = node.getParentId();
            if( parentId != null ) {
                Node parentNode = ( Node ) map.get( parentId );
                parentNode.addChild( node );
            }
            else if( !rootNodes.contains( node ) ) {
                rootNodes.add( node );    
            }
        }

        sortLevels( rootNodes );
    }

    // recursivamente ordena cada nível
    private void sortLevels( List nodes ) {
        Collections.sort( nodes, getComparator() );

        for( Iterator i = nodes .iterator(); i.hasNext() ) {
            Node node = ( Node ) i.next();
            if( node.getChildren().size() > 0 )
                sortLevels( node.getChildren() );
        }
    }

    private Comparator comparator;
    private Comparator getComparator() {
        if( comparator == null ) {
            comparator = new Comparator() {
                public int compare( Object o1, Object o2 ) {
                    Node n1 = ( Node ) o1;
                    Node n2 = ( Node ) o2;
                    
		    return n1.getId().compareTo( n2.getId() );
                }
            };
        }

        return comparator;
    }
}

Cara, alguns apontamentos:

  • escrevi o código aqui no fórum, deve estar cheio de erros de sintaxe
  • não testei
  • não cursei CC, então tenho certeza absoluta de que há algum algoritmo mmmmuito melhor, mais rápido e mais bonito para fazer isso :smiley:

[editei algumas coisas]

_fs

Ah, se estivesse usando o Hibernate o único método que precisaria é o sortLevels() e o getComparator() :smiley:

Criado 5 de agosto de 2005
Ultima resposta 5 de ago. de 2005
Respostas 4
Participantes 3