Czy są jakieś przydatne skróty, których można używać w Javie?
Jak pokazano poniżej, import
już dodaje co najmniej 17 znaków do programu.
import java.io.*;
Rozumiem, że prostym rozwiązaniem byłoby użycie innego języka, ale skrócenie programów Java wydaje się prawdziwym wyzwaniem.
Wskazówki powinny być specyficzne dla języka Java: jeśli dotyczą większości języków podobnych do języka C, należą do bardziej ogólnej listy wskazówek .
package
można pominąć.Odpowiedzi:
Użyj najnowszej możliwej wersji Java. Java 8 pozwala używać wyrażeń lambda, więc używaj go, jeśli trzeba nawet nic podobnego obiektów funkcjonalnych.
Zdefiniuj skrócone funkcje dla rzeczy, których często używasz. Na przykład masz sto wywołań
exampleClassInstance.doSomething(someParameter)
, zdefiniuj nową funkcjęvoid d(ParameterType p){exampleClassInstance.doSomething(p)}
i użyj jej, aby zapisać sobie kilka znaków.Jeśli używasz określonej długiej nazwy klasy więcej niż raz, na przykład
zamiast tego zdefiniuj nową klasę:
Jeśli używasz tylko jednej konkretnej metody tej klasy (ale nadal musisz ją utworzyć), możesz jednocześnie zdefiniować skróconą wersję wewnątrz nowej klasy.
Użyj parametrów typu funkcji, aby skrócić rzeczy, tam gdzie to możliwe, na przykład:
Użyj
for(;;)
zamiastwhile(true)
.Nie używaj modyfikatorów dostępu, chyba że jest to absolutnie konieczne.
Nie używaj
final
do niczego.Nigdy nie umieszczaj bloku po
for
pętli (ale pętla foreachfor(x:y)
jest inna). Dodatkowe instrukcje powinny być umieszczone wewnątrzfor
samej instrukcji, npfor(int i=0;i<m;a(i),b(++i))c(i);
.Użyj wbudowanego przypisania, inkrementacji, tworzenia instancji. W razie potrzeby używaj anonimowych klas wbudowanych. Zamiast tego użyj lambdas, jeśli to możliwe. Wywołania funkcji Nest. Niektóre funkcje gwarantują, że zwrócą swój obiekt nadrzędny, te faktycznie są nawet przeznaczone do połączenia w łańcuch.
Twoje
main
metodythrows Exception
ich nie łapią.Error
jest krótszy niżException
. Jeśli z jakiegoś powodu naprawdę potrzebujeszthrow
wiadomości na stosie, użyjError
, nawet jeśli jest to całkowicie normalna sytuacja.Jeśli jakiś warunek wymagałby natychmiastowego rozwiązania, użyj
int a=1/0;
zamiastthrow null;
lubSystem.exit(0);
. W czasie wykonywania powoduje to wyrzucenieArithmeticException
. Jeśli masz już w kodzie zmienną numeryczną, użyj jej zamiast tego. (Jeśli już maszimport static java.lang.System.*;
, idź zexit(0);
.)Zamiast implementować interfejsy, na przykład
List<E>
, rozszerz bezpośrednią (lub nie tak natychmiastową, jeśli jest to w ogóle jakąś zaletą) klasę potomną, na przykładAbstractList<E>
, która zapewnia domyślne implementacje większości metod i wymaga tylko implementacji kilka kluczowych elementów.Najpierw wypisz swój kod, używając znaków nowej linii, wcięć i pełnych nazw zmiennych. Gdy masz już działający kod, możesz skracać nazwy, przenosić deklaracje i dodawać metody skrótów. Pisząc go na długo, dajesz sobie więcej możliwości uproszczenia programu jako całości.
Porównaj alternatywne optymalizacje z fragmentem kodu, ponieważ najbardziej optymalna strategia może się radykalnie zmienić przy bardzo niewielkich zmianach w kodzie. Na przykład:
Arrays.sort(a)
, najbardziej skutecznym sposobem jest wywołanie go z jego nazwy w pełni kwalifikowanejjava.util.Arrays.sort(a)
.void s(int[]a){java.util.Arrays.sort(a);}
. W tym przypadku nadal powinno się używać pełnej nazwy. (Jeśli potrzebujesz więcej niż jednego przeciążenia, prawdopodobnie robisz to źle).for
pętli podczas gry w golfa, przy braku łatwo dostępnej metody bibliotecznej), możesz skorzystać zArrays.copyOf
zadania. Gdy używana jest więcej niż jedna metoda, a są 3 lub więcej wywołań, wykonywanieimport static java.util.Arrays.*;
jest najbardziej efektywnym sposobem odwoływania się do tych metod. Następnie, tylko jeśli masz więcej niż 8 osobnych połączeń,sort
powinieneś użyć do tego metody skrótu i tylko przy 5 lub więcej połączeniach jest to uzasadnione skrótemcopyOf
.Jedynym prawdziwym sposobem przeprowadzenia takiej analizy kodu jest faktyczne wykonanie potencjalnych modyfikacji na kopiach kodu, a następnie porównanie wyników.
Unikaj używania
someTypeValue.toString();
metody, zamiast tego po prostu dołączsomeTypeValue+""
.Jeśli potrzebujesz systemu Windows, nie używaj Swinga, użyj AWT (chyba że naprawdę potrzebujesz czegoś od Swinga). Porównaj
import javax.swing.*;
iimport java.awt.*;
. Dodatkowo, składniki Swing posiadaJ
dołączany do ich nazwy (JFrame
,JLabel
itp), ale składniki AWT nie (Frame
,Label
itp)źródło
Użyj
interface
zamiastclass
.W java 8 do interfejsów dodano metody statyczne. W interfejsach wszystkie metody są domyślnie publiczne. w konsekwencji
można teraz skrócić do
który jest oczywiście krótszy.
Na przykład skorzystałem z tej funkcji w Hello, World! wyzwanie.
źródło
Za pomocą varargs możesz „rzutować” parametr na tablicę tego samego typu:
zamiast
źródło
Ze statycznym importem :
możesz później zapisać jakiś szablon, ale potrzebujesz wielu inwokacji, aby osiągnąć wypłatę:
źródło
Java
!import static java.lang.System.*
.var o=System.out;
czego trzeba użyć tylko dwa razy, zanim się opłacivar o=System.out.println
działałoby?Argumentu do
main
nie trzeba wywoływaćargs
, a można wyciąć białe znaki:zrobi dobrze.
źródło
Jeśli kiedykolwiek będziesz musiał użyć wyrażeń boolowskich
true
lubfalse
, zamień je odpowiednio na1>0
i1<0
.Na przykład:
Ten przykład wyszukiwania liniowego można zredukować do
źródło
true/false
, po prostu dodajboolean t=1>0,f=1<0;
. Następnie zamiast1>0
, użyjt
i zapisz dwa znaki na użycie. Wypłata za1>0
metodę następuje przy 10 zastosowaniach.boolean t=1>0,f=!t;
- o jeden char krótszy!true
/false
bezpośrednio:f|=a[i++]==42;
dużo oszczędza.boolean
, ale ponieważ nie mogłem wymyślić żadnych przykładów w momencie pisania (zwykle nie koduję w Javie), po prostu napisałem prosty przykład.Jeśli zamierzasz często używać jakiejś metody, przypisz jej klasę rezydentną do zmiennej. Na przykład przypisz
System.out
do zmiennej:Także dla
Integer.parseInt()
:To prawie na pewno wywoła ostrzeżenie ide o „dostępie do metody statycznej ze zmiennej”
źródło
((Integer)1).parseInt("1")
też działa.new Integer("1")
jest jeszcze krótszy. Ale Justin miał na myśli swoją odpowiedź, że możesz ponownie wykorzystywać zmienne, które już masz, do wywołań statycznych. Jak wyjaśniam na dole tej odpowiedzi.Zamiast korzystać z
import static java.lang.System.*
techniki zapisywaniaprintln()
instrukcji, odkryłem, że zdefiniowanie następującej metody jest znacznie bardziej skuteczne w zapisywaniu znaków:Wynika to z faktu, że można go przywoływać,
p(myString)
aout.println(myString)
nie o wiele szybciej i bardziej dramatycznie.źródło
Może się to wydawać oczywiste, ale dla niektórych
Math
funkcji dostępne są krótsze opcje :źródło
Jeśli potrzebujesz
Integer.MAX_VALUE
(2147483647), użyj-1>>>1
.Integer.MIN_VALUE
(-2147483648) jest lepiej napisany1<<31
.źródło
Jeśli chcesz pobrać liczbę z argumentu (lub dowolnego innego ciągu), zwykle widzisz coś takiego:
Wiele razy, nie trzeba
Integer
. Wiele wyzwań nie wykorzystuje dużych liczb. PonieważShort
iByte
oba rozpakują się naint
, użyjvalueOf()
zamiast tego bardziej odpowiedniego i zapisz kilka bajtów.Zachowaj jednak rzeczywistą zmienną jako
int
, ponieważ jest krótsza niż obiebyte
ishort
:Jeśli musisz to zrobić dla wielu numerów, możesz połączyć z tą metodą :
źródło
int n=new Byte(a[0]);
jest trzy razy krótszy. Jeśli liczba może być większa, użyjlong n=new Long(a[0])
,int
w większości przypadków nadal jest lepsza niż s.Nie używać
public class
. Główna metoda musi być publiczna, ale jej klasa nie. Ten kod działa:Możesz biegać,
java S
nawet jeśliclass S
nie jest to klasa publiczna. ( Aktualizacja: Kiedy pisałem tę wskazówkę, korzystałem z Java 7. W Javie 8 twoja główna metoda powinna być w interfejsie . W Javie 5 lub 6 twoja główna metoda powinna być wyliczona .)Wielu programistów Java tego nie wie! Około połowa odpowiedzi na pytanie przepełnienia stosu dotyczące main w klasie niepublicznej błędnie twierdzi, że główna metoda musi być w klasie publicznej. Teraz wiesz lepiej. Usuń
public
inpublic class
i zaoszczędzić 7 znaków.źródło
interface s{static void main(String[]...
jest krótsza. Jeśli potrzebujesz kompilowalnego pliku źródłowego i głównej metody. Ponieważ w interfejsie Java 1.8 wszystkie metody są publiczne, więc można pominąć modyfikator metody.Kilka małych wskazówek do gry w golfa
Te wskazówki były trochę za małe, aby rozdzielić odpowiedzi, więc wykorzystam tę odpowiedź do bardzo małych wskazówek dotyczących kodowania, które znalazłem lub wymyśliłem i nie zostały jeszcze wspomniane w innych poradach:
Usuwanie ostatniego znaku ciągu:
W niektórych przypadkach wiesz wcześniej, jaki jest ostatni znak, a także wiesz, że ta postać występuje tylko raz w ciągu. W takim przypadku możesz
.split
zamiast tego użyć :Skróty kodowania:
Wszystkie kodowania mają kanoniczną nazwę używaną w
java.nio
interfejsie API, a także kanoniczną nazwę używaną w interfejsach APIjava.io
ijava.lang
. Oto pełna lista wszystkich obsługiwanych kodowań w Javie. Dlatego zawsze używaj najkrótszego z dwóch; drugi jest zwykle krótszy (jakUTF-8
vsutf8
,Windows-1252
vsCp1252
itp.), ale nie zawsze (UTF-16BE
vsUnicodeBigUnmarked
).Losowa wartość logiczna:
Liczby pierwsze:
Istnieje wiele różnych sposobów sprawdzania liczb pierwszych lub uzyskania wszystkich liczb pierwszych, ale odpowiedź @ SaraJ tutaj jest najkrótsza. Oto kopia-wklej jako odniesienie:
UWAGA: Zwykle możesz połączyć go z innymi istniejącymi pętlami, w zależności od tego, jak chcesz go używać, więc nie będziesz potrzebować oddzielnej metody. Na przykład zaoszczędziło to wiele bajtów w tej odpowiedzi .
Obcinanie liczb całkowitych zamiast Math.floor / Math.ceil:
Jeśli używasz dodatnich podwójnych / zmiennoprzecinkowych i chcesz
floor
ich, nie używaj,Math.floor
ale(int)
zamiast tego użyj -cast (ponieważ Java obcina się na liczbach całkowitych):Tę samą sztuczkę można zastosować do ujemnych podwójnych / zmiennoprzecinkowych, które chcesz
ceil
zamiast tego:Użyj
&1
zamiast%2
pozbyć się nawiasu:Ponieważ Operator Pierwszeństwo od
&
jest niższa niż standardowych operatorów arytmetycznych, jak*/+-
i%
można pozbyć się nawiasów w niektórych przypadkach.Zauważ, że to naprawdę nie pomaga w kontrolach boolean, ponieważ wtedy nadal potrzebujesz nawiasów, są one tylko trochę przesunięte:
BigIntegers i tworzenie zmiennych dla statycznych wywołań metod:
Korzystając z BigIntegers, utwórz go tylko raz, abyś mógł go ponownie użyć. Jak wiadomo, BigInteger zawiera pola statyczne
ZERO
,ONE
aTEN
. Więc kiedy używasz tylko tych trzech, nie potrzebujesz,import
ale możesz użyćjava.Math.BigInteger
bezpośrednio.UWAGA: Musisz użyć,
=null
więct
jest zainicjowany, aby użyćt.
.Czasami możesz dodać wiele BigIntegerów, aby utworzyć kolejny, aby zapisać bajty. Powiedzmy, że chcesz mieć BigIntegers
1,10,12
z jakiegoś powodu:Jak słusznie zaznaczono w komentarzach, sztuczka z
BigInteger t=null;
wywołaniami metody statycznej może być również używana z innymi klasami.Na przykład tę odpowiedź z 2011 r. Można pograć w golfa:
getBytes()
zamiasttoCharArray()
Kiedy chcesz zapętlić znaki ciągu, zwykle robisz to:
Pętlowanie znaków może być przydatne podczas ich drukowania, dołączania do ciągu znaków lub czegoś podobnego.
Jednak, jeśli używać tylko znaków dla niektórych obliczeń numerycznych Unicode można zastąpić
char
zint
I można zastąpićtoCharArray()
zgetBytes()
:Lub jeszcze krócej w Javie 8+:
W Javie 10+ zapętlanie znaku do wydruku można teraz wykonywać również w 22 bajtach:
Losowy przedmiot z
List
:Sprawdź, czy ciąg znaków zawiera spacje wiodące / końcowe
Dlaczego to działa, gdy
!=
w Strings jest sprawdzanie referencji zamiast wartości w Javie? PonieważString#trim
zwróci „ Kopię tego ciągu z usuniętą początkową i końcową białą spacją lub tego ciągu, jeśli nie ma wiodącej ani końcowej białej spacji . ” Użyłem tego, po tym, jak ktoś mi to zasugerował, w tej mojej odpowiedzi .Palindrom:
Aby sprawdzić, czy Ciąg znaków jest palindromem (pamiętając o parzystych i nieparzystych długościach Ciągów), jest to najkrótszy (
.contains
działa tutaj, ponieważ wiemy, że zarówno Ciąg, jak i jego odwrócona postać są równej długości):.contains(...)
zamiast.equals(...+"")
dzięki komentarzowi @assylias tutaj .Albo jest 0, albo oba są 0?
Myślę, że większość już wie to jedno: jeśli chcesz sprawdzić, czy albo
a
czyb
jest zero, zamiast mnożyć zapisać bajtów:A jeśli chcesz sprawdzić, czy oba
a
ib
są zerowe, można użyć bitowym OR, lub dodać je razem, jeśli są zawsze pozytywne:Parzysty = 1, nieparzysty = -1; lub odwrotnie
Powodem, dla którego to dodałem, było po zobaczeniu
k+(k%2<1?1:-1)
w tej odpowiedzi :n
Czasy pętli w pełnym programieJeśli mamy wyzwanie, w którym pełny program jest obowiązkowy i musimy zapętlić określoną liczbę razy, możemy wykonać następujące czynności:
To samo dotyczy sytuacji, gdy musimy przyjąć ten zakres jako dane wejściowe:
Podziękowania dla @JackAmmo w tym komentarzu .
try-wreszcie zamiast try-catch (wyjątek e) podczas powrotu i kiedy go użyć
Jeśli nie możesz użyć,
throws Exception
ale musiszcatch
coś z tym zrobić przed powrotem, możeszfinally
zamiast tego użyć :Jako przykład, kiedy użyć a
try-catch
, mogę odnieść się do mojej odpowiedzi (uznanie dla pośredniego golfa należy do @KamilDrakari ). W tym wyzwaniu musimy zapętlić po przekątnej macierz NxM, więc musimy ustalić, czy liczba kolumn czy liczba wierszy jest najniższa jako nasze maksimum w pętli for (co jest dość drogie pod względem bajtów:)i<Math.min(a.length,a[0].length)
. Więc po prostu złapanieArrayIndexOutOfBoundsException
użyciacatch-finally
jest krótsze niż ta kontrola, a tym samym oszczędza bajty:UWAGA: Działa to tylko z powodu
return r;
w końcu. Sugerowano mi zmodyfikowanie pierwszej komórki, tak jak @KamilDrakari zrobił w swojej odpowiedzi w języku C #, aby zapisać bajty. Jednak w Javie oznacza to, że będę musiał zmienić go nam->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch(Exception e){}}
(73 bajty), faktycznie zwiększając liczbę bajtów zamiast zmniejszać, gdybym mógł użyćfinally
.Math.pow (2, n)
Jeśli potrzebujesz potęgi 2, nieco mądrzejsze podejście jest znacznie krótsze:
Łączenie bitowych i logicznych kontroli zamiast używania nawiasów
Myślę, że do tej pory jest to dobrze znane
&
i|
może być używane zamiast&&
i||
w sprawdzeniach logicznych Java (boolean). W niektórych przypadkach nadal chcesz używać&&
zamiast&
zapobiegać błędom, na przykładindex >= 0 && array[index].doSomething
. Jeśli&&
zmieniono by na&
tutaj, nadal będzie oceniać część, w której używa indeksu w tablicy, powodującArrayIndexOutOfBoundsException
, stąd użycie&&
w tym przypadku zamiast&
.Jak dotąd podstawy
&&
/||
vs&
/|
w Javie.Gdy chcesz to sprawdzić
(A or B) and C
, najkrótsze mogą się wydawać operatory bitowe:Ponieważ jednak operatorzy bitowi mają pierwszeństwo operatorów przed sprawdzeniami logicznymi, możesz połączyć oba te elementy, aby zapisać bajt tutaj:
Użyj
n+=...-n
zamiast(long)...
Kiedy masz zarówno wejście, jak i wyjście w lambda, na przykład podczas używania
Math.pow
, możesz zapisać bajt, używającn+=...-n
zamiast(long)...
.Na przykład:
Ten zapisany bajt w tej odpowiedzi kopalni , a nawet dwa bajty, łącząc
-n-1
się+~n
w tej odpowiedzi kopalni .źródło
positive integers
? Nie jestem też pewien, czy wdrożenie pułapu działa .since Java automatically floors on integers
; Myślę, że właściwym terminem jest obcięcie , a nie podłoga .String t="";for(int i=s.length();--i>=0;t+=s.charAt(i));return s.equals(t);
s.equals(new StringBuffer(s).reverse()+"")
.Do gry w golfa, która nie wymaga danych wejściowych, możesz użyć bloków statycznych i uruchomić ją dobrze bez żadnej głównej metody, po prostu skompiluj ją z Javą 6.
źródło
java
w wierszu poleceń / w pliku manifestu, którą klasę załadować.Wszyscy wiemy o bitowej xor (
^
), ale jest to również logiczna xor.Tak
(a||b)&&!(a&&b)
po prostu się stajea^b
.Teraz możemy użyć XOR.
Dodatkowo operatorzy,
|
a&
także pracują , pamiętajcie tylko, że pierwszeństwo operatorów się zmienia.źródło
&
a|
także. Może to być przydatne, jeśli twoje warunki są już w nawiasach lub jeśli pracujesz już z logicznymi wartościami logicznymi.!=
zamiast^
dla xor, a==
dla xnorNie musisz używać
Character.toLowerCase(char c)
. Zamiast tego użyj(c|32)
. ZamiastCharacter.toUpperCase(char c)
używać(c&~32)
. Działa to tylko z literami ASCII.źródło
c|~32
spowoduje, że -1 ... lepiej użyćc-32
.Konwertuj ciąg na liczbę
Istnieje wiele sposobów konwersji ciągu na wartość liczbową:
ABC.parseABC :
ABC.valueOf :
ABC.decode :
nowe ABC :
W przypadku gry w golfa najlepiej więc użyć konstruktora podczas konwertowania ciągu na wartość liczbową.
To samo dotyczy
Double
;Float
; aByte
.Nie zawsze ma to zastosowanie, gdy można ponownie użyć już istniejącej operacji podstawowej jako obiektu.
Jako przykład załóżmy, że mamy następujący kod:
Możesz użyć
.decode
zamiast krótszego konstruktora, ponownie wykorzystując parametr jako obiekt:źródło
Nie używaj
Random
!Ogólnie rzecz biorąc, jeśli potrzebujesz losowych liczb,
Random
jest to okropny sposób na obejście tego *.Math.random()
Zamiast tego znacznie lepiej jest użyć . Aby użyćRandom
, musisz to zrobić (powiedzmy, że potrzebujemyint
):Porównaj to z:
i:
Pierwsza metoda wymaga
41+15n
znaków (n
to liczba wywołań). Drugi to25n
postacie, a trzeci to43+7n
.Tak więc, jeśli potrzebujesz go tylko raz lub dwa razy, użyj
Math.random()
metody inline . W przypadku trzech lub więcej połączeń zaoszczędzisz za pomocą funkcji. Albo jeden zapisuje znaki na pierwszym użyciu ponadRandom
.Jeśli używasz już
Math.random()
dladouble
pamiętać, że w czterech zastosowań, to wciąż oszczędności go wyciągnąć na:Za 33 znaki zaoszczędzisz 10 na każdym połączeniu z
r()
Aktualizacja
Jeśli potrzebujesz liczby całkowitej i chcesz zaoszczędzić na przesyłaniu, nie przesyłaj jej! Automatyczne rzutowanie Java, jeśli wykonasz operację zamiast przypisania. Porównać:
* Chyba że musisz zasiać PRNG, aby uzyskać przewidywalne wyniki. W takim razie nie widzę większego rozwiązania.
źródło
Random#nextGaussian
.(int)(Math.random()*9)
ma bardzo małe odchylenie modulo, ponieważMath.random()
zwraca 2 53 możliwe wartości, a 2 53 nie jest wielokrotnością 9. Prawdopodobieństwo każdej liczby jest w zakresie 1/9 plus lub minus 5 / (9 * 2 ** 53), błąd tak mały, że prawie dokładnie 1/9.9
tylko jako przykładu, może to być wszystko. Jestem względnie pewien, żenextInt()
(lub jakakolwiek innaRandom
metoda) ma również niewielkie uprzedzenie, tylko ze względu na działanie PRNG Java.new java.util.Random().nextBoolean()
możesz użyćMath.random()<.5
.Nie wiem, czy uważasz tę „czystą” Javę, ale Przetwarzanie umożliwia tworzenie programów z niewielką początkową konfiguracją (zakończoną automatycznie).
W przypadku wyjścia z konsoli możesz mieć coś tak prostego, jak:
dla wyjścia graficznego, trochę więcej:
źródło
size
; domyślnie będzie to kwadrat o wymiarach 100 na 100 pikseli. W większości systemów operacyjnych ramka wokół niego będzie około dwa razy większa, z kwadratem wyśrodkowanym, a reszta obszaru będzie wypełniona treścią pobraną z pulpitu.setup()
idraw()
użyć „trybu statycznego”. Możesz także użyć 6-cyfrowych kolorów szesnastkowych, a tłumacz je zmieni, co czasem się opłaca (#FF8000
<255,128,0
), a jeśli używasz skali szarości, musisz podać tylko jedną liczbę (255
<255,255,255
)Skrócenie powrotu
Możesz skrócić instrukcje zwrotne ciągów o bajt za pomocą:
do
A jeśli zdarzy się, że zaczniesz zwrot w nawiasie, możesz zrobić z nimi to samo:
do
Myślę, że cytaty są traktowane jak nawiasy? Właściwie to podniosłem to przez AppleScript i pomyślałem, że warto o tym wspomnieć.
źródło
return-n;
zamiastreturn -n;
lubreturn~n;
zamiastreturn ~n;
. Oprócz singli zamiast podwójnych cytatów:return'A';
Nie bój się używać notacji naukowej
Jeśli masz do czynienia z liczbami podwójnymi lub zmiennoprzecinkowymi, możesz użyć notacji naukowej dla liczb. Zamiast pisać
double a=1000
, możesz zmienić go nadouble a=1e3
1 bajt.źródło
Spróbuj użyć
int
zamiastboolean
W niektórych przypadkach stwierdziłem, że krótsze jest zwrócenie wartości całkowitej z metody, która normalnie zwróciłaby wartość logiczną, podobnie jak w programach C.
Zaraz nietoperz
int
jest o 4 bajty krótszy niżboolean
. Za każdym razem, gdy piszeszreturn 0
zamiastreturn 1<0
, zapisujesz dodatkowe 2 bajty i to samo nareturn 1
ponadreturn 1>0
.Pułapka polega na tym, że za każdym razem, gdy chcesz użyć wartości zwracanej bezpośrednio jako logicznej, kosztuje ona 2 bajty (
if(p(n))
v.if(p(n)>0)
). Można to uzupełnić za pomocą arytmetyki logicznej. Biorąc pod uwagę wymyślony scenariusz, w którym chcesz pisaćmożesz zamiast tego pisać
w celu zaoszczędzenia 2 bajtów.
źródło
0
i1
nie stanowią one fałszu / prawdy w Javie (a JLS też nie uważa ich w ten sposób). Jeśli więc golf pyta się o prawdę / fałsz, musisz to zrobić w trybie booleanizowanym (i, niestety, włączyćboolean
funkcję, dodając do tego jeszcze więcej bajtów).t[0]+=p(n):10?0;
Czy to w ogóle jest ważne?t[0]+=p(n)?10:0;
. (Zredagowałem to.)Jeśli użyjesz enum zamiast klasy , zapisujesz jedną postać.
Ale musisz wprowadzić co najmniej jedną instancję wyliczenia (F, G, H w tym przykładzie), która musi się spłacić.
źródło
enum M{;public static void main(String[]a){...}
bez problemów.class M{
ma dokładnie taką samą długość jakenum M{;
. W takim razie wybrałbym to,class
ponieważ jest ładniejsze (IMO)enum{
pracował bez;
; to tylko IDE jęczy, że jest błąd, ale kompilator to akceptujeGdy masz metodę, która powinna zwrócić a
boolean
lubBoolean
, tj .:Możesz zmienić typ
boolean
/Boolean
return,Object
aby zapisać 1 bajt:Ponadto, jak być może zauważyłeś, możesz użyć
<1
czeku zamiast==0
zapisać bajt. Chociaż jest to bardziej ogólna wskazówka dotycząca golfa zamiast specyficznych dla Javy.Jest to najczęściej używane, gdy liczba całkowita nie może być ujemna, na przykład sprawdzanie długości:
zamiast
źródło
c(-21)
wracatrue
z bieżącym.c(-20)
zamiast-21
?-21 % 5 = 4
a-20 % 5 = 0
.-21
.-21 % 5 != 4
w Javie, o co mi chodzi. Podzielna przez pięć funkcji będzie działać prawidłowo, jeśli moduł zawsze zwrócony nieujemna, ale tak nie jest. Zobacz ten przykładowy fragment .%
, więc zapomniałem, że Java zwraca resztę zamiast modułu, stąd różnica.Jak rysować w Javie ...
Oto najkrótsza możliwa płyta kotła lakierniczego GUI:
Grał w golfa za 111 bajtów:
źródło
Unikaj
StringBuilder
sDołączanie rzeczy do
String
zajmuje dużo mniej bajtów.Jeśli musisz odwrócić ciąg i wydrukować go od razu, użyj
StringBuffer
.Jeśli musisz odwrócić ciąg, a następnie zrobić coś innego niż wydrukowanie, użyj
for
każdej pętli.źródło
StringBuffer
dla łańcuchów odwracających.String b="";for(char c:"Hello, World!".toCharArray()){b=c+b;}
{}
pętlę foreach, jeśli zamierzasz użyć tej metody.String s:"".split("")
zamiastchar c:"".toCharArray()
.java.util.stream.Stream
już zaimportowałeś i jeśli chcesz połączyć kolejne wywołanie wyniku (jakB.chartAt(42)
) lub jeśli chcesz tylko przekazać wynik do funkcji (jakf(B)
), to użyciefor(:)
jest równeStream.of("Hello, World!".split("")).reduce("",(a,b)->b+a)
.String b=new StringBuffer("Hello, World!").reverse()+"";
(.toString
zastąpiony przez+""
), a twój drugi wiersz może być:String B="";for(String c:"Hello, World!".split(""))B=c+B;
(char
doString
i.toCharArray()
do.split("")
).Użyj Java 10
var
Jeśli zdefiniujesz pojedynczą zmienną określonego typu, użyj
var
.Przykłady
Nie można użyć w żadnym z poniższych przykładów
var
nie można użyć w wielu przykładachźródło
W większości przypadków twój program będzie jednowątkowy, tzn. Będzie działał tylko jeden wątek. Możesz wykorzystać ten fakt,
return
wchodząc z głównej metody, gdy musisz natychmiast wyjść.Porównaj to z „prawidłowym” zakończeniem programu:
Lub wskazując na
null
:Lub dzieląc przez 0:
źródło
Czasami pojedyncza instrukcja dla pętli może być wymienna. Rozważ następujący kod:
Jest to prosta pętla for będąca rozwiązaniem tego pytania .
Ponieważ wiemy, że
i
nie będzie on wystarczająco duży, aby spowodować błędy StackOverflow, możemy zamiast tego zastąpić pętlę for rekurencją:Możemy symulować pętlę za pomocą operatora trójskładnikowego w instrukcji return, aby spowodować rekurencję.
Ta redukcja jest raczej specyficzna, ale mogę sobie wyobrazić więcej sytuacji, w których byłoby to przydatne.
źródło
Wykorzystanie
...
(varags) jako parametruW niektórych przypadkach krócej jest używać varargs Java jako parametru zamiast luźnych.
Na przykład:
Grałby w większość do tego:
Ale można odegrać w tym dodatkowy bajt:
Zauważ, że wszystkie trzy liczby całkowite są dostępne tylko raz w samej metodzie. Ponieważ
int
jest on dość krótki, korzystne jest, jeśli użyjesz ich tylko raz w metodzie i podasz trzy lub więcej z nich jako parametr.Przy dłuższych parametrach jest to zwykle bardziej przydatne. Na przykład, to była moja pierwotna odpowiedź na to wyzwanie (oblicz wystąpienie znaku wejściowego w ciągu wejściowym):
I zalecono mi grę w golfa do tego:
Ale skończyłem grać w golfa przy użyciu
...
:UWAGA: Jeśli pytanie / wyzwanie wymaga elastycznych danych wejściowych,
...
można je[]
oczywiście skrócić . Jeśli pytanie / wyzwanie konkretnie wymaga, powiedzmy, trzechString
danych wejściowych i nie zezwala naString
tablicę zawierającą trzy wartości, możesz użyćString...
zamiastString a,String b,String c
.źródło
String[]
zamiast varargs? (zapisuje jeszcze 1 bajt)