Java Collection( 술어 기반)을 필터링하는 방법?
a를 필터링하고 싶다.java.util.Collection
술어에 근거하여
Java 8(2014년)은 스트림과 람다(Lambdas)를 사용하여 이 문제를 해결한다.
List<Person> beerDrinkers = persons.stream()
.filter(p -> p.getAge() > 16).collect(Collectors.toList());
여기 튜토리얼이 있다.
제자리에 있는 컬렉션을 수정하는 데 사용한다.(알림:이 경우 술어는 술어를 만족시키는 개체를 제거한다.
persons.removeIf(p -> p.getAge() <= 16);
루프나 내부 클래스를 작성하지 않고 수집을 필터링할 수 있는 람다지:
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
greaterThan(16)));
좀 더 읽기 쉬운 것을 상상할 수 있는가?
고지 사항:나는 람다지에 기고한다.
만약 당신이 자바 1.5를 사용하고 있고 구글 컬렉션을 추가할 수 없다고 가정한다면, 나는 구글 사람들이 했던 것과 매우 유사한 것을 할 것이다.이것은 존의 논평에 약간 다른 것이다.
먼저 이 인터페이스를 코드베이스에 추가하십시오.
public interface IPredicate<T> { boolean apply(T type); }
그것의 시행자들은 특정 술어가 특정 유형에 진실일 때 대답할 수 있다.예: ifT
이었다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));
UPDATE(Java 8 릴리스 이후):
나(앨런)가 처음 이 답을 올린 지 몇 년이 지났는데, 아직도 이 답에 대해 SO 포인트를 모으고 있다는 게 믿기지 않는다.어쨌든, 자바 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();
8는 JDK 8 API for Optionals가 DDAQ 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());
Java 8 스트림이 작동하는 방식에 대한 자세한 예는 여기를 참조하십시오.
Apache Commons의 CollectionUtils.filter(Collection,Predicate)를 사용하십시오.
"최상의" 방법은 너무 광범위한 요청이다."가장 짧다"?"가장 빠르다고?""읽을 수 있는"?제자리에 필터링하시겠습니까, 아니면 다른 컬렉션에 필터링하시겠습니까?
가장 간단하지만 가장 읽기 쉬운 방법은 반복하고 Iterator.remove() 방법을 사용하는 것이다.
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() 컬렉션을 반복하고 술어를 호출한다.keepIt()를 사용하여 수집할 인스턴스를 보관할지 여부를 확인하십시오.
나는 이 일을 위해서만 제3자 도서관을 들여올 명분이 없다고 본다.
제네릭을 지원하는 업데이트된 컬렉션 프레임워크의 경우 Google 컬렉션을 고려하십시오.
UPDATE: 구글 컬렉션 라이브러리는 이제 더 이상 사용되지 않는다.대신 최신판 구아바를 사용해야 한다.그것은 술어에 기초한 필터링 메커니즘을 포함하여 여전히 수집 프레임워크에 대한 모든 동일한 확장자를 가지고 있다.
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());
자바 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();
}
});
평범하고 직선적인 Java는 어때?
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.properties.reason.iterators를 참조하십시오.필터이터레이터
또는 apache commons organ.properties.properties4.iterators 버전 4를 사용할 수 있다.필터이터레이터
Eclipse Collections를 사용하여 내장 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);
Java 8 람다를 사용하여 필터링할 수 있는 방법은 다음과 같다.Predicate
.
Assert.assertEquals(selected, Iterate.select(jdkList, each -> each < 3));
Assert.assertEquals(rejected, Iterate.reject(jdkList, each -> each < 3));
Assert.assertEquals(selected, ecList.select(each -> each < 3));
Assert.assertEquals(rejected, ecList.reject(each -> each < 3));
익명의 내부 클래스를 사용하여 필터링할 수 있는 방법은 다음과 같다.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 목록과 Eclipse Collections MutableLists를 필터링하는 몇 가지 대안이다.
Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));
Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));
다음은 술어 대신 술어2 팩토리를 사용하여 술어에 개체를 할당하지 않는 버전이다.selectWith
를 필요로 하는 방법Predicate2
.
Assert.assertEquals(
selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));
때로는 부정적인 조건으로 필터링하고 싶을 때도 있다.에는 Eclipse Collections라는 .reject
.
Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));
Assert.assertEquals(rejected, ecList.reject(lessThan3));
방법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 Collections의 커밋자입니다.
자바 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()));
ForAweet 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();
[빠른, 빠른, 갈색, 여우, 점프, 오버, 게으른, 개]의 모음으로 볼 때, 이것은 [빠른, 갈색, 점프, 오버, 게으름] 즉 모든 현이 세 글자 이상 길어지는 결과를 낳는다.
ForAweet DSL에서 지원하는 모든 반복 스타일은
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
자세한 내용은 https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach을 참조하십시오.
컬렉션2.구글의 구아바 라이브러리에 있는 필터(수집,Predicate) 방법은 당신이 원하는 대로 한다.
이것은 실제 폐쇄의 부족과 결합되어 자바에 대한 나의 가장 큰 불만이다.솔직히, 위에 언급된 대부분의 방법은 읽기 쉽고 정말로 효율적이다. 그러나 와 함께 시간을 보낸 후에.네트, 얼랑 등...언어 수준에 통합된 목록 이해는 모든 것을 훨씬 더 깨끗하게 만든다.언어 수준에서 추가가 없다면, 자바어는 이 영역의 다른 많은 언어만큼 깨끗할 수 없다.
성능이 큰 문제라면 구글 컬렉션은 (또는 당신만의 간단한 술어 유틸리티를 쓰는) 방법이다.어떤 사람들에게는 람다즈 구문이 더 읽기 쉽지만, 그것은 그다지 효율적이지 않다.
그리고 내가 쓴 도서관이 있다.그 효율성에 관한 어떤 질문도 무시하겠다(예, 그렇게 나쁘다니)......그래, 나는 그것의 명확한 반사를 알고 있어. 그리고 나는 실제로 그것을 사용하지 않지만, 그것은 효과가 있다.
LinkedList<Person> list = ......
LinkedList<Person> filtered =
Query.from(list).where(Condition.ensure("age", Op.GTE, 21));
OR
LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");
자바 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);
JFilter http://code.google.com/p/jfilter/은 당신의 요구에 가장 적합하다.
JFilter는 Java 콩 컬렉션을 쿼리할 수 있는 간단하고 고성능 오픈 소스 라이브러리 입니다.
주요 기능
- 수집 지원(java.util).컬렉션, java.util.맵 및 배열) 속성.
- 심층 컬렉션 내부 컬렉션 지원.
- 내부 쿼리 지원.
- 매개 변수화된 쿼리 지원.
- 100만 개의 레코드를 100ms 이내에 필터링할 수 있음
- 필터(쿼리)는 간단한 json 형식으로 주어지는데, 이는 망고드브 쿼리와 같다.다음은 몇 가지 예다.
- { "id" 0"$le:"10"}
- 여기서 개체 ID 속성이 10보다 작다.
- { "id": {"$in":["0", "100"]}}
- 여기서 개체 ID 속성은 0 또는 100이다.
- {"lineItems":{"라인 금액":"1"}}
- 여기서 매개 변수화된 유형의 lineItems 수집 속성은 lineAmount가 1과 같다.
- ~ "$and":":[{"id": "0", {"billingAddress":{"city":"DEL"}]}
- 여기서 ID 속성은 0이고 billingAddress.city 속성은 DEL이다.
- {"lineItems":{"미션", "키":{"code":"GST", "value":{"$gt": "1.01"}
- 여기서 parameterised type의 세금 맵 유형 특성을 가진 매개변수 유형의 lineItems 수집 속성은 1.01보다 큰 GST 값과 코드가 같다.
- {'$or':[{'code':'10'},{'skus': {'$and':[{'price':{'$in':['20', '40'], {'code':'RedApple'}}}}}
- 제품 코드가 10 또는 20 및 40의 sku 가격, sku 코드가 "RedApple"인 제품을 모두 선택하십시오.
컬렉션 콘텐츠를 복사하지 않고 기능 알고리즘 적용을 지원하는 확장 Iturable 클래스를 작성했다.
사용량:
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에서 객체 컬렉션을 쿼리하는 방법(크라이테리아/SQL 유사)
사용.java 8
, 구체적으로lambda expression
, 아래의 예처럼 간단히 할 수 있다.
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
각각 어디에product
안쪽에myProducts
의 경우, 수집prod.price>10
, 그런 다음 이 제품을 새 필터링된 목록에 추가하십시오.
여기 정말 훌륭한 해답들이 있어.나는 가능한 한 간단하고 읽기 쉽게 유지하고 싶다.
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"});
정렬(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);
내 대답은 케빈 웡으로부터 얻어지는 것으로, 여기 한 라이너로서,CollectionUtils
봄부터 자바 8 람다 표현까지.
CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);
이것은 내가 본 다른 대안들만큼 간결하고 읽기 쉽다 (양면 기반 라이브러리를 사용하지 않고)
Spring CollectionUtils는 봄 버전 4.0.2에서 이용할 수 있다.릴리즈, 그리고 당신은 JDK 1.8과 언어 레벨 8 이상이 필요하다는 것을 기억하십시오.
나는 리스트에 이미 존재하는 값에 따라 리스트를 필터링할 필요가 있었다.예를 들어, 현재 값보다 작은 값을 모두 제거하십시오.{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;
}
});
나의 경우 특정 필드 null이 제외된 리스트를 찾고 있었다.이 작업은 null 주소가 없는 개체의 임시 목록을 루프 및 채우기 위해 수행될 수 있다.하지만 자바 8 스트림 덕분에
List<Person> personsList = persons.stream()
.filter(p -> p.getAdrress() != null).collect(Collectors.toList());
#####################
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
자바 컬렉션 스트림 대신 다른 대안(더 가벼운)으로는 바닐라 컬렉션과 람다(https://github.com/eclipse/agileuml/blob/master/Ocl.java)를 사용하는 Ocl.java 라이브러리가 있다.
예를 들어 ArrayList 단어의 간단한 필터와 합은 다음과 같을 수 있다.
ArrayList<Word> sel = Ocl.selectSequence(words,
w -> w.pos.equals("NN"));
int total = Ocl.sumint(Ocl.collectSequence(sel,
w -> w.text.length()));
Word에 문자열 위치, 문자열 텍스트, 속성이 있는 경우.효율성은 스트림 옵션과 유사해 보인다. 예를 들어, 두 버전 모두에서 10000개의 단어가 약 50ms에 처리된다.
Python, Swift 등을 위한 동등한 OCL 라이브러리가 있다.기본적으로 Java 수집 스트림은 1998년부터 OCL에 존재했던 OCL 운영 ->선택, ->수집 등 재발명되었다.
참조URL: https://stackoverflow.com/questions/122105/how-to-filter-a-java-collection-based-on-predicate
'Programing' 카테고리의 다른 글
vue 구성 요소에서 href로 조건을 추가하려면 어떻게 해야 하는가? (0) | 2022.04.28 |
---|---|
Java에서 일반 클래스 인스턴스화 (0) | 2022.04.28 |
GNU가 다른 컴파일러를 사용하도록 설정 (0) | 2022.04.27 |
Vue2는 위치가 있는 외부 URL로 이동한다.href (0) | 2022.04.27 |
구성 요소를 동적으로 생성하고 vuej에서 프로그래밍 방식으로 값을 반환하는 방법 (0) | 2022.04.27 |