Domanda

Supponiamo che io ho una lista (o Set):

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

Mi piacerebbe tornare un ImmutableList (Set) che ordina / gruppi di termini in ordine naturale in cui i termini che iniziano con "src" sono in primo luogo, "assoc" seconda e "dest" ultima. Se un termine non contiene quelle allora dovrebbe essere rimosso dalla lista risultante.

Quindi il risultato qui è "srcB", "srcT", "assocX", "Desta".

Credo di poter fare questo con una certa combinazione di Iterables.filter o predicati, ma semplicemente non vederlo. Ci deve essere un modo succinto di farlo credo.

EDIT:. Un set al posto di una lista funziona così

È stato utile?

Soluzione

Finché queste tre prefissi sono le uniche cose che ti interessano, io suggerirei qualcosa di simile:

    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)
            )
    );

Questa soluzione sicuramente non sarebbe scale out incredibilmente bene se si inizia ad aggiungere più prefissi per filtrare o ordinare da, dal momento che avrebbe dovuto aggiornare continuamente sia il filtro e il peso di ogni prefisso.

Altri suggerimenti

Dai un'occhiata alla Questa Google Collezioni esempio .

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();

Anche se questo, è vero, restituisce un set.

Credo che si dovrà prima di utilizzare il predicato per eliminare gli elementi che non si desidera, e l'attuazione di una comparatore e ordinare la vostra lista.

Di solito è cattivo design per raccogliere dati nettamente distinte come questo. Nel tuo caso, quando si dice "assocX", "assoc" ha un significato distinto da "X", eppure si fondono insieme.

Quindi, vorrei suggerire la progettazione di una classe con due campi. Quindi è possibile creare un ordinamento sul primo campo, un altro sulla seconda, e combinarli (ad esempio Ordinamento # composto ()). Con un metodo toString () che ha unire questi campi in una stringa. Come bonus, questo può ridurre notevolmente l'utilizzo della memoria attraverso la condivisione.

Quindi, si sarebbe ordinamento di un elenco di tali oggetti, e se si voleva di stamparli, si sarebbe solo chiamare toString () su di loro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top