86
\$\begingroup\$

Are there any useful shortcuts that can be used in Java?

As shown below, import already adds at least 17 characters to a program.

import java.io.*;

I understand that the simple solution would be to use another language, but it seems to be a real challenge to shorten Java programs.


Tips should be specific to Java: if they're applicable to most C-like languages, they belong in the more general list of tips.

\$\endgroup\$
  • 9
    \$\begingroup\$ package can be skipped. \$\endgroup\$ – st0le Jul 19 '12 at 7:08
  • \$\begingroup\$ In an answer, can't I just omit the imports assuming they are there? \$\endgroup\$ – Fabricio May 8 '14 at 15:24
  • 1
    \$\begingroup\$ @Fabricio Not unless the OP specifies so. \$\endgroup\$ – nyuszika7h Sep 26 '14 at 18:49
  • 32
    \$\begingroup\$ Best tip about golfing Java: don't use it. ;) \$\endgroup\$ – kirbyfan64sos Sep 25 '15 at 19:10
  • 4
    \$\begingroup\$ "I want to golf in java" good luck \$\endgroup\$ – sagiksp May 4 '17 at 7:11

38 Answers 38

4
\$\begingroup\$

If you use Java 8, then you can:

Replace Lambda expressions with method references

Lambda expressions can be replaced with method references. Method reference has following form:

ClassName::methodName

so if you use one letter names for classes it's shorter then lambda. Here are the rules

lambda form                  |  reference method form
-------------------------------------------------------------------------------------------------
p -> ClassName.methodName(p) |  ClassName::methodName
p -> new ClassName(p)        |  ClassName::new
p -> p.methodName()          |  ClassName::methodName // where ClassName is class of object p
(p, q) -> p.methodName(q)    |  ClassName::methodName // where ClassName is class of object p

Examples (respectivly):

lambda                       |  reference method
-------------------------------------------------------------------------------------------------
p -> System.out.println(p)   |  System.out::println
p -> new HashSet<>(p)        |  HashSet::new
p -> p.getName()             |  Beer::getName 
(p, q) -> p.compareTo(q)     |  String::compareTo

So, if ClassName is "C", then we have following length diffs:

lambda form                  |  reference method form | length diff
-----------------------------------------------------------------------
p->C.methodName(p)           |  C::methodName         | 5 bytes
p->new C(p)                  |  C::new                | 5 bytes
p->p.methodName()            |  C::methodName         | 4 bytes
(p,q)->p.methodName(q)       |  C::methodName         | 9 bytes

Simplify lambda expressions

And here are some rules of simplifying lambda expressions.

General form of lambda expression is

(parameters) -> { statements;}  // (String a, String b) -> {return a.compareTo(b);}

When there is only one expresion, it can be simplified as follows (return should me ommitted):

(parameters) -> expression      // (String a, String b) -> a.compareTo(b)

When type declaration can be ommited, it can be simplified as follows:

(parameters) -> expression      // (a, b) -> a.compareTo(b)

When there is only one parameter and there is no need to declare type, it can be simplified as follows:

parameter -> expression         // (String s) -> System.out.printout(s)
                                // to
                                // s -> System.out.println(s)
\$\endgroup\$
4
\$\begingroup\$

Use new Stack() when you need basic List functionality

When you need a java.util.List (for example when you want to .add(Object), .remove(Object), java.util.Collections.shuffle(java.util.Collection), etc.), I used to use java.util.ArrayList in most of my answers. But I was recently tipped to use java.util.Vector instead, and java.util.Stack is even shorter:

import java.util.*;

List a=new ArrayList();   // 23 bytes
List b=new Vector();      // 20 bytes
List c=new Stack();       // 19 bytes
\$\endgroup\$
4
\$\begingroup\$

Using Java Applet can save you a lot of space:

import java.applet.Applet;

public class B extends Applet{
    public B(){
        System.out.print("Hello world!");
    }
}

Output:

Hello world!

Also this can be even more shorten by making B to extends nothing.

public class B{
    public B(){
        System.out.print("Hello world!");
    }
}

How ever in additional to desired output we will also get exception:

Output:

Hello world!
java.lang.ClassCastException: B cannot be cast to java.applet.Applet
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Also you can combine this with constructor block and save another 10 bytes like this:

public class B{
    {
        System.out.println("Hello world!");
    }
}

Same output with exception as above.

\$\endgroup\$
  • \$\begingroup\$ One could argue that in case of an applet the HTML page in which it is embedded should count too. \$\endgroup\$ – Paŭlo Ebermann Feb 17 '18 at 16:43
  • \$\begingroup\$ @PaŭloEbermann Html page is the output of the program, here we are talking about the source code \$\endgroup\$ – Ilya Gazman Feb 17 '18 at 17:43
  • \$\begingroup\$ Did applets change so much since I used them 20 years ago? Back then, you had a HTML document with an <applet class=...>...</applet> in it, which, when opened in a web browser, would execute the applet. The result of your System.out could appear in a Java console, but not in the HTML page itself. (You could some APIs to execute Javascript in the browser, thereby changing the page, but that is not what you are showing here.) \$\endgroup\$ – Paŭlo Ebermann Feb 17 '18 at 17:54
  • \$\begingroup\$ @PaŭloEbermann Well you said it, this is definitely not the intended way of using applets, but if it's sufficient for your program to print to stdin and it can ignore the stderr than you can use my suggestion. Obviously, it will not print anything to a web page. \$\endgroup\$ – Ilya Gazman Feb 18 '18 at 0:41
2
\$\begingroup\$

Use String#isEmpty()

To check if a String is empty, you could use either of these:

s.length()<1  // 12 bytes
s.equals("")  // 12 bytes

However, using .isEmpty() is one byte shorter:

s.isEmpty()   // 11 bytes

Note that for Lists it's still shorter to check the size instead of using isEmpty():

l.size()<1    // 10 bytes
l.isEmpty()   // 11 bytes
\$\endgroup\$
  • 1
    \$\begingroup\$ I don't really know Java that well but can't you just use s=="" \$\endgroup\$ – Johan du Toit May 4 '17 at 15:28
  • 1
    \$\begingroup\$ @JohanduToit In Java unfortunately not. String is an Object, and since Java is passed-by-reference, s and "" doesn't point to the same reference, even if they have the same value. So new String("test") == "test" returns false, and new String("test").equals("test") returns true. String literals are an exception to this rule, so "test" == "test" will return true, because the compiler references to the same spot in the background. Perhaps better explained here or .equals in general here \$\endgroup\$ – Kevin Cruijssen May 4 '17 at 18:09
  • \$\begingroup\$ @JohanduToit You could do s.intern()=="" to force Java to replace it with the equivalent object from the string pool, but that's 14 bytes, not really an improvement over the other methods. \$\endgroup\$ – AJMansfield Feb 14 '18 at 20:44
  • \$\begingroup\$ @KevinCruijssen [...] since Java is passed-by-reference [...] -- more importantly since Java does not allow operator overloading and defines equality as identity. \$\endgroup\$ – Jonathan Frech Sep 26 '18 at 14:26
2
\$\begingroup\$

Shortest full program templates.

Introduction

The Java spec never ever say that a full program must contain a main method. It only says:

The Java Virtual Machine starts execution by invoking the method main of some specified class, passing it a single argument, which is an array of strings.

So to the best of our efforts, we can define a Java program as something which when invoked in this way will provide an output:

$ javac A.java
$ java A

All the following templates do that.

Java 8 (42 bytes)

interface A{static void main(String[]a){/* Your code here */}}

Java 7 (45 bytes)

class A{public static void main(String[]a){/* Your code here */}}

Java 5, 6 (12 or 27 bytes)

enum A{A;{/* Your code here */}}

This code above will write something on stderr. Usually something like java.lang.NoSuchMethodError: main\nException in thread "main". If you can write on stderr after execution, use this!

enum A{A;{/* Your code here */System.exit(0);}}

This code above is longer (27 bytes), but it will execute your code and avoid writing anything on stderr.

Conclusion

  1. Don't ever use Java 7.
  2. If your program can be written in Java 5 or 6, use it. If your program can be written in Java 5 or 6, but is longer than a Java 8 version, always check if it could be shorter to write it in Java 5 or 6.
\$\endgroup\$
2
\$\begingroup\$

Bit twiddling actions

Swap variables

You might want to swap int and long variables. The usual way is to have a temporary variable:

void swap(int a, int b) {
  int t=a;a=b;b=t;     //  16 bytes
  System.out.printf("a=%d, b=%d%n", a, b);
}

But you can shorten it like this:

void swap(int a, int b) {
  a^=b^(b=a);          // 11 bytes
  System.out.printf("a=%d, b=%d%n", a, b);
}

Even if you reuse a temporary variable, it's just shorter to write that code, no matter the length of each variable name.

Does work with short and byte but at the cost of casting.

Swap the variables so that the min is in a specific variable and the max is in the other

You have a and b and you don't know which is greater. But you want a to contain the lowest and b to contain the greatest.

void swapMinMax(int a, int b) {
  a^=b<a?b^(b=a):0;            // 17 bytes
  System.out.printf("a=%d, b=%d%n", a, b);
}
\$\endgroup\$
1
\$\begingroup\$

Sometimes, you can use lambdas with iterators:

// SUBOPTIMAL: Don't use lambdas here!
Iterator<A>i=a.iterator();for(A x:(Iterable<A>)()->i){if(x==y)break;}return i.hasNext()?i.next():null;
Iterator<A>i=a.iterator();for(;i.hasNext();){if(i.next()==y)break;}return i.hasNext()?i.next():null;
Iterator<A>i=a.iterator();while(i.hasNext()){if(i.next()==y)break;}return i.hasNext()?i.next():null;

// Lambdas save 11 bytes here!
Iterator<A>i=a.iterator();Iterable<A>j=()->i;for(A x:j){if(x==y)break;}for(A x:j){if(x==z)break;}return i.hasNext()?i.next():null;
Iterator<A>i=a.iterator();for(;i.hasNext();){if(i.next()==y)break;}for(;i.hasNext();){if(i.next()==z)break;}return i.hasNext()?i.next():null;
Iterator<A>i=a.iterator();while(i.hasNext()){if(i.next()==y)break;}while(i.hasNext()){if(i.next()==z)break;}return i.hasNext()?i.next():null;
\$\endgroup\$
1
\$\begingroup\$

Use Try it online to share lambdas

If the solution can be writen in a lambda, Try it online can help you format and reduce what characters need to be included in the solution.

See this for an example.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.