Guava Iterables vs Collections2

0

Porównajmy Iterables.filter(...) i Collections2.filter(...) oba robią dokładnie to samo. Ktoś mi rozjaśni jaka jest różnica i kiedy który stosować? A jak nie ma różnicy, to po co są dwa sposoby?

0

Guava....

0
jarekr000000 napisał(a):

Guava....

I co ta odpowiedź wnosi do tematu? Jak chcesz zabłysnąć, to podaj mi alternatywę na Androida starszego niż 7 (nie, Kotlin to nie odpowiedź)

0

Na pierwszy rzut oka to jedna operuje na Iterable a druga na Collection. Są to dwa różne interfejsy, nie każde Iterable jest Collection.
Jak ogólnie ktoś pracuje na kolekcjach to pewnie niewygodne byłoby używanie Iterable i rzutowanie z powrotem na Collection.

0

Jak się zdaje, znalazłem różnicę. Wygląda na to, że Iterables filtruje i zwraca wynik, to tyle. Jeśli chodzi o Collections2, to:

A few things to note here – first, the output of Collections.filter() is a live view of the original collection – changes to one will be reflected in the other.

It’s also important to understand that now, the result is constrained by the predicate – if we add an element that doesn’t satisfy that Predicate, an IllegalArgumentException will be thrown:

@Test(expected = IllegalArgumentException.class)
public void givenFilteredCollection_whenAddingInvalidElement_thenException() {
    List<String> names = Lists.newArrayList("John", "Jane", "Adam", "Tom");
    Collection<String> result 
      = Collections2.filter(names, Predicates.containsPattern("a"));
 
    result.add("elvis");
}

P.S. przekonwertować do normalnej listy/mapy/set czy coś tam można tak samo w obu przypadkach, to nie ma znaczenia.

0

Barbara Liskov gdzieś po drodze się rozpłakała, trafiając na Collection2.filter().

A co do alternatyw dla Guavy wolałbym skorzystać w kolejności z:

  • Kotlin
  • Scala
  • Bazel + Desugar + Streamy
  • poczekać na Streamy z Desugar w AGP
  • jakiś backport Stream API
0

Naprawdę wolisz jakiś niesprawdzony backport stream api? Każdy, który znam nie nadaje się do niczego. Jaki konkretnie masz zarzut do Guavy? Coś tam działa nie tak jak powinno? Gdzieś wycieki pamięci, namacalne spadki wydajności? Generuje jakiś wielki narzut?

Takie gadanie, że nie bo nie to nie wynika z żadnych obiektywnych przesłanek, tak samo jak ciągle odradzasz gsona, z tą różnicą że gson ma alternatywy, a guava collections albo FluentIterable nie ma (zmiana języka na inny to nie alternatywa).

Tak btw stream api raczej nigdy nie będzie kompatybilne z Androidem < 7, więc poczekać to można, ale na czas, gdyby Androida starszego niż 7 będzie można olać.

Gdyby nie chodziło o Androida, to faktycznie wystarczy Java8, ale wolę Guav niż jakiś krzywy port stream api.

1
kulson napisał(a):

Naprawdę wolisz jakiś niesprawdzony backport stream api? Każdy, który znam nie nadaje się do niczego.

Nie, nie wolę niesprawdzonych backportów. Dlatego nigdzie nie podałem, żeby korzystać z niesprawdzonego backportu Streamów. Co więcej, działający backport Stream API wymieniłem jako ostatnią z alternatyw.

kulson napisał(a):

Jaki konkretnie masz zarzut do Guavy? Coś tam działa nie tak jak powinno? Gdzieś wycieki pamięci, namacalne spadki wydajności? Generuje jakiś wielki narzut?

Jakiś konkretny zarzut do Guavy? Nie wiem. Niespecjalnie prawdę powiedzawszy. Po prostu widzę rozsądniejsze rozwiązania. Nigdzie nie pisałem, żeby nie korzystać z Guavy, czy że jest zła. Aczkolwiek nie podoba mi się w Guavie kilka rzeczy. Chociażby ten potworek, którego wkleiłeś we wcześniejszym poście. Albo 15k metod na twarz w wersji light, które mogłyby być spokojnie podzielone na mniejsze artefakty.

kulson napisał(a):

Takie gadanie, że nie bo nie to nie wynika z żadnych obiektywnych przesłanek, tak samo jak ciągle odradzasz gsona, z tą różnicą że gson ma alternatywy, a guava collections albo FluentIterable nie ma.

Nie wiem, co GSON ma wspólnego z tematem. Ogłaszanie, że ktoś nie podaje argumentów nie oznacza od razu, że ta osoba ich nie podaje. Już kilka razy odnosiłem się do jego popsutego API. Po prostu wolę spacer po lesie zamiast po polu minowym. Natomiast jeżeli komuś wygodnie z GSON'em, to niech z niego korzysta.

kulson napisał(a):

(zmiana języka na inny to nie alternatywa)

Niechęć do używania czegoś, nie sprawia, że to nie jest alternatywą.

Tak btw stream api raczej nigdy nie będzie kompatybilne z Androidem < 7, więc poczekać to można, ale na czas, gdyby Androida starszego niż 7 będzie można olać.

Zdefiniuj kompatybilne. Jeżeli uważasz, że np. lambdy albo domyślne metody w interfejsach są niekompatybilne, to się nawet zgodzę. Jeżeli nie, to podałem w poprzednim poście, jak korzystać z Javowych Streamów.

0
Michał Sikora napisał(a):
kulson napisał(a):

Jeżeli nie, to podałem w poprzednim poście, jak korzystać z Javowych Streamów

Sprecyzujesz? Bazel? Jak to działa? Domyślnie streamów jak wiadomo, nie da się użyć na Androidzie starszym niż 7. Lambdy akurat są kompatybilne, więc nie wiem co masz na myśli.

A Guava/Iterable/FluentIterable to praktycznie ta sama składnia, co streamy. Po co te parcie na streamy w zasadzie?

0

To w takim razie jeśli jest lambda to VAVR powinien tez przechodzić choć na Androida to może być overkill

0

No nie bardzo: https://github.com/vavr-io/vavr/issues/985 ale jakby nawet, to byłyby pewnie te same ograniczenia, co streamy

0

A racja, przecież Vavr wymaga 8...

0
kulson napisał(a):

Sprecyzujesz? Bazel? Jak to działa? Domyślnie streamów jak wiadomo, nie da się użyć na Androidzie starszym niż 7. Lambdy akurat są kompatybilne, więc nie wiem co masz na myśli.

Mmmm... Trochę od końca zacznę. To akurat lambdy są przede wszystkim niekompatybilne z Androidem na poziomie kodu binarnego. To jest dokładnie powód, dla którego np. Vavr nie działałby na Androidzie. Do specyfikacji Dalvika odpowiednik invokedynamic w postacji invoke-custom został dodany dopiero w wersji 38. Niemniej, dalej nie ma konkretnej implementacji LambdaMetafactory, która pozwalałaby na generowanie lambd podczas działania programu. Możliwość korzystania z wyrażeń lambda wynika z jakieś procesu postkompilacyjnego. Może to być np. Retrolambda, Jack & Jill albo Desugar. Desugar jest to narzędzie wyciągnięte z Bazel i dodane do AGP. Transformuje ono kod źródłowy zawierający np. lambdy na taki, który jest kompatybilny z DEX.

Streamy, same w sobie, nie posiadają akurat niczego specjalnego po stronie kodu binarnego (pomijając, że są napisane na lambdach). Natomiast napisanie programu, który by transformował odpowiednio całe API jest dużo trudniejsze i bardziej pracochłonne niż transformacja lambd. Desugar został wzbogacony m.in. o Streamy jakoś w lutym, ale tylko wewnątrz projektu Bazel i trzeba poczekać na przeportowanie go do AGP. Natomiast Bazel sam w sobie nic nie robi specjalnego. System budowy projektów "jak każdy inny".

kulson napisał(a):

A Guava/Iterable/FluentIterable to praktycznie ta sama składnia, co streamy. Po co te parcie na streamy w zasadzie?

Ależ ja się zgadzam. Ja nie mam żadnego parcia na Streamy. Jak ktoś już ma Guavę w projekcie, to niech korzysta z Guavy. Równie dobrze nie miałbym nic przeciwko używaniu synchronicznie Rx API do takich transformacji, jeżeli już byłby Rx w projekcie. Wyglądałoby to trochę głupio, ale zasadniczo działałoby dobrze. Czemu wolałbym inne rozwiązania niż Guava, po krótce napisałem wcześniej.

0
Michał Sikora napisał(a):

Desugar został wzbogacony m.in. o Streamy jakoś w lutym, ale tylko wewnątrz projektu Bazel i trzeba poczekać na przeportowanie go do AGP.

Ze streamów można korzystać od dawna, ale tylko jeśli minimalne api to Nougat. Chodzi ci o to, że Desguar z Bazel nie ma tego ograniczenia i można korzystać też na starszych Androidach?

1 użytkowników online, w tym zalogowanych: 0, gości: 1