Pregunta

Supongamos que tengo una lista (o conjunto):

List<String> testList = Lists.newArrayList("assocX","srcT","destA","srcX", "don't care Y", "garbage", "srcB");

Me gustaría volver una ImmutableList (Set) que ordena / grupos de términos en orden natural donde los términos que comienzan con "src" son en primer lugar, "Assoc" segundo y "destino" pasado. Si un término no contiene aquellos entonces debe ser retirado de la lista resultante.

Por lo tanto el resultado aquí es "SRCB", "SRCT", "assocX", "Desta".

Creo que puedo hacer esto con una combinación de Iterables.filter o predicados, pero simplemente no verlo. Tiene que haber una manera sucinta de hacerlo creo.

EDIT:. Un conjunto en lugar de una lista funciona tan bien

¿Fue útil?

Solución

Mientras esos tres prefijos son las únicas cosas que le interesan, me gustaría sugerir algo como esto:

    Predicate<String> filter = new Predicate<String>() {
        @Override
        public boolean apply(String input) {
            return input.startsWith("src") || input.startsWith("assoc") || input.startsWith("dest");
        }
    };

    Function<String, Integer> assignWeights = new Function<String, Integer>() {
        @Override
        public Integer apply(String from) {
            if (from.startsWith("src")) {
                return 0;
            } else if (from.startsWith("assoc")) {
                return 1;
            } else if (from.startsWith("dest")) {
                return 2;
            } else {
                /* Shouldn't be possible but have to do something */
                throw new IllegalArgrumentException(from + " is not a valid argument");
            }
        }
    };

    ImmutableList<String> sortedFiltered = ImmutableList.copyOf(
            Ordering.natural().onResultOf(assignWeights).sortedCopy(
                    Iterables.filter(testList, filter)
            )
    );

Esta solución sería sin duda no escalar muy bien si usted comienza a añadir más prefijos para filtrar o ordenar por, ya que tendría que actualizar continuamente tanto el filtro y el peso de cada prefijo.

Otros consejos

Para consultar Este ejemplo Google Colecciones .

Function<Fruit, String> getNameFunction = new Function<Fruit, String>() {
    public String apply(Fruit from) {
        return from.getName();
    }
};

Ordering<Fruit> nameOrdering = Ordering.natural().onResultOf(getNameFunction);

ImmutableSortedSet<Fruit> sortedFruits = ImmutableSortedSet.orderedBy(
    nameOrdering).addAll(fruits).build();

A pesar de esto, sin duda, devuelve un conjunto.

Yo creo que tengas primero en utilizar el predicado para eliminar los elementos que no desee, y la implementación de un Comparador y ordenar a su lista.

Por lo general es un mal diseño para cotejar los datos que se distinguen claramente como esta. En su caso, cuando se dice "assocX", "Assoc" tiene un significado independiente de "X", sin embargo, que ellos se funden juntos.

Así que podría sugerir el diseño de una clase con dos campos. A continuación, puede crear un ordenamiento en el primer campo, otro en el segundo, y combinarlos (por ejemplo, compuesto de pedido # ()). Con un método toString () que no fusionar estos campos en una cadena. Como beneficio adicional, esto puede reducir en gran medida el uso de memoria a través de compartir.

Así que sería ordenar una lista de tales objetos, y si querías para imprimirlos, usted acaba de llamar a toString () sobre ellos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top