سؤال

أريد أن تصفية java.util.Collection بناء على المسند.

هل كانت مفيدة؟

المحلول

جافا 8 (2014) يحل هذه المشكلة باستخدام تيارات lambdas في سطر واحد من التعليمات البرمجية:

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

هنا البرنامج التعليمي.

استخدام Collection#removeIf تعديل جمع في المكان.(لاحظ:في هذه الحالة, المسند إزالة الكائنات من تلبية المسند):

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

lambdaj يسمح تصفية مجموعات دون كتابة الحلقات أو الطبقات الداخلية:

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

يمكنك أن تتخيل شيئا أكثر قابلية للقراءة ؟

تنويه: أنا مساهم في lambdaj

نصائح أخرى

على افتراض أن كنت تستخدم جافا 1.5, و أنه لا يمكن إضافة مجموعات جوجل, وأود أن تفعل شيئا تشبه جوجل الرجال.هذا هو اختلاف طفيف على جون تعليقات.

الأولى إضافة هذه الواجهة إلى تعليمات البرمجة الأساسية.

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

لها والمنفذين يمكن الإجابة عندما معين المسند صحيح من نوع معين.E. g.إذا T كانت User و AuthorizedUserPredicate<User> تنفذ IPredicate<T>, ثم AuthorizedUserPredicate#apply إرجاع ما إذا كانت مرت في User هو المصرح به.

ثم في بعض المرافق الدرجة, هل يمكن أن نقول

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

حتى على افتراض أن لديك استخدام المذكورة أعلاه قد يكون

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

إذا كان الأداء على الخطية التحقق من القلق ، ثم قد تريد أن يكون لها المجال كائن له هدف المجموعة.كائن المجال الذي يحتوي على الهدف جمع قد منطق تصفية على أساليب تهيئة إضافة تعيين المجموعة المستهدفة.

تحديث:

في الأداة المساعدة فئة (دعنا نقول المسند), واضاف لقد حدد الأسلوب مع خيار القيمة الافتراضية عند المسند لا عودة القيمة المتوقعة, و أيضا خاصية ثابتة على params لاستخدامها داخل جديد IPredicate.

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

المثال التالي يبحث عن الأشياء المفقودة بين مجموعات:

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

المثال التالي يبحث عن مثيل في مجموعة, ويعود العنصر الأول من جمع القيمة الافتراضية عندما سبيل المثال لم يتم العثور على:

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

التحديث (بعد Java 8 الإصدار):

مرت عدة سنوات منذ أن (آلان) نشر أول هذا الجواب ، وأنا ما زلت لا أستطيع أن أصدق أنا جمع حتى نقاط عن هذه الإجابة.على أية حال الآن جافا 8 أدخلت الإغلاق إلى اللغة جوابي الآن بشكل مختلف و أكثر بساطة.مع جافا 8 ، هناك حاجة واضحة ثابتة فئة فائدة.حتى إذا كنت ترغب في العثور على 1 عنصر يطابق المسند.

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

جدك 8 API اخليارات لديه القدرة على get(), isPresent(), orElse(defaultUser), orElseGet(userSupplier) و orElseThrow(exceptionSupplier), فضلا عن غيرها من 'بعملية' وظائف مثل map, flatMap و filter.

إذا كنت تريد ببساطة جمع جميع المستخدمين في أي مباراة المسند ، ثم استخدام Collectors لإنهاء تيار في المطلوب جمع.

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

انظر هنا لمزيد من الأمثلة على كيفية جافا 8 تيارات العمل.

استخدام CollectionUtils.تصفية(جمع المسند), من أباتشي العموم.

"أفضل" طريقة واسعة جدا طلب.هو "أقصر"?"أسرع"?"للقراءة"?مرشح في مكان أو في آخر جمع ؟

أبسط (ولكن ليس أكثر قابلية للقراءة) طريقة تكرار استخدام التكرار.طريقة إزالة ():

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

الآن لجعله أكثر قابلية للقراءة ، يمكنك التفاف إلى أداة الأسلوب.ثم يخترع IPredicate واجهة إنشاء مجهول تنفيذ واجهة تفعل شيئا مثل:

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

حيث filterInPlace() تكرار جمع المكالمات المسند.الممتنع عن المكسرات() لمعرفة إذا كان سبيل المثال أن يوضع في المجموعة.

لا أرى مبررا في جلب طرف ثالث المكتبة فقط لهذه المهمة.

النظر في مجموعات جوجل من أجل تحديث مجموعات إطار يدعم الأدوية.

التحديث:جوجل مجموعات المكتبة الآن إهمال.يجب عليك استخدام أحدث إصدار من الجوافة بدلا من ذلك.فإنه لا يزال لديه كل نفس امتداد إلى مجموعات الإطار بما في ذلك آلية الترشيح بناء على المسند.

انتظر جافا 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());

منذ الإفراج المبكر عن جافا 8 ، قد تتمكن من محاولة شيء من هذا القبيل:

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

على سبيل المثال, إذا كان لديك قائمة من الأعداد الصحيحة و أردت تصفية الأرقام > 10 ثم طباعة هذه الأرقام إلى وحدة التحكم, هل يمكن أن تفعل شيئا مثل:

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

أنا رمي RxJava في الحلقة التي تتوفر أيضا على الروبوت.RxJava قد لا يكون دائما هو الخيار الأفضل, ولكن سوف تعطيك المزيد من المرونة إذا كنت ترغب في إضافة المزيد من التحولات في جمع الخاصة بك أو التعامل مع أخطاء أثناء التصفية.

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

الإخراج:

1
3
5

المزيد من التفاصيل على RxJava هو filter يمكن العثور على هنا.

الإعداد:

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

الاستخدام:

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

كيف حول بعض عادي و straighforward جافا

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

بسيطة للقراءة و سهل (ويعمل في الروبوت!) ولكن إذا كنت تستخدم جافا 8 يمكنك أن تفعل ذلك في الحلو سطر واحد:

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

علما بأن toList() هو ثابت المستوردة

هل أنت متأكد من أنك تريد تصفية المجموعة نفسها, بدلا من التكرار?

انظر org.أباتشي.المشاع.مجموعات.التكرار.FilterIterator

أو باستخدام الإصدار 4 من طراز أباتشي العموم org.أباتشي.المشاع.collections4.التكرار.FilterIterator

دعونا ننظر في كيفية تصفية المدمج في JDK قائمة MutableList باستخدام الكسوف مجموعات (سابقا ع مجموعات).

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

إذا كنت تريد تصفية الأرقام أقل من 3 ، كنت تتوقع النتائج التالية.

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

هنا هو كيف يمكنك تصفية باستخدام مجهول الطبقة الداخلية كما Predicate.

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

وهنا بعض البدائل تصفية JDK قوائم الكسوف مجموعات MutableLists باستخدام المسندات مصنع.

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

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

هنا هو الإصدار الذي لا تخصيص كائن على المسند ، باستخدام Predicates2 مصنع بدلا من ذلك مع selectWith الأسلوب الذي يأخذ Predicate2.

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

في بعض الأحيان كنت تريد تصفية على حالة سلبية.هناك طريقة خاصة في الكسوف المجموعات التي تسمى reject.

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

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

هنا هو كيف يمكنك تصفية باستخدام جافا 8 امدا كما Predicate.

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

طريقة partition عودة اثنين من المجموعات التي تحتوي على العناصر المختارة من قبل ورفض من قبل Predicate.

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

ملاحظة:أنا committer عن الكسوف مجموعات.

مع ForEach DSL قد تكتب

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

بالنظر إلى مجموعة من [, سريع, البني, فوكس, يقفز, أكثر،, كسول, الكلب] هذه النتائج في [السريع, البني, يقفز, على, كسول] ، أي جميع سلاسل أطول من ثلاثة أحرف.

كل التكرار من الأساليب المعتمدة من قبل ForEach DSL

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

للحصول على مزيد من التفاصيل ، يرجى الرجوع إلى https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach

على Collections2.تصفية(جمع المسند) طريقة جوجل الجوافة المكتبة لا مجرد ما كنت أبحث عنه.

منذ جافا 9 Collectors.filtering تمكين:

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

وبالتالي تصفية يجب أن تكون:

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

على سبيل المثال:

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

هذا جنبا إلى جنب مع عدم وجود حقيقي الإغلاق هو وجع أكبر بلدي جافا.بصراحة معظم الأساليب المذكورة أعلاه هي من السهل جدا لقراءة حقا كفاءة ؛ ومع ذلك ، بعد قضاء بعض الوقت مع .صافي ، إرلانج ، الخ...قائمة على الفهم المتكامل على مستوى اللغة يجعل كل شيء أنظف بكثير.دون إضافات على مستوى اللغة ، جافا فقط لا يمكن أن يكون نظيفا كما العديد من اللغات الأخرى في هذا المجال.

إذا كان الأداء هو مصدر قلق كبير, مجموعات Google هو الطريق للذهاب (أو الكتابة الخاصة بك بسيطة المسند المنفعة).Lambdaj الجملة هو أكثر قابلية للقراءة لبعض الناس, ولكن ليس تماما فعالة.

ثم هناك مكتبة كتبت.سوف أتجاهل أي أسئلة فيما يتعلق الكفاءة (نعم ، هذا سيء)......نعم, أنا أعرف بوضوح انعكاس على أساس ، أي لا تستخدم في الواقع ، ولكن عمل ذلك:

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

أو

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

JFilter http://code.google.com/p/jfilter/ هو الانسب بالنسبة للشرط الخاص بك.

JFilter بسيطة و عالية الأداء مكتبة مفتوحة المصدر الاستعلام عن مجموعة من Java beans.

الميزات الرئيسية

  • دعم جمع (جافا.util.جمع جافا.util.خريطة مجموعة) خصائص.
  • دعم مجموعة داخل مجموعة من أي عمق.
  • الدعم الداخلي الاستعلامات.
  • دعم استعلامات بمعلمات.
  • يمكن تصفية 1 مليون السجلات في قليل من 100 مللي ثانية.
  • تصفية ( الاستعلام) في البسيطة تنسيق json, هو مثل Mangodb الاستعلامات.وفيما يلي بعض الأمثلة.
  • { "id":{"$لو":"10"}
    • حيث معرف الكائن العقار أقل من أو يساوي 10.
  • { "id":{"$في":["0", "100"]}}
    • حيث كائن معرف الخاصية هي 0 أو 100.
  • {"lineItems":{"lineAmount":"1"}}
    • حيث lineItems جمع العقار من معلمات نوع lineAmount يساوي 1.
  • { "$و":[{"id":"0"}, {"billingAddress":{"المدينة":"ديل"}}]}
    • حيث معرف الخاصية هي 0 و billingAddress.المدينة الملكية ديل.
  • {"lineItems":{"الضرائب":{ "مفتاح":{"كود":"GST"}, "value":{"$gt":"1.01"}}}}
    • حيث lineItems جمع العقار من معلمات النوع الذي الضرائب خريطة نوع العقار من parameteriszed نوع رمز يساوي GST قيمة أكبر من 1.01.
  • {'$أو':[{'رمز':'10'},{'sku':{'$و':[{'السعر':{'$في':['20', '40']}}, {'رمز':'RedApple'}]}}]}
    • حدد جميع المنتجات حيث رمز المنتج هو 10 أو الكود سعر في 20 و 40 و الكود كود "RedApple".

كتبت ممتدة Iterable الدرجة التي تدعم تطبيق الفنية الخوارزميات دون نسخ جمع المحتوى.

الاستخدام:

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

رمز أعلاه سوف فعلا تنفيذ

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

استخدام جمع الاستعلام المحرك (CQEngine).هذا هو إلى حد بعيد أسرع طريقة للقيام بذلك.

انظر أيضا: كيف يمكنك الاستعلام كائن مجموعات في جافا (المعايير/SQL-مثل)?

رائعة رائعة الإجابات هنا.لي, أود أن تبقي يخفف بسيطة للقراءة قدر الإمكان:

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

بسيطة قبل Java8 الحل:

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

للأسف هذا الحل غير صحيح تماما عامة ، إخراج قائمة بدلا من نوع معين جمع.أيضا ، ليصل في المكتبات أو كتابة الوظائف التي التفاف التعليمات البرمجية هذا يبدو مبالغة لي ما لم يكن الشرط هو معقد ، ولكن بعد ذلك يمكنك كتابة دالة على الشرط.

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

يدعم مختلف الاحتمالات ،

وبالنظر إلى جمع ،

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

من نوع ،

class Dto
{
    private int id;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getText()
    {
        return text;
    }
}

فلتر

جافا 7

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

جافا 8

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

أيضا ،

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

الفرز (أيضا متاح على جافا 7)

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

تجمع (أيضا متاح على جافا 7)

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

ينضم (أيضا متاح على جافا 7)

معين ،

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

يمكن انضم مثل ،

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

التعبيرات

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

جوابي يبني على أنه من كيفن وونغ ، هنا بطانة واحدة باستخدام CollectionUtils من الربيع و Java 8 امدا التعبير.

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

هذا هو الموجز و مقروء مثل أي بديل رأيت (دون استخدام الجانب القائم على المكتبات)

الربيع CollectionUtils متاح من الربيع الإصدار 4.0.2.الإصدار ، و تذكر أنك تحتاج جدك 1.8 و مستوى اللغة 8+.

باستخدام java 8, تحديدا lambda expression, يمكنك أن تفعل ذلك ببساطة مثل المثال التالي:

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

حيث لكل product داخل myProducts جمع إذا prod.price>10, ثم إضافة هذا المنتج الجديد تصفية قائمة.

أنا في حاجة إلى مرشح قائمة اعتمادا على القيم الموجودة بالفعل في القائمة.على سبيل المثال إزالة جميع القيم التالية التي هي أقل من القيمة الحالية.{2 5 3 4 7 5} -> {2 5 7}.أو على سبيل المثال إزالة جميع التكرارات {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;
    }
}

هذا النحل تستخدم مثل هذا.

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

مع الجوافة:

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

في جافا 8, يمكنك مباشرة استخدام عامل التصفية هذا الأسلوب ومن ثم القيام بذلك.

 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); 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top