Czy istnieje elegancki sposób na usunięcie Nulli podczas przekształcania kolekcji za pomocą Guava?
Mam pytanie dotyczące uproszczenia kodu obsługi kolekcji przy użyciu Google Collections (update: guawa ).
W tym samym roku, w 2011 roku, w ramach projektu" resource id", w ramach projektu"resource id", w ramach projektu "resource id", w 2012 roku, w ramach projektu "resource id", w 2013 roku, w ramach projektu "resource id".]}Collection<Computer> matchingComputers = findComputers();
Collection<String> resourceIds =
Lists.newArrayList(Iterables.transform(matchingComputers, new Function<Computer, String>() {
public String apply(Computer from) {
return from.getResourceId();
}
}));
Teraz, getResourceId()
może zwrócić null( i zmiana tego nie jest obecnie opcją), jednak w tym przypadku chciałbym pominąć null z wynikowej kolekcji łańcuchów.
Oto jeden ze sposobów filtrowania null out:
Collections2.filter(resourceIds, new Predicate<String>() {
@Override
public boolean apply(String input) {
return input != null;
}
});
Można by to wszystko poskładać tak:
Collection<String> resourceIds = Collections2.filter(
Lists.newArrayList(Iterables.transform(matchingComputers, new Function<Computer, String>() {
public String apply(Computer from) {
return from.getResourceId();
}
})), new Predicate<String>() {
@Override
public boolean apply(String input) {
return input != null;
}
});
Ale to nie jest eleganckie, a co dopiero czytelne, dla tak prostego zadania! W rzeczywistości zwykły stary kod Javy (bez wymyślnych predykatów lub funkcji w ogóle) byłby prawdopodobnie dużo czystszy: {]}
Collection<String> resourceIds = Lists.newArrayList();
for (Computer computer : matchingComputers) {
String resourceId = computer.getResourceId();
if (resourceId != null) {
resourceIds.add(resourceId);
}
}
Korzystanie z powyższego z pewnością jest również opcją, ale z ciekawości (i chęci poznania więcej kolekcji Google), czy możesz zrobić dokładnie to samo w jakiś krótszy lub bardziej elegancki sposób za pomocą Google Kolekcje ? 5 answers
Jest już orzeczenie w Predicates
to ci pomoże ... Predicates.notNull()
... i możesz użyć Iterables.filter()
i faktu, że Lists.newArrayList()
może zająć Iterable
, aby posprzątać to trochę więcej.
Collection<String> resourceIds = Lists.newArrayList(
Iterables.filter(
Iterables.transform(matchingComputers, yourFunction),
Predicates.notNull()
)
);
Jeśli faktycznie nie potrzebujesz Collection
, tylko Iterable
, wtedy Lists.newArrayList()
połączenie może odejść zbyt i jesteś o krok czystszy ponownie!
Podejrzewam, że może się okazać, że Function
znów się przyda i będzie najbardziej przydatny jako
public class Computer {
// ...
public static Function<Computer, String> TO_ID = ...;
}
Który oczyszcza to jeszcze bardziej (i będzie promować ponowne użycie).
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-07-29 10:27:13
Nieco" ładniejsza " składnia z FluentIterable
(od 12): {]}
ImmutableList<String> resourceIds = FluentIterable.from(matchingComputers)
.transform(getResourceId)
.filter(Predicates.notNull())
.toList();
static final Function<Computer, String> getResourceId =
new Function<Computer, String>() {
@Override
public String apply(Computer computer) {
return computer.getResourceId();
}
};
Zwróć uwagę, że zwracana lista jest ImmutableList
. Można jednak użyć metody copyInto()
, aby wlać elementy do dowolnego zbioru.
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-07-29 10:27:34
Trwało to dłużej niż @Jon Skeet oczekiwał , ale strumienie Java 8 robią to prosto:
List<String> resourceIds = computers.stream()
.map(Computer::getResourceId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
Możesz również użyć .filter(x -> x != null)
jeśli chcesz; różnica jest bardzo niewielka .
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-10-07 03:00:50
Po pierwsze, stworzyłbym gdzieś stały filtr:
public static final Predicate<Object> NULL_FILTER = new Predicate<Object>() {
@Override
public boolean apply(Object input) {
return input != null;
}
}
Wtedy możesz użyć:
Iterable<String> ids = Iterables.transform(matchingComputers,
new Function<Computer, String>() {
public String apply(Computer from) {
return from.getResourceId();
}
}));
Collection<String> resourceIds = Lists.newArrayList(
Iterables.filter(ids, NULL_FILTER));
Możesz użyć tego samego filtra null wszędzie w kodzie.
Jeśli używasz tej samej funkcji obliczeniowej gdzie indziej, możesz też uczynić ją stałą, pozostawiając tylko:
Collection<String> resourceIds = Lists.newArrayList(
Iterables.filter(
Iterables.transform(matchingComputers, RESOURCE_ID_PROJECTION),
NULL_FILTER));
Na pewno nie jest tak miły jak odpowiednik C#, ale to wszystko będzie się lot ładniejszy w Javie 7 z zamknięciami i metodami rozszerzeń:)
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
2009-11-26 09:52:31
Możesz napisać własną metodę w ten sposób. to odfiltruje NULL dla dowolnej funkcji, która zwraca null z metody apply.
public static <F, T> Collection<T> transformAndFilterNulls(List<F> fromList, Function<? super F, ? extends T> function) {
return Collections2.filter(Lists.transform(fromList, function), Predicates.<T>notNull());
}
Metoda może być wywołana następującym kodem.
Collection c = transformAndFilterNulls(Lists.newArrayList("", "SD", "DDF"), new Function<String, Long>() {
@Override
public Long apply(String s) {
return s.isEmpty() ? 20L : null;
}
});
System.err.println(c);
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
2010-06-25 05:08:29