Frage

Ich möchte a filtern java.util.Collection basierend auf einem Prädikat.

War es hilfreich?

Lösung

Java 8 (2014) löst dieses Problem mithilfe von Streams und Lambdas in einer Codezeile:

List<Person> beerDrinkers = persons.stream()
    .filter(p -> p.getAge() > 16).collect(Collectors.toList());

Hier ist ein Lernprogramm.

Verwenden Collection#removeIf um die Sammlung vor Ort zu ändern.(Beachten:In diesem Fall entfernt das Prädikat Objekte, die das Prädikat erfüllen):

persons.removeIf(p -> p.getAge() <= 16);

Lambdaj ermöglicht das Filtern von Sammlungen, ohne Schleifen oder innere Klassen schreiben zu müssen:

List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
    greaterThan(16)));

Können Sie sich etwas Lesbareres vorstellen?

Haftungsausschluss: Ich bin ein Mitwirkender bei lambdaj

Andere Tipps

Unter der Annahme, dass Sie Java 1.5 verwenden, und dass Sie können nicht Google Sammlungen hinzufügen, würde ich etwas sehr ähnlich tun, was die Google Jungs haben . Dies ist eine leichte Abwandlung Jons Kommentare.

Zuerst diese Schnittstelle zu Ihrer Codebasis hinzuzufügen.

public interface IPredicate<T> { boolean apply(T type); }

Die Implementierer beantworten kann, wenn ein bestimmtes Prädikat wahr eines bestimmten Typs ist. Z.B. Wenn T User waren und AuthorizedUserPredicate<User> implementiert IPredicate<T>, dann AuthorizedUserPredicate#apply gibt zurück, ob die in User weitergegeben autorisiert ist.

Dann in einiger Utility-Klasse, man könnte sagen,

public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
    Collection<T> result = new ArrayList<T>();
    for (T element: target) {
        if (predicate.apply(element)) {
            result.add(element);
        }
    }
    return result;
}

Also, vorausgesetzt, dass Sie die Verwendung der oben könnte sein

haben
Predicate<User> isAuthorized = new Predicate<User>() {
    public boolean apply(User user) {
        // binds a boolean method in User to a reference
        return user.isAuthorized();
    }
};
// allUsers is a Collection<User>
Collection<User> authorizedUsers = filter(allUsers, isAuthorized);

Wenn die Leistung auf der linearen Überprüfung von Belang ist, dann will ich vielleicht ein Domain-Objekt haben, den die Zielsammlung hat. Das Domain-Objekt, das die Zielsammlung hat, würde für die Methoden hat Logik Filterung, die initialisieren, hinzufügen und die Zielsammlung festgelegt.

UPDATE:

In der Utility-Klasse (sie Prädikat sagen), ich habe eine select-Methode mit einer Option für Standardwert hinzugefügt, wenn das Prädikat nicht den erwarteten Wert zurückgibt, und auch eine statische Eigenschaft für params in der neuen IPredicate verwendet werden .

public class Predicate {
    public static Object predicateParams;

    public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {
        Collection<T> result = new ArrayList<T>();
        for (T element : target) {
            if (predicate.apply(element)) {
                result.add(element);
            }
        }
        return result;
    }

    public static <T> T select(Collection<T> target, IPredicate<T> predicate) {
        T result = null;
        for (T element : target) {
            if (!predicate.apply(element))
                continue;
            result = element;
            break;
        }
        return result;
    }

    public static <T> T select(Collection<T> target, IPredicate<T> predicate, T defaultValue) {
        T result = defaultValue;
        for (T element : target) {
            if (!predicate.apply(element))
                continue;
            result = element;
            break;
        }
        return result;
    }
}

Das folgende Beispiel sucht nach Objekten zwischen einer Sammlung fehlt:

List<MyTypeA> missingObjects = (List<MyTypeA>) Predicate.filter(myCollectionOfA,
    new IPredicate<MyTypeA>() {
        public boolean apply(MyTypeA objectOfA) {
            Predicate.predicateParams = objectOfA.getName();
            return Predicate.select(myCollectionB, new IPredicate<MyTypeB>() {
                public boolean apply(MyTypeB objectOfB) {
                    return objectOfB.getName().equals(Predicate.predicateParams.toString());
                }
            }) == null;
        }
    });

Das folgende Beispiel sucht nach einer Instanz in einer Sammlung, und liefert das erste Element der Sammlung als Standardwert, wenn die Instanz nicht gefunden wird:

MyType myObject = Predicate.select(collectionOfMyType, new IPredicate<MyType>() {
public boolean apply(MyType objectOfMyType) {
    return objectOfMyType.isDefault();
}}, collectionOfMyType.get(0));

UPDATE (nach Java 8 Release):

Es ist schon einige Jahre her, dass ich (Alan) erste Antwort geschrieben, und ich kann immer noch nicht glauben, dass ich für diese Antwort SO Punkte sammle. Jedenfalls jetzt, dass Java 8 Schließungen in die Sprache eingeführt, wäre meine Antwort jetzt deutlich anders und einfacher. Mit Java 8, gibt es keine Notwendigkeit für eine bestimmte statische Utility-Klasse. Also, wenn Sie das erste Element zu finden, das Ihr Prädikat übereinstimmt.

final UserService userService = ... // perhaps injected IoC
final Optional<UserModel> userOption = userCollection.stream().filter(u -> {
    boolean isAuthorized = userService.isAuthorized(u);
    return isAuthorized;
}).findFirst();

Das JDK 8 API für optionals hat die Fähigkeit, get(), isPresent(), orElse(defaultUser), orElseGet(userSupplier) und orElseThrow(exceptionSupplier), sowie andere 'monadischen' Funktionen wie map, flatMap und filter.

Wenn Sie wollen einfach alle Benutzer sammeln, die das Prädikat übereinstimmen, dann die Collectors verwenden den Strom in der gewünschten Sammlung zu beenden.

final UserService userService = ... // perhaps injected IoC
final List<UserModel> userOption = userCollection.stream().filter(u -> {
    boolean isAuthorized = userService.isAuthorized(u);
    return isAuthorized;
}).collect(Collectors.toList());

Siehe hier für weitere Beispiele dafür, wie Java 8-Streams zu arbeiten.

„Best“ Art und Weise ist ein zu weite Anfrage. Ist es „kürzeste“? "Fastest"? "Lesbar"? Filter an Ort und Stelle oder in einer anderen Sammlung?

Einfachstes (aber nicht die meisten lesbar) Art und Weise ist es zu durchlaufen und verwendet Iterator.remove () Methode:

Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
  Foo foo = it.next();
  if( !condition(foo) ) it.remove();
}

Jetzt, damit es besser lesbar, können Sie es in ein Dienstprogramm Verfahren wickeln können. Dann erfinden eine IPredicate Schnittstelle, eine anonyme Implementierung dieser Schnittstelle erstellen und so etwas wie:

CollectionUtils.filterInPlace(col,
  new IPredicate<Foo>(){
    public boolean keepIt(Foo foo) {
      return foo.isBar();
    }
  });

Dabei gilt filterInPlace (), um die Sammlung iterieren und ruft Predicate.keepIt () zu lernen, wenn die Instanz in der Sammlung aufbewahrt werden.

Ich sehe nicht wirklich eine Rechtfertigung für nur für diese Aufgabe in einem Dritt Bibliothek zu bringen.

Google Sammlungen für einen aktualisierten Kollektionen Framework, das Generika unterstützt.

UPDATE : Die Google-Sammlungen Bibliothek ist jetzt veraltet. Sie sollten die neueste Version von Guava stattdessen verwenden. Es hat immer noch alle gleichen Erweiterungen der Sammlung Rahmen für einen Mechanismus, nach einem Prädikat Filterung.

Warten auf Java 8:

List<Person> olderThan30 = 
  //Create a Stream from the personList
  personList.stream().
  //filter the element to select only those with age >= 30
  filter(p -> p.age >= 30).
  //put those filtered elements into a new List.
  collect(Collectors.toList());

Da die frühe Version von Java 8, könnten Sie so etwas wie versuchen:

Collection<T> collection = ...;
Stream<T> stream = collection.stream().filter(...);

Zum Beispiel, wenn Sie eine Liste von ganzen Zahlen haben und man wollte die Zahlen filtern, die> 10 sind und dann aus diesen Zahlen an die Konsole zu drucken, Sie etwas tun könnten, wie:

List<Integer> numbers = Arrays.asList(12, 74, 5, 8, 16);
numbers.stream().filter(n -> n > 10).forEach(System.out::println);

Ich werde werfen RxJava im Ring, die auch auf Android . RxJava vielleicht nicht immer die beste Option, aber es wird Ihnen mehr Flexibilität, wenn Sie es wünschen mehr Transformationen auf Ihrer Sammlung hinzufügen oder Fehler beim Filtern bearbeiten.

Observable.from(Arrays.asList(1, 2, 3, 4, 5))
    .filter(new Func1<Integer, Boolean>() {
        public Boolean call(Integer i) {
            return i % 2 != 0;
        }
    })
    .subscribe(new Action1<Integer>() {
        public void call(Integer i) {
            System.out.println(i);
        }
    });

Ausgabe:

1
3
5

Weitere Informationen zu RxJava der filter können hier .

Das Setup:

public interface Predicate<T> {
  public boolean filter(T t);
}

void filterCollection(Collection<T> col, Predicate<T> predicate) {
  for (Iterator i = col.iterator(); i.hasNext();) {
    T obj = i.next();
    if (predicate.filter(obj)) {
      i.remove();
    }
  }
}

Die Nutzung:

List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
  public boolean filter(MyObject obj) {
    return obj.shouldFilter();
  }
});

Wie wäre es schlicht und straighforward Java

 List<Customer> list ...;
 List<Customer> newList = new ArrayList<>();
 for (Customer c : list){
    if (c.getName().equals("dd")) newList.add(c);
 }

Einfach, lesbar und leicht (und arbeitet in Android!) Aber wenn Sie mit Java 8 Sie es in einem süßen eine Zeile tun:

List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());

Beachten Sie, dass ToList () statisch importiert

Sind Sie sicher, dass Sie die Sammlung selbst zu filtern, anstatt ein Iterator?

siehe

org.apache.commons.collections.iterators.FilterIterator

oder mit der Version 4 von Apache Commons org.apache.commons.collections4.iterators.FilterIterator

Schauen wir uns an, wie ein filtern Einbau-JDK-Liste und einem MutableList mit Eclipse-Sammlungen (früher GS Sammlungen ).

List<Integer> jdkList = Arrays.asList(1, 2, 3, 4, 5);
MutableList<Integer> ecList = Lists.mutable.with(1, 2, 3, 4, 5);

Wenn Sie die Zahlen weniger als 3 filtern wollen, würden Sie die folgenden Ausgaben erwartet.

List<Integer> selected = Lists.mutable.with(1, 2);
List<Integer> rejected = Lists.mutable.with(3, 4, 5);

Hier ist, wie Sie filtern können eine anonyme innere Klasse, die als Predicate verwendet wird.

Predicate<Integer> lessThan3 = new Predicate<Integer>()
{
    public boolean accept(Integer each)
    {
        return each < 3;
    }
};

Assert.assertEquals(selected, Iterate.select(jdkList, lessThan3));

Assert.assertEquals(selected, ecList.select(lessThan3));

Hier sind einige Alternativen zu Filtern JDK Listen und Eclipse-Sammlungen MutableLists die Prädikate Fabrik.

Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));

Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));

Hier ist eine Version, die nicht ein Objekt für das Prädikat nicht vor, doch durch die Predicates2 Fabrik statt mit der selectWith Methode, die ein Predicate2 nimmt.

Assert.assertEquals(
    selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));

Manchmal möchte man auf einem negativen Zustand filtern. Es ist eine spezielle Methode in Eclipse Kollektionen für das genannte reject.

Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));

Assert.assertEquals(rejected, ecList.reject(lessThan3));

Hier ist, wie Sie filtern können eine Java 8 Lambda als Predicate verwendet wird.

Assert.assertEquals(selected, Iterate.select(jdkList, each -> each < 3));
Assert.assertEquals(rejected, Iterate.reject(jdkList, each -> each < 3));

Assert.assertEquals(selected, gscList.select(each -> each < 3));
Assert.assertEquals(rejected, gscList.reject(each -> each < 3));

Die Methode partition werden zwei Sammlungen zurückkehren, um die Elemente ausgewählt von und abgelehnt von der Predicate enthält.

PartitionIterable<Integer> jdkPartitioned = Iterate.partition(jdkList, lessThan3);
Assert.assertEquals(selected, jdkPartitioned.getSelected());
Assert.assertEquals(rejected, jdkPartitioned.getRejected());

PartitionList<Integer> ecPartitioned = gscList.partition(lessThan3);
Assert.assertEquals(selected, ecPartitioned.getSelected());
Assert.assertEquals(rejected, ecPartitioned.getRejected());

. Hinweis: Ich bin ein Committer für Eclipse Sammlungen

Mit dem ForEach DSL können Sie schreiben

import static ch.akuhn.util.query.Query.select;
import static ch.akuhn.util.query.Query.$result;
import ch.akuhn.util.query.Select;

Collection<String> collection = ...

for (Select<String> each : select(collection)) {
    each.yield = each.value.length() > 3;
}

Collection<String> result = $result();

eine Sammlung von Gegeben [The, schnell, Braun, Fuchs, Sprünge, über, die, faul, Hund] ergibt sich [schnell, braun, springt über, faul], dh alle Saiten länger als drei Zeichen.

Alle Iteration Stile unterstützt durch die ForEach DSL sind

  • AllSatisfy
  • AnySatisfy
  • Collect
  • Counnt
  • CutPieces
  • Detect
  • GroupedBy
  • IndexOf
  • InjectInto
  • Reject
  • Select

Weitere Informationen finden Sie unter https: //www.iam.unibe .ch / SCG / svn_repos / Quellen / ForEach

Die Collections2.filter (Collection, Predicate) Verfahren in Google Guava Bibliothek tut genau das, was Sie suchen.

Da java 9 Collectors.filtering aktiviert ist:

public static <T, A, R>
    Collector<T, ?, R> filtering(Predicate<? super T> predicate,
                                 Collector<? super T, A, R> downstream)

So sollte Filterung sein:

collection.stream().collect(Collectors.filtering(predicate, collector))

Beispiel:

List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
            .collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));

Dies, zusammen mit dem Mangel an echten Schließungen kombiniert, ist mein größtes Problem für Java. Ehrlich gesagt, die meisten der oben genannten Methoden sind ziemlich leicht zu lesen und wirklich effizient; jedoch nach mit .Net, Erlang, etc viel Zeit ... Liste Verständnis in der Sprachebene integriert macht alles so viel sauberer. Ohne Zusätze auf der Sprachebene, Java kann nicht nur so sauber sein wie viele andere Sprachen in diesem Bereich.

Wenn die Leistung eine große Sorge ist, Google Sammlungen sind der Weg zu gehen (oder Ihr eigenes einfaches Prädikat Dienstprogramm schreiben). Lambdaj Syntax ist besser lesbar für einige Leute, aber es ist nicht ganz so effizient.

Und dann gibt es eine Bibliothek, die ich geschrieben habe. Ich werde alle Fragen in Bezug auf ihre Effizienz ignorieren (ja, sein so schlecht) ...... Ja, ich weiß, seine klar Reflexion basiert, und nein, ich eigentlich nicht verwenden, aber es funktioniert:

LinkedList<Person> list = ......
LinkedList<Person> filtered = 
           Query.from(list).where(Condition.ensure("age", Op.GTE, 21));

oder

LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");

http://code.google.com/p/jfilter/ ist am besten geeignet für Ihre Anforderung.

Jfilter ist eine einfache und leistungsstarke Open-Source-Bibliothek Sammlung von Java-Beans abzufragen.

Hauptmerkmale

  • Unterstützung der Sammlung (java.util.Collection, java.util.Map und Array) Eigenschaften.
  • Unterstützung der Sammlung in der Sammlung von beliebiger Tiefe.
  • Unterstützung von inneren Abfragen.
  • Unterstützung von parametrisierte Abfragen.
  • Kann filtern 1 Million Datensätze in wenigen 100 ms.
  • Filter (Abfrage) in einfachem JSON-Format gegeben ist, ist es wie Mangodb Abfragen. Im Folgenden sind einige Beispiele.
  • { "id": { "$ le": "10"}
    • , wo Objekt-ID-Eigenschaft ist kleiner als 10 entspricht.
  • { "id": { "$ in": [ "0", "100"]}}
    • , wo Objekt-ID-Eigenschaft 0 oder 100.
  • { "Lineitem": { "lineAmount": "1"}}
    • wo Lineitem Sammlung Eigenschaft parametrisierte Typs lineAmount hat gleich 1 ist.
  • { "$ und": [{ "id": "0"}, { "billingaddress": { "Stadt": "DEL"}}]}
    • wobei id Eigenschaft ist 0 und billingAddress.city Eigenschaft ist DEL.
  • { "Lineitem": { "Steuer": { "Schlüssel": { "Code": "GST"}, "Wert": { "$ gt": "1,01"}}}}
    • wo Lineitem Sammlung Eigenschaft parametrisierte Art, die Steuer Kartentyp Eigenschaft parameteriszed Art hat Code hat gleich zu GST-Wert größer als 1,01.
  • { '$ oder': [{ 'Code': '10'}, { 'skus': { '$ und': [{ 'Preis': { '$ in': [ '20', '40 ']}}, {' Code ':' REDAPPLE '}]}}]}
    • Alle Produkte auswählen, wo Produkt-Code 10 oder sku Preis in 20 und 40 und sku Code "REDAPPLE".

Ich schrieb eine erweiterte Iterable Klasse , die ohne das Kopieren der Sammlung Inhalt.

Verbrauch:

List<Integer> myList = new ArrayList<Integer>(){ 1, 2, 3, 4, 5 }

Iterable<Integer> filtered = Iterable.wrap(myList).select(new Predicate1<Integer>()
{
    public Boolean call(Integer n) throws FunctionalException
    {
        return n % 2 == 0;
    }
})

for( int n : filtered )
{
    System.out.println(n);
}

Der obige Code tatsächlich ausführen

for( int n : myList )
{
    if( n % 2 == 0 ) 
    {
        System.out.println(n);
    }
}

Verwenden Sie Sammlung Query Engine (CQEngine) . Es ist bei weitem der schnellste Weg, dies zu tun.

Siehe auch: Wie abfragen Sie Objektsammlungen in Java (Criteria / SQL-like)

Einige wirklich große tolle Antworten hier. Me, ich möchte die Dinge so einfach und lesbar wie möglich:

public abstract class AbstractFilter<T> {

    /**
     * Method that returns whether an item is to be included or not.
     * @param item an item from the given collection.
     * @return true if this item is to be included in the collection, false in case it has to be removed.
     */
    protected abstract boolean excludeItem(T item);

    public void filter(Collection<T> collection) {
        if (CollectionUtils.isNotEmpty(collection)) {
            Iterator<T> iterator = collection.iterator();
            while (iterator.hasNext()) {
                if (excludeItem(iterator.next())) {
                    iterator.remove();
                }
            }
        }
    }
}

Die einfache Pre-Java8 Lösung:

ArrayList<Item> filtered = new ArrayList<Item>(); 
for (Item item : items) if (condition(item)) filtered.add(item);

Leider ist diese Lösung nicht vollständig generisch, eine Liste eher als die Art der gegebenen Sammlung ausgibt. Auch in Bibliotheken oder Schreiben von Funktionen zu bringen, die diesen Code scheint übertrieben zu mir wickeln, wenn der Zustand komplex ist, aber dann können Sie eine Funktion für den Zustand schreiben.

https://code.google.com/p/joquery/

Unterstützt verschiedene Möglichkeiten,

Bei Sammlung,

Collection<Dto> testList = new ArrayList<>();

vom Typ

class Dto
{
    private int id;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getText()
    {
        return text;
    }
}

Filter

Java 7

Filter<Dto> query = CQ.<Dto>filter(testList)
    .where()
    .property("id").eq().value(1);
Collection<Dto> filtered = query.list();

Java 8

Filter<Dto> query = CQ.<Dto>filter(testList)
    .where()
    .property(Dto::getId)
    .eq().value(1);
Collection<Dto> filtered = query.list();

Auch

Filter<Dto> query = CQ.<Dto>filter()
        .from(testList)
        .where()
        .property(Dto::getId).between().value(1).value(2)
        .and()
        .property(Dto::grtText).in().value(new string[]{"a","b"});

Sortierung (auch für die Java 7)

Filter<Dto> query = CQ.<Dto>filter(testList)
        .orderBy()
        .property(Dto::getId)
        .property(Dto::getName)
    Collection<Dto> sorted = query.list();

Gruppierung (auch für die Java 7)

GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
        .group()
        .groupBy(Dto::getId)
    Collection<Grouping<Integer,Dto>> grouped = query.list();

Verbindet (auch für die Java 7)

In Anbetracht

class LeftDto
{
    private int id;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getText()
    {
        return text;
    }
}

class RightDto
{
    private int id;
    private int leftId;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getLeftId()
        {
            return leftId;
        }

    public int getText()
    {
        return text;
    }
}

class JoinedDto
{
    private int leftId;
    private int rightId;
    private String text;

    public JoinedDto(int leftId,int rightId,String text)
    {
        this.leftId = leftId;
        this.rightId = rightId;
        this.text = text;
    }

    public int getLeftId()
    {
        return leftId;
    }

    public int getRightId()
        {
            return rightId;
        }

    public int getText()
    {
        return text;
    }
}

Collection<LeftDto> leftList = new ArrayList<>();

Collection<RightDto> rightList = new ArrayList<>();

Kann wie verbunden werden,

Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
                .<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
                .on(LeftFyo::getId, RightDto::getLeftId)
                .transformDirect(selection ->  new JoinedDto(selection.getLeft().getText()
                                                     , selection.getLeft().getId()
                                                     , selection.getRight().getId())
                                 )
                .list();

Ausdrücke

Filter<Dto> query = CQ.<Dto>filter()
    .from(testList)
    .where()
    .exec(s -> s.getId() + 1).eq().value(2);

Meine Antwort auf dem von Kevin Wong baut, hier als Einzeiler mit CollectionUtils von Frühling und eine Java 8 Lambda Ausdruck.

CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);

Das ist so präzise und gut lesbar wie jede Alternative I (ohne Aspekt-basierten Bibliotheken) gesehen habe

Frühling CollectionUtils ab Frühjahr Version 4.0.2.RELEASE verfügbar ist, und denken Sie daran müssen Sie JDK 1.8 und Sprachniveau 8 +.

java 8 Verwendung, insbesondere lambda expression, können Sie es tun einfach wie das folgende Beispiel:

myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())

Dabei steht für jeden product innerhalb myProducts Sammlung, wenn prod.price>10, dann hinzufügen, um dieses Produkt in die neuen gefilterte Liste.

Ich brauchte eine Liste zu filtern, je nach den Werten bereits in der Liste. Entfernen Sie beispielsweise alle Werte folgt, ist kleiner als der aktuelle Wert. {2 5 3 5 7 4} -> {2 5 7}. Oder zum Beispiel alle Duplikate entfernen {3 5 4 2 3 5 6} -.> {3 5 4 2 6}

public class Filter {
    public static <T> void List(List<T> list, Chooser<T> chooser) {
        List<Integer> toBeRemoved = new ArrayList<>();
        leftloop:
        for (int right = 1; right < list.size(); ++right) {
            for (int left = 0; left < right; ++left) {
                if (toBeRemoved.contains(left)) {
                    continue;
                }
                Keep keep = chooser.choose(list.get(left), list.get(right));
                switch (keep) {
                    case LEFT:
                        toBeRemoved.add(right);
                        continue leftloop;
                    case RIGHT:
                        toBeRemoved.add(left);
                        break;
                    case NONE:
                        toBeRemoved.add(left);
                        toBeRemoved.add(right);
                        continue leftloop;
                }
            }
        }

        Collections.sort(toBeRemoved, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        for (int i : toBeRemoved) {
            if (i >= 0 && i < list.size()) {
                list.remove(i);
            }
        }
    }

    public static <T> void List(List<T> list, Keeper<T> keeper) {
        Iterator<T> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (!keeper.keep(iterator.next())) {
                iterator.remove();
            }
        }
    }

    public interface Keeper<E> {
        boolean keep(E obj);
    }

    public interface Chooser<E> {
        Keep choose(E left, E right);
    }

    public enum Keep {
        LEFT, RIGHT, BOTH, NONE;
    }
}

wird Biene Dieser so benutzt.

List<String> names = new ArrayList<>();
names.add("Anders");
names.add("Stefan");
names.add("Anders");
Filter.List(names, new Filter.Chooser<String>() {
    @Override
    public Filter.Keep choose(String left, String right) {
        return left.equals(right) ? Filter.Keep.LEFT : Filter.Keep.BOTH;
    }
});

Mit Guava:

Collection<Integer> collection = Lists.newArrayList(1, 2, 3, 4, 5);

Iterators.removeIf(collection.iterator(), new Predicate<Integer>() {
    @Override
    public boolean apply(Integer i) {
        return i % 2 == 0;
    }
});

System.out.println(collection); // Prints 1, 3, 5

In Java 8, Sie können direkt auf diese Filtermethode verwenden und dann das tun.

 List<String> lines = Arrays.asList("java", "pramod", "example");

 List<String> result = lines.stream()              
         .filter(line -> !"pramod".equals(line))     
         .collect(Collectors.toList());              

 result.forEach(System.out::println); 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top