Tôi muốn lọc một java.util.Collection
dựa trên một vị ngữ.
Tôi muốn lọc một java.util.Collection
dựa trên một vị ngữ.
Câu trả lời:
Java 8 ( 2014 ) giải quyết vấn đề này bằng cách sử dụng các luồng và lambdas trong một dòng mã:
List<Person> beerDrinkers = persons.stream()
.filter(p -> p.getAge() > 16).collect(Collectors.toList());
Đây là một hướng dẫn .
Sử dụng Collection#removeIf
để sửa đổi bộ sưu tập tại chỗ. (Lưu ý: Trong trường hợp này, vị từ sẽ loại bỏ các đối tượng thỏa mãn vị ngữ):
persons.removeIf(p -> p.getAge() <= 16);
lambdaj cho phép lọc các bộ sưu tập mà không cần viết các vòng lặp hoặc các lớp bên trong:
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
greaterThan(16)));
Bạn có thể tưởng tượng một cái gì đó dễ đọc hơn?
Tuyên bố miễn trừ trách nhiệm: Tôi là người đóng góp cho lambdaj
persons.removeIf(p -> p.getAge() <= 16);
Giả sử rằng bạn đang sử dụng Java 1.5 và bạn không thể thêm Bộ sưu tập của Google , tôi sẽ làm một cái gì đó rất giống với những gì Google đã làm. Đây là một thay đổi nhỏ về ý kiến của Jon.
Đầu tiên thêm giao diện này vào cơ sở mã của bạn.
public interface IPredicate<T> { boolean apply(T type); }
Những người thực hiện nó có thể trả lời khi một vị ngữ nhất định đúng với một loại nhất định. Ví dụ: Nếu T
đã User
và AuthorizedUserPredicate<User>
thực hiện IPredicate<T>
, sau đó AuthorizedUserPredicate#apply
trả về cho dù thông qua User
được cho phép.
Sau đó, trong một số lớp tiện ích, bạn có thể nói
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;
}
Vì vậy, giả sử rằng bạn có việc sử dụng ở trên có thể là
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);
Nếu hiệu suất của kiểm tra tuyến tính là mối quan tâm, thì tôi có thể muốn có một đối tượng miền có bộ sưu tập đích. Đối tượng miền có bộ sưu tập đích sẽ có logic lọc cho các phương thức khởi tạo, thêm và đặt bộ sưu tập đích.
CẬP NHẬT:
Trong lớp tiện ích (giả sử là Vị ngữ), tôi đã thêm một phương thức chọn với một tùy chọn cho giá trị mặc định khi vị từ không trả về giá trị mong đợi và cũng là một thuộc tính tĩnh cho các tham số được sử dụng bên trong IPredicate mới.
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;
}
}
Ví dụ sau đây tìm kiếm các đối tượng bị thiếu giữa các bộ sưu tập:
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;
}
});
Ví dụ sau, tìm kiếm một thể hiện trong một bộ sưu tập và trả về phần tử đầu tiên của bộ sưu tập làm giá trị mặc định khi không tìm thấy thể hiện:
MyType myObject = Predicate.select(collectionOfMyType, new IPredicate<MyType>() {
public boolean apply(MyType objectOfMyType) {
return objectOfMyType.isDefault();
}}, collectionOfMyType.get(0));
CẬP NHẬT (sau khi phát hành Java 8):
Đã vài năm kể từ lần đầu tiên tôi (Alan) đăng câu trả lời này và tôi vẫn không thể tin rằng mình đang thu thập điểm SO cho câu trả lời này. Ở mức độ nào, bây giờ Java 8 đã giới thiệu các bao đóng cho ngôn ngữ, câu trả lời của tôi bây giờ sẽ khác đi đáng kể và đơn giản hơn. Với Java 8, không cần một lớp tiện ích tĩnh riêng biệt. Vì vậy, nếu bạn muốn tìm phần tử thứ 1 phù hợp với vị ngữ của bạn.
final UserService userService = ... // perhaps injected IoC
final Optional<UserModel> userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;
}).findFirst();
API JDK 8 cho optionals có khả năng get()
, isPresent()
, orElse(defaultUser)
, orElseGet(userSupplier)
và orElseThrow(exceptionSupplier)
, cũng như các chức năng khác 'monadic' như map
, flatMap
và filter
.
Nếu bạn chỉ muốn thu thập tất cả người dùng phù hợp với vị ngữ, thì hãy sử dụng Collectors
để kết thúc luồng trong bộ sưu tập mong muốn.
final UserService userService = ... // perhaps injected IoC
final List<UserModel> userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;
}).collect(Collectors.toList());
Xem ở đây để biết thêm ví dụ về cách hoạt động của luồng Java 8.
val authorized = for (user <- users if user.isAuthorized) yield user
Sử dụng CollectionUtils.filter (Bộ sưu tập, Vị ngữ) , từ Apache Commons.
Cách "tốt nhất" là một yêu cầu quá rộng. Có phải là "ngắn nhất"? "Nhanh nhất"? "Có thể đọc được"? Lọc tại chỗ hoặc vào bộ sưu tập khác?
Cách đơn giản nhất (nhưng không dễ đọc nhất) là lặp lại nó và sử dụng phương thức Iterator.remove ():
Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
Foo foo = it.next();
if( !condition(foo) ) it.remove();
}
Bây giờ, để làm cho nó dễ đọc hơn, bạn có thể gói nó thành một phương thức tiện ích. Sau đó, phát minh ra một giao diện IPredicate, tạo một triển khai ẩn danh của giao diện đó và làm một cái gì đó như:
CollectionUtils.filterInPlace(col,
new IPredicate<Foo>(){
public boolean keepIt(Foo foo) {
return foo.isBar();
}
});
trong đó filterInPlace () lặp lại bộ sưu tập và gọi Primateate.keepIt () để tìm hiểu nếu cá thể được giữ trong bộ sưu tập.
Tôi thực sự không thấy một lời biện minh nào cho việc mang vào thư viện của bên thứ ba chỉ cho nhiệm vụ này.
stream()
tính năng này, nhưng không phải ai cũng được chơi với những đồ chơi mới nhất: P
Xem xét Bộ sưu tập của Google cho khung Bộ sưu tập được cập nhật hỗ trợ thuốc generic.
CẬP NHẬT : Thư viện bộ sưu tập google hiện không dùng nữa. Thay vào đó, bạn nên sử dụng phiên bản mới nhất của Guava . Nó vẫn có tất cả các phần mở rộng giống nhau cho khung bộ sưu tập bao gồm cơ chế lọc dựa trên một vị từ.
Đợi 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());
personList.removeIf(p -> p.age < 30);
Ít dài dòng hơn. Ngoài ra, tôi đã nghe nói về việc bắt đầu thực hiện apis chấp nhận và trả lại Stream
s thay vì Collection
s vì Stream
nó rất hữu ích và nhanh chóng nhưng việc đi đến / từ chúng là chậm.
Kể từ khi phát hành sớm Java 8, bạn có thể thử một cái gì đó như:
Collection<T> collection = ...;
Stream<T> stream = collection.stream().filter(...);
Ví dụ: nếu bạn có một danh sách các số nguyên và bạn muốn lọc các số> 10 và sau đó in ra các số đó vào bảng điều khiển, bạn có thể thực hiện một số việc như:
List<Integer> numbers = Arrays.asList(12, 74, 5, 8, 16);
numbers.stream().filter(n -> n > 10).forEach(System.out::println);
Tôi sẽ ném RxJava vào vòng, cũng có sẵn trên Android . RxJava có thể không phải luôn luôn là lựa chọn tốt nhất, nhưng nó sẽ giúp bạn linh hoạt hơn nếu bạn muốn thêm nhiều biến đổi trên bộ sưu tập của mình hoặc xử lý các lỗi trong khi lọc.
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);
}
});
Đầu ra:
1
3
5
Thông tin chi tiết về RxJava filter
có thể được tìm thấy ở đây .
Các thiết lập:
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();
}
}
}
Việc sử dụng:
List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
public boolean filter(MyObject obj) {
return obj.shouldFilter();
}
});
Làm thế nào về một số Java đơn giản và mạnh mẽ
List<Customer> list ...;
List<Customer> newList = new ArrayList<>();
for (Customer c : list){
if (c.getName().equals("dd")) newList.add(c);
}
Đơn giản, dễ đọc và dễ dàng (và hoạt động trong Android!) Nhưng nếu bạn đang sử dụng Java 8, bạn có thể thực hiện điều đó trong một dòng ngọt ngào:
List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());
Lưu ý rằng toList () được nhập tĩnh
Bạn có chắc chắn muốn tự lọc Bộ sưu tập, thay vì bộ lặp không?
xem org.apache.commons.collections.iterators.FilterIterator
hoặc sử dụng phiên bản 4 của apache commons org.apache.commons.collections4.iterators.FilterIterator
Hãy xem cách lọc Danh sách JDK tích hợp và Danh sách Mutable bằng cách sử dụng Bộ sưu tập Eclipse .
List<Integer> jdkList = Arrays.asList(1, 2, 3, 4, 5);
MutableList<Integer> ecList = Lists.mutable.with(1, 2, 3, 4, 5);
Nếu bạn muốn lọc các số nhỏ hơn 3, bạn sẽ mong đợi các đầu ra sau.
List<Integer> selected = Lists.mutable.with(1, 2);
List<Integer> rejected = Lists.mutable.with(3, 4, 5);
Đây là cách bạn có thể lọc bằng lambda Java 8 như 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));
Đây là cách bạn có thể lọc bằng cách sử dụng một lớp bên trong ẩn danh là 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));
Dưới đây là một số lựa chọn thay thế để lọc danh sách JDK và Bộ sưu tập Eclipse MutableLists bằng cách sử dụng nhà máy Dự đoán .
Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));
Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));
Đây là một phiên bản không phân bổ một đối tượng cho vị từ, bằng cách sử dụng nhà máy Dự đoán2 thay vì selectWith
phương thức lấy một Predicate2
.
Assert.assertEquals(
selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));
Đôi khi bạn muốn lọc trên một điều kiện tiêu cực. Có một phương thức đặc biệt trong Bộ sưu tập Eclipse cho cái được gọi đó reject
.
Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));
Assert.assertEquals(rejected, ecList.reject(lessThan3));
Phương thức partition
sẽ trả về hai bộ sưu tập, chứa các phần tử được chọn và từ chối bởi 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());
Lưu ý: Tôi là người đi làm cho Bộ sưu tập Eclipse.
removeIf
một danh sách hoặc thiết lập cho nguyên thủy?
Với DSL ForEach bạn có thể viết
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();
Đưa ra một bộ sưu tập [The, quick, brown, fox, jumps, over, the, lazy, dog] điều này dẫn đến [quick, brown, jumps, over, lazy], tức là tất cả các chuỗi dài hơn ba ký tự.
Tất cả các kiểu lặp được hỗ trợ bởi ForEach DSL là
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
Để biết thêm chi tiết, vui lòng tham khảo https://www.iam.unibe.ch/scg/svn_Vpose/Source/ForEach
Phương thức Bộ sưu tập2.filter (Bộ sưu tập, Vị ngữ) trong thư viện Guava của Google thực hiện đúng như những gì bạn đang tìm kiếm.
Vì java 9 Collectors.filtering
được bật:
public static <T, A, R>
Collector<T, ?, R> filtering(Predicate<? super T> predicate,
Collector<? super T, A, R> downstream)
Do đó, bộ lọc phải là:
collection.stream().collect(Collectors.filtering(predicate, collector))
Thí dụ:
List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
.collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));
Điều này, kết hợp với việc thiếu các bao đóng thực sự, là điểm yếu lớn nhất của tôi đối với Java. Thành thật mà nói, hầu hết các phương pháp được đề cập ở trên là khá dễ đọc và THỰC SỰ hiệu quả; tuy nhiên, sau khi dành thời gian với .Net, Erlang, v.v ... danh sách hiểu được tích hợp ở cấp độ ngôn ngữ làm cho mọi thứ trở nên sạch sẽ hơn rất nhiều. Không có bổ sung ở cấp độ ngôn ngữ, Java không thể sạch như nhiều ngôn ngữ khác trong lĩnh vực này.
Nếu hiệu suất là một mối quan tâm lớn, các bộ sưu tập của Google là cách để đi (hoặc viết tiện ích vị ngữ đơn giản của riêng bạn). Cú pháp Lambdaj dễ đọc hơn đối với một số người, nhưng nó không hoàn toàn hiệu quả.
Và sau đó có một thư viện tôi đã viết. Tôi sẽ bỏ qua bất kỳ câu hỏi nào liên quan đến hiệu quả của nó (vâng, nó tệ lắm)
LinkedList<Person> list = ......
LinkedList<Person> filtered =
Query.from(list).where(Condition.ensure("age", Op.GTE, 21));
HOẶC LÀ
LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");
JFilter http://code.google.com.vn/p/jfilter/ phù hợp nhất với yêu cầu của bạn.
JFilter là một thư viện mã nguồn mở đơn giản và hiệu năng cao để truy vấn bộ sưu tập các hạt Java.
Các tính năng chính
Tôi đã viết một lớp Iterable mở rộng hỗ trợ áp dụng các thuật toán chức năng mà không cần sao chép nội dung bộ sưu tập.
Sử dụng:
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);
}
Đoạn mã trên sẽ thực sự thực thi
for( int n : myList )
{
if( n % 2 == 0 )
{
System.out.println(n);
}
}
Sử dụng Bộ sưu tập công cụ truy vấn (CQEngine) . Đó là cách nhanh nhất để làm điều này.
Xem thêm: Làm thế nào để bạn truy vấn các bộ sưu tập đối tượng trong Java (Tiêu chí / giống như SQL)?
Một số câu trả lời thực sự tuyệt vời ở đây. Tôi, tôi muốn giữ cho mình đơn giản và dễ đọc nhất có thể:
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();
}
}
}
}
}
Giải pháp tiền Java8 đơn giản:
ArrayList<Item> filtered = new ArrayList<Item>();
for (Item item : items) if (condition(item)) filtered.add(item);
Thật không may, giải pháp này không hoàn toàn chung chung, xuất ra một danh sách hơn là loại bộ sưu tập đã cho. Ngoài ra, việc mang vào các thư viện hoặc viết các hàm bao bọc mã này có vẻ như quá mức cần thiết đối với tôi trừ khi điều kiện phức tạp, nhưng sau đó bạn có thể viết một hàm cho điều kiện.
https://code.google.com.vn/p/joquery/
Hỗ trợ các khả năng khác nhau,
Cho bộ sưu tập,
Collection<Dto> testList = new ArrayList<>();
loại,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Bộ lọc
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();
Cũng thế,
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"});
Sắp xếp (cũng có sẵn cho Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Nhóm (cũng có sẵn cho Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Tham gia (cũng có sẵn cho Java 7)
Được,
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<>();
Có thể tham gia như,
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();
Biểu thức
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Câu trả lời của tôi dựa trên điều đó từ Kevin Wong, ở đây dưới dạng một lớp lót sử dụng CollectionUtils
từ mùa xuân và biểu thức lambda Java 8 .
CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);
Điều này ngắn gọn và dễ đọc như bất kỳ sự thay thế nào tôi đã thấy (không sử dụng các thư viện dựa trên khía cạnh)
Spring CollectionUtils có sẵn từ phiên bản mùa xuân 4.0.2.RELEASE và hãy nhớ rằng bạn cần JDK 1.8 và ngôn ngữ cấp 8+.
Sử dụng java 8
, cụ thể lambda expression
, bạn có thể làm điều đó đơn giản như ví dụ dưới đây:
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
trong đó cho mỗi bộ sưu tập product
bên trong myProducts
, nếu prod.price>10
, sau đó thêm sản phẩm này vào danh sách được lọc mới.
Tôi cần lọc một danh sách tùy thuộc vào các giá trị đã có trong danh sách. Ví dụ: xóa tất cả các giá trị theo sau giá trị nhỏ hơn giá trị hiện tại. {2 5 3 4 7 5} -> {2 5 7}. Hoặc ví dụ để xóa tất cả các bản sao {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;
}
}
Con ong này sẽ dùng như thế này.
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;
}
});
Với ổi:
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
Trong Java 8, Bạn có thể trực tiếp sử dụng phương thức lọc này và sau đó thực hiện điều đó.
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);