Lambda - porównanie Stringa za pomocą == zwraca poprawny wynik

Lambda - porównanie Stringa za pomocą == zwraca poprawny wynik
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:2 dni
  • Lokalizacja:Futurama
  • Postów:887
0

Witajcie!

Kończę ogarniać lambdę i mam do was wszystkich pytanie względem przykładu z książki (który już przybliżam).

Mam taki oto interfejs.

Kopiuj
public interface MyFunc<T> {
	int func(T[] vals, T t);
}

Taką klasę

Kopiuj
public class MyArrayOps {
	
	static <T> int countMatching(T[] vals, T v) {
		int count = 0;
		
		for (int i = 0; i < vals.length; i++) {
			if (vals[i] == v) {
				++count;
			}
		}
		return count;
	}
}

Oraz klasę wykonawczą

Kopiuj
public class GenericMethodRefDemo {
	
	static <T> int myOp(MyFunc<T> f, T[] vals, T v) {
		return f.func(vals, v);
	}
	
	public static void main(String[] args) {
		Integer[] vals = {1,2,3,4,2,3,4,4,5};
		String[] strs = {"Jeden", "Dwa", "Trzy", "Dwa"};
		
		int count;
		
		count = myOp(MyArrayOps::countMatching, vals, 4);
		System.out.println(count);
		count = myOp(MyArrayOps::countMatching, strs, "Dwa");
		System.out.println(count);
	}
}

Moje pytanie brzmi: dlaczego podając tablicę obiektów String i osobny obiekt typu String, czyli ta linijka

Kopiuj
count = myOp(MyArrayOps::<String>countMatching, strs, "Dwa");

zwraca poprawny wynik? W końcu metoda countMatching porównuje obiekty za pomocą operatora ==, co normalnie porównałoby referencje...
Czy lambda wnioskując typ podanych obiektów korzysta niejawnie z metody equals przy użyciu operatora ==?


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
edytowany 1x, ostatnio: Burdzi0
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
1

Niesłusznie zakładasz, że referencje są różne.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:2 dni
  • Lokalizacja:Futurama
  • Postów:887
0

@bogdans: Ale jak to? O.o
Czy taka sama referencja nie byłaby, gdybym wykorzystał coś takiego?:

Kopiuj
count = myOp(MyArrayOps::countMatching, strs, strs[1]);

Rozwiń, jeśli możesz, bo już kompletnie zgłupiałem... (zwłaszcza, że to przykład z kompendium Herberta Schildta przepisany jota w jotę)


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
1

Tak działa kompilator - jeśli dostrzeże dwa identyczne Stringi (a przy tworzeniu drugiego nie ma operatora new), to nie tworzy dwóch różnych obiektów.

Kopiuj
String a = "dwa";
String b = "dwa";
//porównanie a == b zwraca true
String c = new String("dwa");
//porównanie a == c zwraca false
String d = new String("dwa").intern();
//porównanie a == d zwraca true

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:2 dni
  • Lokalizacja:Futurama
  • Postów:887
0

Rzeczywiście, masz rację...
Czy to oznacza błąd w książce?


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

O jaki błąd pytasz?


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:2 dni
  • Lokalizacja:Futurama
  • Postów:887
0

Już nie ważne, już (chyba) ogarnąłem, że jego celem było porównanie referencji, a nie wartości obiektu (bo tak jest, prawda?)


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
edytowany 1x, ostatnio: Burdzi0
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@Burdzi0 w 99% przypadków chcesz porównywać wartości a nie referencje. No i pamiętaj że String w javie, tak samo jak np. Integer maja pewien wewnętrzny cache, wiec obiekty tworzone przez valueOf() mogą być tymi samymi obiektami. To nie jest problem bo te obiekty i tak są immutable -> zmiana stringa powoduje utworzenie nowego.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:2 dni
  • Lokalizacja:Futurama
  • Postów:887
0
Shalom napisał(a):

No i pamiętaj że String w javie, tak samo jak np. Integer maja pewien wewnętrzny cache, wiec obiekty tworzone przez valueOf() mogą być tymi samymi obiektami. To nie jest problem bo te obiekty i tak są immutable -> zmiana stringa powoduje utworzenie nowego.

Tego nie wiedziałem, dzięki :)


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:4 minuty
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

I tu jako uzupełnienie ciekawa metoda z klasy String
intern

Przydaje się raz na piętnaście lat.


jeden i pół terabajta powinno wystarczyć każdemu
S9
To już wiem czemu jej nie wykorzystałem - bo programuje tylko 3 lata w Javie

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.