문제

내가 원하는 필터링 java.util.Collection 에 기반하는 조건이 있습니다.

도움이 되었습니까?

해결책

Java 8 (2014) 한 줄의 코드로 스트림과 람다를 사용 하여이 문제를 해결합니다.

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

여기에 있습니다 지도 시간.

사용 Collection#removeIf 컬렉션을 제자리에 수정합니다. (통지 :이 경우 술어는 술어를 만족시키는 물체를 제거합니다) :

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

람다 즈 루프 나 내부 클래스를 쓰지 않고 필터링 컬렉션이 허용됩니다.

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

더 읽기 쉬운 것을 상상할 수 있습니까?

부인 성명: 나는 Lambdaj의 기고자입니다

다른 팁

당신이 사용하고 있다고 가정합니다 Java 1.5, 그리고 당신은 추가 할 수 없습니다 Google 컬렉션, 나는 Google Guys가 한 것과 매우 비슷한 일을 할 것입니다. 이것은 Jon의 의견에 약간의 변화입니다.

먼저이 인터페이스를 코드베이스에 추가하십시오.

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

구현자는 특정 유형이 특정 유형에 맞을 때 대답 할 수 있습니다. 예를 들어 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);

선형 점검의 성능이 우려되는 경우 대상 컬렉션이있는 도메인 객체를 갖고 싶을 수도 있습니다. 대상 컬렉션이있는 도메인 객체에는 대상 컬렉션을 초기화, 추가 및 설정하는 메소드에 대한 로직을 필터링합니다.

업데이트:

유틸리티 클래스 (술어로 말하면)에서는 술어가 예상 값을 반환하지 않을 때 기본값 옵션 옵션이있는 선택 메소드를 추가했으며 새로운 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 릴리스 후) :

내가이 답을 처음 게시 한 지 몇 년이 지났지 만 여전히이 답변에 대한 포인트를 수집하고 있다고 믿을 수는 없습니다. 여하튼, Java 8은 언어에 대한 폐쇄를 도입 했으므로 이제 내 대답은 상당히 다르고 간단 할 것입니다. Java 8의 경우 고유 한 정적 유틸리티 클래스가 필요하지 않습니다. 따라서 술어와 일치하는 첫 번째 요소를 찾으려면.

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

옵션의 JDK 8 API는 get(), isPresent(), orElse(defaultUser), orElseGet(userSupplier) 그리고 orElseThrow(exceptionSupplier), 그리고 다른 'monadic'함수 : 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());

보다 여기 Java 8 스트림 작동 방식에 대한 더 많은 예를 보려면.

사용 CollectionUtils.Filter (수집, 술어), Apache Commons에서.

"최상의 방법"너무 넓습니다.그것은"가장 짧은"?"빠른"?"읽을 수 있는"?필터 장소에서 또는 다른 컬렉션으로?

가장 간단한(하지만 가장 읽을 수)방법을 반복하고 사용하여 반복기입니다.제거()메소드:

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()반복하여 수집 및 전화를 조건이 있습니다.이전()을 배우는 경우 인스턴스에 보관되어야의 컬렉션입니다.

나는 정말 보이지 않는 합리화하는 데에서 타사 라이브러리에 대한 이 작업입니다.

고려 Google 컬렉션 한 업데이트 컬렉션을 지원하는 프레임 워크 제네릭입니다.

업데이트:Google 컬렉션 라이브러리는 이제 사용되지 않습니다.당신이 사용해야 의 최신 릴리스 구아바 대신 합니다.그것은 여전히 모든 동 확장 컬렉션은 프레임 워크를 포함한 메커니즘에 대한 필터링 기반으로는 조건이 있습니다.

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

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

평범하고 끔찍한 자바는 어떻습니까?

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

단순하고 읽기 쉽고 쉽게 (그리고 Android에서 작동합니다!) Java 8을 사용하는 경우 달콤한 한 줄로 수행 할 수 있습니다.

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

Tolist ()는 정적으로 가져옵니다

반복자가 아닌 컬렉션 자체를 필터링하고 싶습니까?

보다 org.apache.commons.collections.iterators.filteriterator

또는 Apache Commons의 버전 4를 사용합니다 org.apache.commons.collections.iterators.filteriterator

내장 JDK 목록을 필터링하는 방법을 살펴 보겠습니다. MutableList 사용 일식 컬렉션 (전에 GS 컬렉션).

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 목록을 필터링하는 몇 가지 대안입니다 일식 컬렉션 The를 사용하는 Mutablelists 일치합니다 공장.

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

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

다음은 술어에 대한 객체를 할당하지 않는 버전입니다. predicates2 대신 공장 selectWith a Predicate2.

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

때로는 부정적인 상태로 필터링하고 싶을 때가 있습니다. 이클립스 컬렉션에는 특별한 방법이 있습니다. reject.

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

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

Java 8 Lambda를 사용하여 필터링하는 방법은 다음과 같습니다. 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());

참고 : 나는 Eclipse 컬렉션을위한 커피터입니다.

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

The, Quick, Brown, Fox, Jump, Over, Lazy, Dog]의 모음을 감안할 때 [빠른, 갈색, 점프, 오버, 게으른], 즉 모든 문자열이 세 문자보다 길다.

Foreach DSL이 지원하는 모든 반복 스타일은 다음과 같습니다

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

자세한 내용은 참조하십시오 https://www.iam.unibe.ch/scg/svn_repos/sources/foreach

그만큼 collections2.filter (수집, 술어) 방법 Google의 Guava 라이브러리 당신이 찾고있는 일을합니다.

부터 Java 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()));

이것은 실제 폐쇄 부족과 결합 된 Java에게 가장 큰 그립입니다. 솔직히, 위에서 언급 한 대부분의 방법은 읽기 쉽고 실제로 효율적입니다. 그러나 .NET, Erlang 등으로 시간을 보내면 언어 수준에 통합 된 목록 이해력은 모든 것을 훨씬 더 깨끗하게 만듭니다. 언어 수준에 추가되지 않으면 Java는이 영역의 다른 많은 언어만큼 깨끗하지 않습니다.

성능이 큰 관심사 인 경우 Google 컬렉션은 갈 수있는 방법입니다 (또는 간단한 술어 유틸리티를 작성하십시오). Lambdaj Syntax는 일부 사람들에게는 더 읽기 쉽지만 효율적이지는 않습니다.

그리고 내가 쓴 도서관이 있습니다. 나는 그 효율성에 관한 질문을 무시할 것입니다 (예, 그 나쁜 것) ... 예, 나는 그것의 명확하게 반영 기반을 알고 있습니다. 그리고 실제로 그것을 사용하지는 않지만 작동합니다.

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의 쿼리를위한 간단하고 고성능 오픈 소스 라이브러리입니다.

주요 특징들

  • 수집 지원 (java.util.collection, java.util.map 및 배열) 속성.
  • 모든 깊이의 컬렉션 내부의 수집 지원.
  • 내부 쿼리 지원.
  • 매개 변수화 쿼리 지원.
  • 100ms 안에 1 백만 레코드를 필터링 할 수 있습니다.
  • 필터 (쿼리)는 간단한 JSON 형식으로 제공되며 MangoDB 쿼리와 같습니다. 다음은 몇 가지 예입니다.
  • { "id": { "$ le": "10"}
    • 여기서 객체 ID 속성이 10보다 적습니다.
  • { "id": { "$ in": [ "0", "100"}}
    • 여기서 객체 ID 속성은 0 또는 100입니다.
  • { "lineitems": { "Lineamount": "1"}}
    • 여기서 매개 변수화 된 유형의 LineItems 수집 속성은 Lineamount가 1과 동일합니다.
  • { "$ and": [{ "id": "0"}, { "BillingAddress": { "city": "del"}}]}
    • 여기서 ID 속성은 0이고 BillingAddress.city 속성은 del입니다.
  • { "lineitems": { "taxes": { "key": { "code": "gst"}, "value": { "$ gt": "1.01"}}}}
    • 여기서 세금이있는 매개 변수화 유형의 lineitems 수집 속성 매개 변수 유형의 속성은 코드가 1.01보다 큰 gst 값과 같습니다.
  • { '$ 또는': [{ 'code': '10'}, { 'skus': { '$ and': [{ 'price': { '$ in': [ '20', '40']} }, { 'code': 'redapple'}]}}}}
    • 제품 코드가 10 또는 Sku 가격이 20과 40에서 Sku Code가 "RedApple"인 모든 제품을 선택하십시오.

나는 썼다 확장 된 반복 클래스 이는 컬렉션 컨텐츠를 복사하지 않고 기능적 알고리즘 적용을 지원합니다.

용법:

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). 이 작업을 수행하는 가장 빠른 방법입니다.

또한보십시오: Java (Criteria/SQL-Like)에서 객체 수집을 어떻게 쿼리합니까?

여기에 정말 멋진 대답이 있습니다. 나, 나는 가능한 한 간단하고 읽을 수있게하고 싶다 :

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

필터

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

또한,

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

정렬 (Java 7에서도 이용 가능)

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

그룹화 (Java 7에서도 이용 가능)

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

가입 (Java 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);

내 대답은 Kevin Wong의 그에 대한 대답을 바탕으로 여기에서 1 라이너를 사용합니다. CollectionUtils ~에서 그리고 Java 8 람다 표현.

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

이것은 내가 본 대안만큼 간결하고 읽을 수 있습니다 (측면 기반 라이브러리를 사용하지 않고)

CollectionUtils Spring Version 4.0.2에서 구할 수 있으며 Release는 JDK 1.8 및 Language Level 8+가 필요하다는 것을 기억하십시오.

사용 java 8, 구체적으로 lambda expression, 당신은 단순히 아래 예처럼 할 수 있습니다.

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

각각 어디에 product 내부에 myProducts 컬렉션, if 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;
    }
});

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

Java 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