Category Archives: java

Hosting a Maven repository on github (with sources and javadoc)

How to make a small open sourced library available to other developers via maven? One way is to deploy it on Maven Central Repository. What I’d like to do is to deploy it to github, so I can modify it freely. This post will tell you how to do that.

The typical way I deploy artifacts to a github is to use mvn deploy. Here are steps:

  • Use site-maven-plugin to push the artifacts to github
  • Use maven-javadoc-plugin to push the javadoc
  • Use maven-source-plugin to push the source
  • Configure maven to use the remote mvn-repo as a maven repository

Configure maven-deploy-plugin

First, I add the following snippnet to tell maven to deploy artifacts to a temporary location inside my target directory:

<distributionManagement>
  <repository>
    <id>internal.repo</id>
    <name>Temporary Staging Repository</name>
    <url>file://${project.build.directory}/mvn-repo</url>
  </repository>
</distributionManagement>
<plugins>
  <plugin>
    <artifactId>maven-deploy-plugin</artifactId>
    <version>2.8.1</version>
    <configuration>
      <altDeploymentRepository>
      internal.repo::default::file://${project.build.directory}/mvn-repo
      </altDeploymentRepository>
    </configuration>
  </plugin>
</plugins>

read more

Run Java main from Maven from Command line

Maven exec plugin lets you run the main method of a Java class in your project, with the project dependencies automatically included in the classpath.
This article show you a way of using the maven exec plugin to run java, with code examples.

Complile the code

Since you are not running your code in a maven phase, you first need to compile the code. Remember exec:java does not automatically compile your code, you need to do that first.

read more

Mockito 101

Mockito is a mocking framework that lets you write beatiful tests with clean and simple API. It biases toward minimal specifications, makes different behaviors look different, and displays clear error messages.

Creating Mocks

To create a mock using Mockito, simply annotate mocks with @Mock and call MockitoAnnotations.initMocks(this).

import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class FooClassTest {
  @Mock 
  mockFoo;

  public void setUp() {
    MockitoAnnotations.initMocks(this);
    ...
  }
  ...
}

Stubbing values

Stubbing values can stimulate the behavior of exsiting code or be a temporary substitute for yet-to-be-developed code. By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, …). You can override the stubbing values as below. Once stubbed, the method will always return stubbed value regardless of how many times it is called. For a method with a void return, ususally we do not need to stub it.

import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.when;
...
// a method that returns values
when(mockFoo.someCall()).thenReturn(someValue);
when(mockFoo.someCall()).thenThrow(new FooException());
// a method with a void return
doThrow(new FooException()).when(mockFoo).voidMethodThatThrows();

read more

Remove Duplicates from Sorted Array

Question

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
For example,
Given input array A = [1,1,2],
Your function should return length = 2, and A is now [1,2].

read more

Text Justification

Question

Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ‘ ‘ when necessary so that each line has exactly L characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.

For example,

words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16.

Return the formatted lines as:

[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Note: Each word is guaranteed not to exceed Lin length.

Corner Cases:

A line other than the last line might contain only one word. What should you do in this case?
In this case, that line should be left-justified.

My Solution

  public List<String> fullJustify(String[] words, int L) {
    if (words == null || words.length == 0) {
      return Collections.emptyList();
    }
    List<Line> lines = parseToLines(words, L);
    return fillLines(lines, L);
  }

  private List<String> fillLines(List<Line> lines, int L) {
    List<String> output = new ArrayList<String>();
    for (int i = 0; i < lines.size(); i++) {
      Line line = lines.get(i);
      if (line.wordCount() == 1) {
        StringBuilder sb = new StringBuilder();
        sb.append(line.words.get(0));
        sb.append(getSlot(L - line.totalNonSpaceLetterLength()));
        output.add(sb.toString());
      } else if (i == lines.size() - 1) {
        StringBuilder sb = new StringBuilder();
        sb.append(line.words.get(0));
        for (int j = 1; j < line.wordCount(); j++) {
          sb.append(' ');
          sb.append(line.words.get(j));
        }
        sb.append(getSlot(L - line.minimumLength()));
        output.add(sb.toString());
      } else {
        int space = (L - line.totalNonSpaceLetterLength())
            / (line.wordCount() - 1);
        int remain = (L - line.totalNonSpaceLetterLength())
            % (line.wordCount() - 1);
        StringBuilder sb = new StringBuilder();
        sb.append(line.words.get(0));
        for (int j = 1; j <= remain; j++) {
          sb.append(getSlot(space+1));
          sb.append(line.words.get(j));
        }
        for (int j = remain+1; j < line.wordCount(); j++) {
          sb.append(getSlot(space));
          sb.append(line.words.get(j));
        }
        output.add(sb.toString());
      }
    }
    return output;
  }

  private String getSlot(int i) {
    char[] cs = new char[i];
    Arrays.fill(cs, ' ');
    return new String(cs);
  }

  private List<Line> parseToLines(String[] words, int L) {
    List<Line> lines = new ArrayList<Line>();
    Line currentLine = new Line();
    lines.add(currentLine);
    for (String word : words) {
      if (currentLine.minimumLength() + word.length() < L) {
        currentLine.addWord(word);
      } else {
        currentLine = new Line();
        lines.add(currentLine);
        currentLine.addWord(word);
      }
    }
    return lines;
  }

  class Line {

    private List<String> words;
    private int totalLength;

    Line() {
      words = new ArrayList<String>();
      totalLength = 0;
    }

    void addWord(String word) {
      words.add(word);
      totalLength += word.length();
    }

    int wordCount() {
      return words.size();
    }

    int totalNonSpaceLetterLength() {
      return totalLength;
    }

    int minimumLength() {
      return totalLength + words.size() - 1;
    }
  }

read more

Using regex to hanging indent a paragraph in Java

This post shows how to hanging indent a long paragraph using regular expression. The method will consider word boundaries, which means it will not break words for the indentation. To illustrate the problem, consider the following example

There has been an increasing effort in recent years to extract relations between entities from natural language text. In this dissertation, I will focus on various aspects of recognizing biomedical relations between entities reported in scientific articles.

The output should be

There has been an increasing effort in recent years to extract relations between
  entities from natural language text. In this dissertation, I will focus on
  various aspects of recognizing biomedical relations between entities reported
  in scientific articles.

My method

We need a regular expression to break the paragraph into a sequence of strings with fixed length. Suppose the text width is 80 and the indent is 3, the length of first string is 80. All remainders’ length is 77.

The main process of the algorithm is following

  1. Get the first 80 characters
  2. For the remaining strings, replace splitting points with three spaces

To find the splitting points, we use the regular expression (.{1,77})\s+. This regex searches a substring whose length is less and equal to 77 and whose last char is not a white space. After finding it, we replace the group ($1) with $1\n. Therefore, the java code should look like this

String regex = "(.{1,77})\\s+";
String replacement = "   $1\n";
text.replaceAll(regex, replacement);

This regex works perfect except for the last line. If the given text doesn’t end with a whitespace, like \n, the last line will not be handled correctly. Consider the last line as

in scientific articles.

In the last search, the regex cannot find the whitespace at the end of the line, so it will locate the space between “scientific” and “articles”. As the result, we will get

...
   in scientific
articles.

To overcome this problem, I add a fake “\n” at the end of the paragraph. After formatting, I remove it then.

Other part of the code are trivial. Here I attach my source code. I use Apache common libraries to generate indent spaces and assert the validation of indent. For more recent codes, you can check my Github

/**
   * Format a paragraph to that has all lines but the first indented.
   * 
   * @param text text to be formatted
   * @param hangIndent hanging indentation. hangIndent >= 0
   * @param width the width of formatted paragraph
   * @param considerSpace true if only split at white spaces.
   * @return
   */
  public static String hangIndent(String text, int hangIndent, int width,
      boolean considerSpace) {
    Validate.isTrue(
        hangIndent >= 0,
        "hangIndent should not be negative: %d",
        hangIndent);
    Validate.isTrue(width >= 0, "text width should not be negative: %d",
        width);
    Validate.isTrue(
        hangIndent < width,
        "hangIndent should not be less than width: "
        + "hangIndent=%d, width=%d",
        hangIndent,
        width);

    StringBuilder sb = new StringBuilder(text.substring(0, hangIndent));
    // Needed to handle last line correctly.
    // Will be trimmed at last
    text = text.substring(hangIndent) + "\n";
    // hang indent
    String spaces = org.apache.commons.lang3.StringUtils
        .repeat(' ', hangIndent);
    String replacement = spaces + "$1\n";
    String regex = "(.{1," + (width - hangIndent) + "})";
    if (considerSpace) {
      regex += "\\s+";
    }
    text = text.replaceAll(regex, replacement);
    // remove first spaces and last "\n"
    text = text.substring(hangIndent, text.length() - 1);
    return sb.append(text).toString();
  }

read more

Java.io in nutshell: 22 case studies

This post attempts to cover a comprehensive set of operations in java.io. Compared with other books and blogs related to this topic, my motivation is to show “how-to” through case studies. As once a Java student, I realize the most effective way of learning a new program language is through examples: copy and paste a piece of codes, run it to see results, then try to modify and re-run it step-by-step. Therefore, I assume this post will be helpful.

It is worth noting that this post will not touch anything related to java.nio because I think it is quite a different topic.

Table of Contents

Given a binary tree, create a list of all the nodes at each depth — Recursive version

Another FAQ on the programming interview.

Question

Given a binary search tree, design an algorithm which creates a linked list of all the nodes at each depth (eg, if you have a tree with depth D, you’ll have D linked lists).

Solution

Cracking the Coding Interview (4ed) (see page 126) provided a non-recursive algorithm. For me, a recursive version is neater and much easier to understand.

Sort a stack in ascending order in O(n log n)

Another FAQ on the programming interview.

Question

Write a program to sort a stack in ascending order. You should not make any assumptions about how the stack is implemented. The following are the only functions that should be used to write this program: push | pop | peek | isEmpty.

Solution

Cracking the Coding Interview (4ed) (see page 121) provided an O(N^2) algorithm by using one more stack. The idea is to pull an item from the original stack and push it on the other stack. If pushing this item would violate the sort order of the new stack, the algorithm removes enough items from it so that it’s possible to push the new item. Because of the copyright, I won’t paste her code here, but you can easily find it out online (:P).

Can we do better? I think we can mimic the way of quicksort by picking a pivot from the stack (using pop) first. Then we conduct the partition operation by pushing all elements in the stack with values less than the pivot into one stack, while all elements with values greater than the pivot into the other. After that, we recursively sort two sub-stacks and merge two at last with the pivot in the middle.

Because we can only use the stack structure, I pick the pivot using pop. The merge operation is tricky and I am not sure if we can have a better way to combine two stacks. So if you have any idea, please let me know.

On average, this algorithm makes O(n log n) comparisons to sort items. In the worst case, it makes O(n2) comparisons, though this behavior is rare.

public static Stack<Integer> sort(Stack<Integer> s) {
  if (s.isEmpty()) {
    return s;
  }
  int pivot = s.pop();
  
  // partition
  Stack<Integer> left  = new Stack<Integer>();
  Stack<Integer> right = new Stack<Integer>();
  while(!s.isEmpty()) {
    int y = s.pop();
    if (y < pivot) {
      left.push(y);
    } else {
      right.push(y);
    }
  }
  sort(left);
  sort(right);
   
  // merge
  Stack<Integer> tmp = new Stack<Integer>();
  while(!right.isEmpty()) {
    tmp.push(right.pop());
  }
  tmp.push(pivot);
  while(!left.isEmpty()) {
    tmp.push(left.pop());
  }
  while(!tmp.isEmpty()) {
    s.push(tmp.pop());
  }
  return s;
}

read more