Java Programming Tips & Tricks

Tutorialspoint - compile and run code online

2016-12-05 00:00:00 +0000

Over at Tutorialspoint.com they have created a superb well of study material and tools. Most impressive are the online compiler and runtime terminals, dubbed Coding Ground, for a large selection of popular and obscure languages and tools. Here’s an example Java project, based on the previous article on word counting. Click Compile followed by Execute and the output from the snippet will show in the terminal. The data file “words” is included in the project. (Note that these terminal seems to run best in Chrome based browsers, and fails to load in Firefox).

Also worth checking out is their long list of tutorials for everything from Java; other programming languages; to sports and “soft skills”. Especially with the programming tutorials, their embedded online compiler & terminal feels very slick, as seen below.

My personal site fades in comparison, however, my goal is not to offer complete university courses. Remember Java will remain focused on exploration and examples of interesting aspects of the Java language.

Demo project

Tutorial

Word count

2016-11-26 21:22:37 +0000

Here’s another neat streams snippet, which in three lines handles what would take at least two loops in pre-Java 8 code. The task at hand is to count the number of occurrences of each unique word in a file. Given the content shown below, this Bash command line would solve it.

cat words | tr ' ' '\n' | sort | uniq -c

File content:

one two three four
two three four
three four four

Shell output:

  4 four
  1 one
  3 three
  2 two

The Java code follows a similar flow as seen in the pipes above: Read the file, split each line by space, and flatten the result from all lines into a single stream. Finally, the collect() function is used with the groupingBy() helper, to map each token (or word) in the stream (the identity) to its count.

    Map<String, Long> map = Files.lines(path)
        .flatMap(line -> Stream.of(line.split(" ")))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

The Java map will contain the following key-value pairs. Here, the words are also accidentally sorted alphabetically. However, the order is not guaranteed by collect() function, since it returns a HashMap.

  {four=4, one=1, three=3, two=2}

The full listing:

package com.rememberjava.lambda;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Test;

public class WordCount {

  @Test
  public void countWords() throws IOException {
    Path path = Paths.get("com/rememberjava/lambda/words");

    Map<String, Long> map = Files.lines(path)
        .flatMap(line -> Stream.of(line.split(" ")))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

    System.out.println(map);
  }
}

Fun with IO Streams

2016-11-21 14:12:08 +0000

With Java 8, file IO became a pleasure to work with. It was a drastic break from the old verbose syntax and awkward ((line = in.readLine()) != null) and try/try/close idioms. With the new Stream based methods and lambda functions, the IO API becomes more similar to Python in ease of use.

In the code snippet below, all the lines of a file is read, sorted, and printed.

    Path p = Paths.get("/etc/passwd");
    Files.lines(p).sorted().forEach(System.out::println);

The following lines do the same, but break up the in-line method invocations and returned objects, to more clearly see what’s going on.

    Path p = Paths.get("/etc", "passwd");
    Stream<String> lines = Files.lines(p);
    Stream<String> sorted = lines.sorted();
    sorted.forEach(System.out::println);
    lines.close();

Traversing the directory hierarchy is similarly easy and compact:

    Path p = Paths.get("/proc/bus");
    Files.walk(p).forEach(System.out::println);

Finally, here’s an idea for an assertFileEquals() method. It takes two file names, one which is the expected “golden” file which would contain the output from the test. (The example file names below are to make sure the test passes).

  @Test
  public void testGoldenFile() throws IOException {
    assertFileEquals("/proc/cpuinfo", "/proc/cpuinfo");
  }

  private void assertFileEquals(String expectedFile, String actualFile)
      throws IOException {
    String[] actual = readFile(expectedFile);
    String[] expected = readFile(actualFile);

    Assert.assertArrayEquals(expected, actual);
  }

  private String[] readFile(String filename) throws IOException {
    return Files.lines(Paths.get(filename)).toArray(String[]::new);
  }

Finally, here’s the full test file listing.

package com.rememberjava.lambda;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

import org.junit.Assert;
import org.junit.Test;

public class StreamFun {

  @Test
  public void printFile() throws IOException {
    Path p = Paths.get("/etc/passwd");
    Files.lines(p).sorted().forEach(System.out::println);
  }

  @Test
  public void printFileAlternative() throws IOException {
    Path p = Paths.get("/etc", "passwd");
    Stream<String> lines = Files.lines(p);
    Stream<String> sorted = lines.sorted();
    sorted.forEach(System.out::println);
    lines.close();
  }

  @Test
  public void walkDirectories() throws IOException {
    Path p = Paths.get("/proc/bus");
    Files.walk(p).forEach(System.out::println);
  }

  @Test
  public void testGoldenFile() throws IOException {
    assertFileEquals("/proc/cpuinfo", "/proc/cpuinfo");
  }

  private void assertFileEquals(String expectedFile, String actualFile)
      throws IOException {
    String[] actual = readFile(expectedFile);
    String[] expected = readFile(actualFile);

    Assert.assertArrayEquals(expected, actual);
  }

  private String[] readFile(String filename) throws IOException {
    return Files.lines(Paths.get(filename)).toArray(String[]::new);
  }
}

Hello Junit Test!

2016-10-08 12:00:00 +0000

Unit testing can sometimes be like washing the dishes: You know it should be done, that you’ll have to do it eventually, but it can always be postponed. On the other hand, executing your code through unit tests is a great way to verify that it works as expected, in a short amount of time and with little code overhead. Furthermore, writing unit tests is a convenient way to execute any kind of code easily, especially from within a modern IDE, where it is typically easier to run a single test method than a full executable. Many of the examples on this site will use unit tests as the driver.

Test Method

The “Hello World” minimal example of a Junit 4 test method can be seen in the first example below. All it takes, is a method (of any name) annotated with the @Test annotation. Typically, a test method will assert something against expected values, albeit in the examples below this is ineffectual.

package com.rememberjava.junit;

import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class HelloJunit {

  @Test
  public void test() {
    assertTrue(true);
  }
}

Setup and teardown

The anatomy of a test case class is as seen in the following example. Again, the method names are not relevant, and only the annotations indicate at what point they will be executed. All the annotations can appear on multiple methods, and the only additional requirements are that all annotated methods have to be public; and that the before and after class methods have to be static.

package com.rememberjava.junit;

import org.junit.*;

public class JunitTestMethods {

  @BeforeClass
  public static void setUpBeforeClass() {}

  @AfterClass
  public static void tearDownAfterClass() {}

  @Before
  public void setUp() {}

  @After
  public void tearDown() {}

  @Test
  public void test() {}
}

Order of execution

The final example below adds some flesh to the body of each of the methods, and illustrates a few basic principles of how the different methods are used.

  • The annotations indicate the order: BeforeClass, Before, Test, After, AfterClass.
  • BeforeClass and AfterClass methods are run once, while Before and After methods are executed for every Test method.
  • Since the Class level methods are static, any global fields they use also have to be static.
  • The class is re-constructed for every single Test method. This will reset all global fields, as seen in the output below.
  • The order between Test methods is typically chronological as they appear in the file, however, it is good practice not to rely on this. Or rather, Test methods should not depend on each other.
package com.rememberjava.junit;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class JunitTestMethodsOrder {

  private static int a;
  private int b;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    a = 1;
    System.out.println(a + " beforeClass");
  }

  @Before
  public void setUp() throws Exception {
    a++;
    b++;
    System.out.println(a + " setup " + b);
  }

  @Test
  public void firstTest() {
    a++;
    b++;
    System.out.println(a + " first " + b);
    assertTrue(a > 2);
  }

  @Test
  public void secondTest() {
    a++;
    b++;
    System.out.println(a + " second " + b);
    assertFalse(false);
  }

  @After
  public void tearDown() throws Exception {
    a++;
    b++;
    System.out.println(a + " tearDown " + b);
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    a++;
    System.out.println(a + " afterClass");
  }
}

The test case above gives the following output. Notice the static a counter, and the global non-static b counter which is reset.

1 beforeClass
2 setup 1
3 first 2
4 tearDown 3
5 setup 1
6 second 2
7 tearDown 3
8 afterClass

Hello World!

2016-10-08 10:00:00 +0000

To start off, the smallest Java program there is.

class HelloWorld {
  public static void main(String args[]) {
    System.out.println("Hello World!");
  }
}

To compile and run from the command line:

  javac HelloWorld.java
  java HelloWorld
Older posts