JavaRush /Blog Java /Random-PL /Przerwa kawowa #163. Jaka jest różnica między lambdą a od...

Przerwa kawowa #163. Jaka jest różnica między lambdą a odwołaniem do metody. 5 sposobów łączenia ciągu null w Javie

Opublikowano w grupie Random-PL

Jaka jest różnica między lambdą a odwołaniem do metody

Źródło: Reddit IntelliJ IDEA sugeruje zastąpienie wyrażeń lambda odniesieniami do metod. Jaka jest różnica między nimi? Przerwa kawowa #163.  Jaka jest różnica między lambdą a odwołaniem do metody.  5 sposobów łączenia ciągu null w Javie — 1Okazuje się, że istnieje subtelna różnica między wyrażeniami lambda a odniesieniami do metod. Na przykład porównaj: myInstance::getStuff i () ->myInstance.getStuff() . Ogólnie rzecz biorąc, obie opcje są sobie równoważne. Ale jeśli myInstance ma wartość null, a lambda generuje wskaźnik zerowy podczas oceny lambda, wówczas odwołanie do metody zostanie wygenerowane natychmiast podczas próby dostępu do odwołania. I co? Ogólnie rzecz biorąc, jest to ważne, jeśli kod oceniający wyrażenie lambda znajduje się wewnątrz try-catch ze wskaźnikiem zerowym. Na przykład mam funkcję mayBeNull (funkcja Dostawca<T>) , która robi coś takiego:
try {
    doStuff(function.get().getSomeMore().getSomeMore());
} catch (NullPointerException e) {
    doOtherStuff();
}
Jeśli wywołanie funkcji MightBeNull(() -> myNullVariable.getStuff()) zadziałałoby bez zgłaszania wyjątku, wówczas „odpowiednik”: MightBeNull(myNullVariable::getStuff) zgłosi wyjątek NullPointerException natychmiast po wywołaniu funkcji. To jest różnica. Notatka. Według Stackoverflow, jeśli zastąpisz lambdę odwołaniem do metody, kod bajtowy klasy będzie bardziej zwarty, co oznacza, że ​​klasa będzie ładować się szybciej do JVM. Aby jednak odczuć taki zysk, potrzebne są tysiące niezoptymalizowanych lambd. Jednak w dużym projekcie taką liczbę można łatwo zgromadzić. W przeciwnym razie wybór między lambdą a odwołaniem do metody jest kwestią gustu i czytelności kodu. Na przykład, jeśli lambda ma kilka linii, wówczas czytelność jest zmniejszona, a kod na tym skorzysta tylko wtedy, gdy lambda zostanie umieszczona w osobnej metodzie i użyte zostanie odwołanie do niej.

5 sposobów łączenia ciągu null w Javie

Źródło: Gitconnected Po przeczytaniu tego wpisu dowiesz się więcej sposobów pracy z ciągami znaków w Javie. Java udostępnia wiele sposobów łączenia ciągów znaków, ale czasami, gdy nie zwracamy uwagi na ciągi zerowe, możemy otrzymać ciąg zerowy, czego oczywiście nie chcemy. Skorzystaj więc z moich zalecanych metod, aby uniknąć wartości null podczas łączenia String.

Analiza problemu

Jeśli chcemy połączyć tablice ciągów, możemy po prostu użyć operatora +. Jednak podczas wykonywania tej czynności możemy napotkać wartości zerowe .
String[] values = {"https", "://", "gist.", "github", ".com", null};
String result = "";

for (String value : values) {
    result = result + value;
}
Połączenie wszystkich tych elementów prowadzi do następującego wyniku:
https://Gist.github.comnull
Chociaż znaleźliśmy problem, wynikowa wartość null jest również łączona jako ciąg znaków, co zdecydowanie nie jest tym, na co liczyliśmy. Nawet jeśli pracujemy na Javie w wersji 8 lub nowszej i używamy statycznej metody String.join() do łączenia ciągów, nadal otrzymamy wartości null .
String[] values = {"https", "://", "gist.", "github", ".com", null};
String result = String.join("", values);
Wynik jest taki sam:
https://Gist.github.comnull
Jak więc rozwiązać ten problem? Istnieje kilka rozwiązań. Aby ułatwić późniejszą demonstrację kodu, wyodrębniamy metodę, która może przekazać ciąg znaków i zwrócić ciąg inny niż null.
public String nullToString(String value) {
    return value == null ? "" : value;
}

1. String.concat()

String.concat() to metoda dostępna w klasie String . Jest to bardzo wygodne w przypadku łączenia ciągów.
for (String value : values) {
    result = result.concat(getNonNullString(value));
}
Ponieważ wywoływana jest metoda nullToString() , w rezultacie nie powstają wartości null .

2. Kreator ciągów

Klasa StringBuilder udostępnia wiele przydatnych i wygodnych metod konstruowania ciągów. Najczęściej stosowaną wśród nich jest metoda append() , która wykorzystuje funkcję append() do łączenia ciągów znaków i jest połączona z metodą nullToString() w celu uniknięcia wartości null .
String[] values = {"https", "://", "gist.", "github", ".com", null};
StringBuilder result = new StringBuilder();

for (String value : values) {
    result = result.append(nullToString(value));
}
W rezultacie możesz uzyskać następujący wynik:
https://gist.github.com

3. Klasa StringJoiner (Java 8+)

Klasa StringJoiner zapewnia bardziej zaawansowaną funkcję łączenia ciągów. Może nie tylko określić ogranicznik podczas łączenia, ale także określić przedrostek i przyrostek. Podczas łączenia ciągów możemy użyć metody add() . Aby uniknąć wartości null , zostanie tu również zastosowana metoda nullToString() .
String[] values = {"https", "://", "gist.", "github", ".com", null};
StringJoiner result = new StringJoiner("");

for (String value : values) {
    result = result.add(nullToString(value));
}

4. Filtr strumieni (Java 8+)

Stream API to zaawansowana klasa operacji na strumieniach wprowadzona w języku Java 8, która może wykonywać standardowe operacje filtrowania, dopasowywania, przeglądania, grupowania, statystyki i inne operacje.
  • Filtr działania filtra może otrzymać funkcję predykatu .
  • Interfejs funkcji Predicate jest taki sam, jak wprowadzony wcześniej interfejs Function .
  • To jest funkcjonalny interfejs.
  • Może przyjmować parametr ogólny <T> , a zwracana wartość jest typu logicznego.
  • Predykat jest często używany do filtrowania danych .
Możemy więc zdefiniować predykat , który będzie sprawdzał ciąg zerowy i przekazywać go do metody filter() z API Stream. Ponadto można użyć metody Collectors.joining() w celu połączenia pozostałych ciągów znaków innych niż null.
String[] values = {"https", "://", "gist.", "github", ".com", null};

String result = Arrays.stream(values)
    .filter(Objects::nonNull)
    .collect(Collectors.joining());

5. Użyj operatora +

Użycie operatora + może również rozwiązać problem, ale nie jest zalecane. Wiemy, że String jest obiektem niezmiennym. Użycie znaku + często powoduje utworzenie obiektu typu string i za każdym razem, gdy w pamięci tworzony jest nowy ciąg, więc zużycie wydajności podczas używania znaku + do łączenia ciągów jest bardzo wysokie.

Wniosek

W tym artykule przedstawiono kilka metod łączenia ciągów i obsługi wartości NULL, przy czym różne metody mogą być odpowiednie w różnych scenariuszach. Z analizy wynika, że ​​wydajność StringBuilder jest najlepsza. Ale w rzeczywistych warunkach trzeba połączyć pewne scenariusze, a następnie wybrać metodę z najmniejszą utratą wydajności.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION