Jaki jest najlepszy sposób filtrowania kolekcji Java?
Chcę filtrować java.util.Collection
Na podstawie predykatu.
26 answers
Java 8 (2014) rozwiązuje ten problem używając strumieni i lambda w jednej linii kodu:
List<Person> beerDrinkers = persons.stream()
.filter(p -> p.getAge() > 16).collect(Collectors.toList());
Oto tutorial .
Użycie Collection#removeIf
aby zmodyfikować kolekcję w miejscu. (Uwaga: w tym przypadku predykat usunie obiekty, które spełniają predykat):
persons.removeIf(p -> p.getAge() <= 16);
Lambdaj umożliwia filtrowanie kolekcji bez pisania pętli lub klas wewnętrznych:
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),
greaterThan(16)));
Czy możesz sobie wyobrazić coś więcej czytelne?
Od 2006 roku jest członkiem Stowarzyszenia lambdaj.]}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 19:23:48
Zakładając, że używasz Java 1.5 i że nie możesz dodać kolekcji Google , zrobiłbym coś bardzo podobnego do tego, co zrobili faceci z Google. Jest to niewielka różnica w komentarzach Jona.
Najpierw dodaj ten interfejs do swojej bazy kodowej.
public interface IPredicate<T> { boolean apply(T type); }
Jego implementatorzy mogą odpowiedzieć, gdy określony predykat jest prawdziwy określonego typu. Np. Jeśli T
były User
i AuthorizedUserPredicate<User>
implementują IPredicate<T>
, to AuthorizedUserPredicate#apply
zwraca czy przekazywana w User
jest autoryzowany.
Wtedy w jakiejś klasie użytkowej, można powiedzieć
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;
}
Więc, zakładając, że masz zastosowanie powyższego może być
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);
Jeśli wydajność na sprawdzeniu liniowym jest niepokojąca, to mogę chcieć mieć obiekt domain, który ma kolekcję docelową. Obiekt domain, który ma kolekcję docelową, ma logikę filtrowania dla metod inicjalizujących, dodających i ustawiających kolekcję docelową.
Aktualizacja:
W klasie użytkowej (powiedzmy Predykat), dodałem metodę select z opcją wartości domyślnej, gdy predykat nie zwraca wartości oczekiwanej, a także statyczną właściwość dla params, które mają być używane wewnątrz nowego 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;
}
}
Poniższy przykład szuka brakujących obiektów między kolekcjami:
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;
}
});
Poniższy przykład wyszukuje instancję w kolekcji i zwraca pierwszy element kolekcji jako wartość domyślną, gdy instancja nie zostanie znaleziona:
MyType myObject = Predicate.select(collectionOfMyType, new IPredicate<MyType>() {
public boolean apply(MyType objectOfMyType) {
return objectOfMyType.isDefault();
}}, collectionOfMyType.get(0));
UPDATE (po wydaniu Javy 8):
Minęło kilka lat, odkąd (Alan) po raz pierwszy opublikował tę odpowiedź, i nadal nie mogę uwierzyć, że zbieram więc punkty za tę odpowiedź. W każdym razie, teraz, gdy Java 8 wprowadziła zamknięcia do języka, moja odpowiedź byłaby teraz znacznie inna i prostsza. W Javie 8 nie ma potrzeby stosowania odrębnej statycznej klasy narzędzi. Więc jeśli chcesz znaleźć pierwszy element, który pasuje do twojego predykatu.
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 dla opcji ma zdolność do get()
, isPresent()
, orElse(defaultUser)
, orElseGet(userSupplier)
i orElseThrow(exceptionSupplier)
, a także inne funkcje "monadyczne", takie jak map
, flatMap
i filter
.
Jeśli chcesz po prostu zebrać wszystkich użytkowników, którzy pasują do predykatu, użyj Collectors
, aby zakończyć strumień w żądanej kolekcji.
final UserService userService = ... // perhaps injected IoC
final List<UserModel> userOption = userCollection.stream().filter(u -> {
boolean isAuthorized = userService.isAuthorized(u);
return isAuthorized;
}).collect(Collectors.toList());
Zobacz tutaj aby uzyskać więcej przykładów działania strumieni Java 8.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-11 16:09:52
Use CollectionUtils.filter (Collection,Predicate) , z Apache Commons.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-17 06:11:33
"najlepszy" sposób to zbyt szeroka Prośba. Czy jest "najkrótsza"? "Najszybszy"? "Czytelny"? Filtrować w miejscu czy w innej kolekcji?
Najprostszym (ale nie najbardziej czytelnym) sposobem jest iteracja i użycie iteratora.metoda remove ():
Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
Foo foo = it.next();
if( !condition(foo) ) it.remove();
}
Teraz, aby uczynić go bardziej czytelnym, możesz owinąć go w metodę użytkową. Następnie wymyśl interfejs IPredicate, stwórz anonimową implementację tego interfejsu i zrób coś w stylu:
CollectionUtils.filterInPlace(col,
new IPredicate<Foo>(){
public boolean keepIt(Foo foo) {
return foo.isBar();
}
});
Gdzie filterInPlace() iteruje kolekcję i wywołuje Predykat.keepIt (), aby dowiedzieć się, czy instancja ma być przechowywana w kolekcji.
Naprawdę nie widzę uzasadnienia dla sprowadzenia trzeciej biblioteki tylko do tego zadania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-17 16:26:29
Rozważ zbiory Google dla zaktualizowanego frameworka kolekcji, który obsługuje generyki.
Aktualizacja : biblioteka zbiorów google jest obecnie przestarzała. Zamiast tego należy użyć najnowszej wersji Guava. Nadal ma wszystkie te same rozszerzenia do frameworku kolekcji, w tym mechanizm filtrowania na podstawie predykatu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-13 19:26:35
Wait for 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());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 08:24:01
Od wczesnej wersji Javy 8 można spróbować czegoś takiego:
Collection<T> collection = ...;
Stream<T> stream = collection.stream().filter(...);
Na przykład, jeśli masz listę liczb całkowitych i chcesz filtrować liczby, które są > 10, a następnie wydrukować te liczby do konsoli, możesz zrobić coś takiego:
List<Integer> numbers = Arrays.asList(12, 74, 5, 8, 16);
numbers.stream().filter(n -> n > 10).forEach(System.out::println);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-27 21:41:55
Wrzucę RxJava do ringu, który jest również dostępny na Android . RxJava może nie zawsze być najlepszą opcją, ale daje większą elastyczność, jeśli chcesz dodać więcej przekształceń do swojej kolekcji lub obsłużyć błędy podczas filtrowania.
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);
}
});
Wyjście:
1
3
5
Więcej szczegółów na temat RxJava ' s filter
można znaleźć tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-14 23:25:12
Konfiguracja:
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();
}
}
}
Użycie:
List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
public boolean filter(MyObject obj) {
return obj.shouldFilter();
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 16:41:27
A może jakaś prosta i prosta Java
List<Customer> list ...;
List<Customer> newList = new ArrayList<>();
for (Customer c : list){
if (c.getName().equals("dd")) newList.add(c);
}
Prosty, czytelny i łatwy (i działa w Androidzie!) Ale jeśli używasz Javy 8 możesz to zrobić w słodkiej jednej linijce:
List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());
Zauważ, że tolist () jest importowane statycznie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-12 05:03:57
Czy na pewno chcesz filtrować samą kolekcję, a nie iterator?
Zobacz org.Apacz.commons.Kolekcje.Iteratory.FilterIterator
Lub używając wersji 4 Apache commons org.Apacz.commons.kolekcje4.Iteratory.FilterIterator
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-16 08:43:33
Przyjrzyjmy się jak filtrować wbudowaną listę JDK i MutableList używając kolekcji Eclipse (dawniej kolekcji GS).
List<Integer> jdkList = Arrays.asList(1, 2, 3, 4, 5);
MutableList<Integer> ecList = Lists.mutable.with(1, 2, 3, 4, 5);
Jeśli chcesz filtrować liczby mniejsze niż 3, spodziewaj się następujących wyników.
List<Integer> selected = Lists.mutable.with(1, 2);
List<Integer> rejected = Lists.mutable.with(3, 4, 5);
Oto jak możesz filtrować używając anonimowej klasy wewnętrznej jako 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));
Oto kilka alternatyw dla filtrowania list JDK i kolekcji Eclipse MutableLists za pomocą predykaty fabryka.
Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));
Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));
Oto wersja, która nie przydziela obiektu dla predykatu, używając fabryki predykatów Predykaty2 zamiast metody selectWith
, która przyjmuje Predicate2
.
Assert.assertEquals(
selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));
Czasami chcesz filtrować pod negatywnym warunkiem. W zbiorach Eclipse istnieje specjalna metoda o nazwie reject
.
Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));
Assert.assertEquals(rejected, ecList.reject(lessThan3));
Oto jak można filtrować używając Java 8 lambda jako 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));
Metoda partition
zwróci dwa zbiory, zawierające elementy wybrane i odrzucone przez 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());
Uwaga: jestem committerem Dla Kolekcji Eclipse.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 04:20:22
Z ForEach DSL możesz napisać
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();
Biorąc pod uwagę zbiór [the, quick, brown, fox, jumps, over, the, lazy, dog], skutkuje to [quick, brown, jumps, over, lazy], czyli wszystkimi ciągami dłuższymi niż trzy znaki.
Wszystkie style iteracji obsługiwane przez ForEach DSL are
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
Aby uzyskać więcej informacji, zapoznaj się z https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-03 16:20:21
Kolekcje2.metoda filter (Collection,Predicate) w Google ' s Guava library robi dokładnie to, czego szukasz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-09 21:19:44
To, w połączeniu z brakiem prawdziwych zamknięć, jest moim największym zmartwieniem dla Javy. Szczerze mówiąc, większość wymienionych powyżej metod jest dość łatwa do odczytania i naprawdę skuteczna; jednak po spędzeniu czasu z. Net, Erlang itp... zrozumienie listy zintegrowane na poziomie językowym sprawia, że wszystko jest o wiele czystsze. Bez dodatków na poziomie języka Java nie może być tak czysta, jak wiele innych języków w tej dziedzinie.
Jeśli wydajność jest ogromnym problemem, zbiory Google to sposób aby przejść (lub napisać własne proste narzędzie predykatu). Składnia Lambdaj jest dla niektórych bardziej czytelna, ale nie jest tak wydajna.
I jest jeszcze biblioteka, którą napisałem. Zignoruję wszelkie pytania dotyczące jego skuteczności(tak, jest tak źle)...... Tak, Wiem, że jest wyraźnie odbity i nie, nie używam go, ale działa: {]}
LinkedList<Person> list = ......
LinkedList<Person> filtered =
Query.from(list).where(Condition.ensure("age", Op.GTE, 21));
Lub
LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 03:55:48
JFilter http://code.google.com/p/jfilter / najlepiej odpowiada Twoim wymaganiom.
JFilter jest prostą i wydajną biblioteką open source do odpytywania kolekcji Java beans.
Kluczowe cechy
- Wsparcie kolekcji (java.util.Kolekcja, java.util.Map i Array) właściwości.
- Wsparcie zbioru wewnątrz zbioru o dowolnej głębokości.
- Wsparcie zapytań wewnętrznych.
- Wsparcie parametryzowanych zapytań.
- Can filter 1 milion rekordów w kilka 100 ms.
- Filter (query) jest podany w prostym formacie json, jest jak zapytania Mangodb. Oto kilka przykładów.
- {"id": {"$le": "10"}
- gdzie właściwość object id jest mniejsza niż równa 10.
- {"id": {"$in": ["0", " 100"]}}
- gdzie właściwość object id wynosi 0 lub 100.
- {"lineItems": {"lineAmount": "1"}}
- gdzie właściwość kolekcji lineItems typu parametryzowanego ma wartość lineAmount równą 1.
- {"$and":[{"id": "0"}, {"billingAddress":{"city": "DEL"}}]}
- gdzie właściwość id wynosi 0 i billingAddress.właścicielem miasta jest DEL.
- {"lineItems": {"taxes": {"key": {"code": "GST"}, "value": {"$gt": "1.01"}}}}
- gdzie właściwość kolekcji lineItems parametryzowanego typu, która ma właściwość map type parametryzowanego typu, ma kod równy wartości GST większej niż 1.01.
- {"$or": [{"code": "10"}, {"SKU": {"$i": [{"cena": {"$w':['20', '40']}}, {'Kod": "RedApple"}]}}]}
- Wybierz wszystkie produkty, w których Kod produktu to 10 lub cena sku w 20 i 40, A kod sku to "RedApple".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-05 10:46:58
Napisałem rozszerzoną klasę Iterable, która wspiera stosowanie algorytmów funkcjonalnych bez kopiowania zawartości kolekcji.
Użycie:
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);
}
Powyższy kod faktycznie wykona
for( int n : myList )
{
if( n % 2 == 0 )
{
System.out.println(n);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 15:50:02
Use Collection Query Engine (CQEngine). Jest to zdecydowanie najszybszy sposób, aby to zrobić.
Zobacz także: Jak odpytywać zbiory obiektów w Javie (Criteria/SQL-like)?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:25
Od java 9 Collectors.filtering
jest włączone:
public static <T, A, R>
Collector<T, ?, R> filtering(Predicate<? super T> predicate,
Collector<? super T, A, R> downstream)
Zatem filtrowanie powinno być:
collection.stream().collect(Collectors.filtering(predicate, collector))
Przykład:
List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
.collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 13:59:00
Proste rozwiązanie pre-Java8:
ArrayList<Item> filtered = new ArrayList<Item>();
for (Item item : items) if (condition(item)) filtered.add(item);
Niestety to rozwiązanie nie jest w pełni ogólne, wypisując listę, a nie Typ danej kolekcji. Ponadto wprowadzanie bibliotek lub pisanie funkcji zawijających ten kod wydaje mi się przesadą, chyba że warunek jest złożony, ale wtedy możesz napisać funkcję dla warunku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 19:15:32
Https://code.google.com/p/joquery/
Obsługuje różne możliwości,
Dany zbiór,
Collection<Dto> testList = new ArrayList<>();
Typu,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Filtr
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();
Również,
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"});
Sortowanie (dostępne również dla Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Grupowanie (dostępne również dla Javy 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Joins (dostępny również dla Java 7)
Podane,
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<>();
Można połączyć tak,
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();
Wyrażenia
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-03 12:59:35
Moja odpowiedź opiera się na tym od Kevina Wonga, tutaj jako jednolinijkowy za pomocą CollectionUtils
z spring i wyrażenia Java 8 lambda.
CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);
Jest to tak zwięzłe i czytelne, jak każda alternatywa, jaką widziałem (bez użycia bibliotek opartych na aspektach)
Spring CollectionUtils jest dostępny od wersji wiosennej 4.0.2.Wydaj i pamiętaj, że potrzebujesz JDK 1.8 i poziomu językowego 8+.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-22 11:18:24
Kilka naprawdę świetnych, świetnych odpowiedzi tutaj. Ja bym chciał żeby było jak najbardziej proste i czytelne:
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();
}
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 16:22:48
Używając java 8
, a konkretnie lambda expression
, możesz to zrobić po prostu jak w poniższym przykładzie:
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
Gdzie dla każdej product
wewnątrz myProducts
kolekcji, Jeśli prod.price>10
, to dodaj ten produkt do nowej listy filtrowanej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-12 21:47:55
Z Guawą:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-15 09:26:44
Musiałem filtrować listę w zależności od wartości już obecnych na liście. Na przykład usuń wszystkie następujące wartości, które są mniejsze niż bieżąca wartość. {2 5 3 4 7 5} -> {2 5 7}. Lub na przykład, aby usunąć wszystkie duplikaty {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;
}
}
To będzie używane w ten sposób.
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;
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-15 14:28:05