Operator add klasy set zwraca wartość logiczną, która jest prawdą, jeśli element (który ma zostać dodany) jeszcze nie istniał, a fałsz w przeciwnym razie. Pisze
if (set.add(entry)) {
//do some more stuff
}
uważany za dobry styl pod względem pisania czystego kodu? Zastanawiam się, skoro robicie dwie rzeczy naraz. 1) dodanie elementu i 2) sprawdzenie, czy element istniał.
java
coding-style
clean-code
Andreas Braun
źródło
źródło
java.util.Set
, który powraca,add
gdy element nie był jeszcze obecny, prawda?if (!set.add(entry)) {// entry already present, possibly a case you want to handle}
Odpowiedzi:
Tak to jest.
Zazwyczaj operacja zwraca wartość logiczną, ponieważ można jej użyć do podejmowania decyzji, tj. W obrębie
if
konstrukcji. Jedynym innym sposobem, w jaki mógłbyś zrealizować ten potencjał, byłoby przechowywanie wartości zwracanej w zmiennej, a następnie natychmiastowe użycie jej w zmiennejif
, która jest po prostu głupia i na pewno nie jest lepsza od pisaniaif(operation()) { ... }
. Więc po prostu idź i zrób to, nie będziemy cię oceniać (za to).źródło
Set.add
jako pojedynczej operacji bez nazywania alternatywy. Jeśli zamierzoną operacją jest dodanie pojedynczego elementu i sprawdzenie, czy został on dodany, nie ma potrzeby stosowania bardziej wydajnej alternatywy, która nadal komplikuje operację bez korzyści. Mam nadzieję, że wiesz, żeSet.add
jest to wbudowana metoda JRE, której można używać bez wcześniejszego zapoznania się z> 700 stronicową książką.Powiedziałbym, że nie jest tak czysty, jak to możliwe, ponieważ zmusza opiekuna albo już wie, albo sprawdza, co oznacza wartość zwracana. Czy to oznacza, że wartość już istniała, jeszcze nie istniała, została pomyślnie wstawiona? Jeśli nie użyjesz go dużo, nie będziesz wiedział, a nawet jeśli to zrobisz, będzie to o wiele więcej obciążenia psychicznego.
Wolałbym następujące:
Tak, nieco bardziej szczegółowe, ale kompilator powinien generować dokładnie ten sam kod bajtowy, a nawet ludzie, którzy nie używali zestawów Java od lat, mogą podążać za logiką, nie szukając niczego.
źródło
add
zwraca true, jeśli elementu już tam nie było, a nie, jeśli tak było. (Brzmienie pytania jest mylące.)Set.add
, jesteś niedoświadczony i powinieneś szukać tych metod, aby się ich nauczyć i stać się bardziej doświadczonym.notAlreadyPresent
nie jest najlepszym sformułowaniem. Użyłbymadded
i oczekuję, że czytelnik będzie wiedział, dlaczego wartość nie zostanie dodana do zestawu.Jeśli prawda oznacza sukces, to jest to dobry, czytelny kod.
Istnieje powszechna konwencja, że funkcja lub metoda zwraca true (lub coś, co daje wartość true) po sukcesie. Tak długo, jak podąża za tym twój kod, myślę, że umieszczenie metody w warunku jest w porządku.
Moim zdaniem taki kod jest niepotrzebnie zaśmiecony:
Czujesz się, jakbyś się powtarzał.
Pytanie jest jednak dwuznaczne co do znaczenia zwracanej wartości. Mówisz „boolean, który wskazuje, czy dodany element już istniał”, co może sugerować, że prawda oznacza, że element istniał (i dodawanie nie nastąpiło). W takim przypadku idealnie zmieniłbym zachowanie zwrotne metody na bardziej konwencjonalne. Jeśli nie jest to możliwe, dodałbym dodatkową zmienną pośrednią, która pozwala wyraźnie oznaczyć wynik w kodzie (jak sugerują inni).
źródło
false
oznacza, że element nie został dodany, ponieważ był już zawarty, itrue
oznacza, że element nie był już zawarty. Gdyadd()
dodaje element do zestawu, jeśli zestaw jeszcze go nie zawierał,true
oznacza to, że element został pomyślnie dodany do zestawu.add
kończy się sukcesem bez potrzeby robienia czegokolwiek. Jeśli element nie był jeszcze w zestawie,add
sukces polega na dodaniu elementu do zestawu. Która interpretacja jest poprawna, jest arbitralna. Mniej arbitralna definicja sukcesu pochodzi z języka: metoda odnosi sukces, jeśli zwraca normalnie.firstLessThanSecond(int l, int r)
i zwraca ona,true
jeślil > r
lubfalse
jeślil <= r
, to metoda ta nie jest skuteczna, mimo że zwraca normalnie.add
jest surowym skrótem umowy. Dokumentacja zaczyna się od „Dodaje określony element do tego zestawu, jeśli nie jest już obecny”, co jest wystarczające, niezależnie od tego, czy element był już w zestawie. Możesz dowolnie interpretować zwracaną wartość, ale ostatecznie jest to tylko twoja interpretacja. W drugim przykładzie metoda ocenia, czy warunek jest spełniony. Jeśli warunek jest fałszywy, metoda z pewnością nie zawiodła, ponieważ pomyślnie oceniła warunek.Powiedziałbym, że jest bardzo podobny do C. Przez większość czasu wolałbym mieć opisowo nazwaną zmienną dla wyniku mutacji i żadna mutacja nie zachodzi w
if
stanie.Kompilator wyeliminuje tę zmienną, jeśli zostanie natychmiast ponownie wykorzystana. Ludziom łatwiej będzie czytać źródło; dla mnie jest to ważniejsze.
Gdyby ktoś musiał rozszerzyć warunek poprzez dodanie klauzuli
and
/or
do warunku if, może.add()
w niektórych przypadkach nie zadzwonić z powodu oceny zwarcia. O ile nie przewiduje się zwarcia, może to być błąd.źródło
if (set.contains(entry)){set.add(entry); //do more stuff}
czy to również jest eliminowane przez kompilator?contains
iadd
. Ponadto podwójnie sprawdza sięentry
w zestawie; może to odgrywać rolę w przypadku bardzo dużych zestawów i bardzo lekkich pętli.if (set.contains(entry)){set.add(entry); //do more stuff}
a zamiast tego iść np. Z odpowiedzią Karla Bielefeldta?Wygląda na to, że Twój kod przerywa rozdzielanie zapytań poleceń . Jest to omówione w książce Clean Code i wideo Struktury funkcji . Więc z perspektywy Clean Code myślę, że nie jest uważany za dobry styl.
Dla mnie cel twojego kodu jest niejasny. Czy oba są wykonywane, gdy pozycja jest dodawana, czy też już istnieje? Co
add()
zwraca przedmiot? Kod błędu?źródło
if (set.contains(entry)){set.add(entry); //do more stuff}
co wydaje się trochę głupie. Jakie jest twoje zdanie na ten temat?Collection
API.