ArrayList algorithm complexity, performance and gotchas

This piece of advice is about the Java ArrayList and LinkedList. It is not a insight about a general not specified List algorithm.

ArrayList is a random access data store.

LinkedList is sequential access data store.

There are these very important performance issues to know:

  • Remove: ArrayList remove(E ) is painful slow. Please consider LinkedList if this operation is used often in your application. Also the ArrayList positional remove(index) is painful bad. These operations require constant-time in a LinkedList and linear-time in an ArrayList. (*)
  • Use ArrayList constructor that take a size argument. You can measure by your self the defference when using large lists.
  • List Interface : Iterating over the elements in a list is preferable to indexing through it if the caller does not know the implementation.
  • Remember that you have the method addAll() for bulk operations.
  • Add positional add(index) is painful O(n) on ArrayList and O(1) in LinkedList (*)
  • Set positional set(index) is painful O(n) on LinkedList and O(1) in ArrayList   (*)

(*) Also the outline of the Collections Framework states that LinkedList is better than ArrayList for accessing in the middle of the list.

Also:

Do not do this:

 int a1[] = { -23, 12, 21 };
 
for (int v : a1)
           myarraylist.add(new Integer(v));

prefer this instead:

myarrayList.addAll(Arrays.asList(23,12,21)

Also

Arrays.asList

for translating arrays to strings is obsolete. Use this instead:

System.out.println(Arrays.toString(myArray));

Static Lock (ReentrantLock) and SonarQube destroyed my day

Yes, the idea of letting a module pass through a SonarQube validation throw us in putting ‘static’ on a lot of fields. A static happen to be attached to a ReentrantLock …
And many wasted hours of debugging followed because the applications using this module became crazy and not correct.
This piece of code can destry your application:

private static final Lock = new ReentrantLock();

Benchmark , Performance StringJoiner StringBuffer “+” plus operator

This is a benchmark for performance and behaviour of joining strings with:

  • StringJoiner
  • StringBuffer
  • The + operator

The result is that

StringJoiner is the winner.

StringBuffer and ‘+’ are worse and have the same performance.

package org.sample;
 
import java.util.ArrayList;
import java.util.List;
 
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
 
@Warmup(iterations = 10, time = 1)
@Measurement(iterations = 10, time = 1)
@State(Scope.Benchmark)
@Fork(1)
public class JoinString extends JoinStringBase {
	@Param({ "10000" })
	private int CYCLES;
 
	private final int P = 4;
 
	private List listCounter;
 
	private List listA;
	private List listC;
	private List listD;
	private List listXP;
	private List listJOINER;
 
	@Setup(Level.Trial)
	public void setUp() {
		listCounter = new ArrayList<>(CYCLES + 1);
 
		for (int i = 0; i < CYCLES; i++) {
			listCounter.add("" + i);
		}
 
		listA = new ArrayList<>(CYCLES + 1);
		listC = new ArrayList<>(CYCLES + 1);
		listD = new ArrayList<>(CYCLES + 1);
		listXP = new ArrayList<>(CYCLES + 1);
		listJOINER = new ArrayList<>(CYCLES + 1);
 
		System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", Integer.toString(P));
	}
 
	@Benchmark
	public long useStringBuffer() {
		for (int i = 0; i < CYCLES; i++) {
			listC.add(bufferDateString(TEXT));
		}
		return listC.size();
	}
 
	@Benchmark
	public long plusOperator() {
		for (int i = 0; i < CYCLES; i++) {
			listA.add(plusOperator(TEXT));
		}
		return listA.size();
	}
 
	@Benchmark
	public long useStringJoiner() {
		for (int i = 0; i < CYCLES; i++) {
			listJOINER.add(stringJoiner(TEXT));
		}
		return listJOINER.size();
	}
}
 
 
 
import java.util.StringJoiner;
 
class JoinStringBase {
 
	private static final String TWENTY = "20";
	private static final String POINT = ".";
 
	protected static final String TEXT = "_20ge20";
 
	String stringJoiner(String pScad) {
		StringJoiner sj = new StringJoiner("");
		String day = pScad.substring(1, 3);
		String month = pScad.substring(3, 5);
		String monthInt = MONTHS.valueOf(month).month;
		String yearSuffix = pScad.substring(5, 7);
 
		sj.add(day);
		sj.add(POINT);
		sj.add(monthInt);
		sj.add(POINT);
		sj.add(TWENTY);
		sj.add(yearSuffix);
		return sj.toString();
 
	}
 
	final String bufferDateString(String pScad) {
		StringBuffer buffer = new StringBuffer();
		String day = pScad.substring(1, 3);
		String month = pScad.substring(3, 5);
		String monthInt = MONTHS.valueOf(month).month;
		String yearSuffix = pScad.substring(5, 7);
 
		buffer.append(day);
		buffer.append(POINT);
 
		buffer.append(monthInt);
		buffer.append(POINT);
 
		buffer.append(TWENTY);
		buffer.append(yearSuffix);
		return buffer.toString();
	}
 
	final String plusOperator(String pScad) {
		String day = pScad.substring(1, 3);
		String month = pScad.substring(3, 5);
		String monthInt = MONTHS.valueOf(month).month;
		String yearSuffix = pScad.substring(5, 7);
 
		String scadFormat = day + POINT + monthInt + POINT + TWENTY + yearSuffix;
		return scadFormat;
	}
 
	enum MONTHS {
		ge("01"), fb("02"), mz("03"), ap("04"), mg("05"), gn("06"), lg("07"), ag("08"), st("09"), ot("10"), nv("11"), dc("12");
 
		final String month;
 
		MONTHS(String month) {
			this.month = month;
		}
	}
 
	final String plusOperatorXP(String pScad) {
		return pScad.substring(1, 3) + POINT + MONTHS.valueOf(pScad.substring(3, 5)).month + POINT + TWENTY
				+ pScad.substring(5, 7);
	}
 
	final String bufferDateStringXP(String pScad) {
		StringBuffer buffer = new StringBuffer();
 
		String month = pScad.substring(3, 5);
 
		buffer.append(pScad.substring(1, 3));
		buffer.append(POINT);
 
		buffer.append(MONTHS.valueOf(month).month);
		buffer.append(POINT);
 
		buffer.append(TWENTY);
		buffer.append(pScad.substring(5, 7));
		return buffer.toString();
	}
 
}

 

The results in details:

blogJoinString2

REST and CQRS Command Query Responsibility Segregation

CQRS stands for Command Query Responsibility Segregation.
REST goes well with CQRS when we use the paradigm of “REST without PUT”.
The idea is that we no longer PUT the “new” state of an entity, instead we make our mutations be first class  citizen nouns (rather than verbs), and POST them.

REST without PUT has a side-benefit of separating command and query interfaces (CQRS)  and forces consumers to allow for eventual consistency.
We POST command entities to one endpoint (the “C” of CQRS) and GET a model entity from another endpoint  (the “Q”).

JMH how to tips

JMH is a good tool for benchmarking your code.

The following hints will help you to save time in an otherwise not easy set up.

  • always use state and scope at class level. Use Scope.Thread when uncertainn. Like:
    @State(Scope.Thread)
    public class MyClass {
  • No benchmarks to run message? check the include/exclude regexps.
  • Always use Fork s greater than zero.
  • Methods annotated with @Benchmark should be public.
  • Always return something from a benchmarked method.
  • Do you need to organize many becnhmarks though many classes? Use the command line to select a specific benchmark to run. Like:

Please refer to this  document for more hints.

Automatically generate java backend and rest api from existing database

I am working a lot with databases , hibernate , restful apis in Java SE / java EE with HTML clients.
I am pleased to suggest this workflow that relies on Netbeans automatic generation capabilities.

1. Netbeans generates JPA entities from an existing database.

As it is described at Dzone and at Oracle site.
You have also the option of generating JAXB annotations directly in the JPA entity classes.

2. Netbeans generates then restful api from the entities.

As it is described at NetBeans Help site.

It is really a breeze to come up fast with a Java backend.
I am working now on the HTML / javascript/ jquery client and I will let you know.

Generate JPA entities from database

with Netbeans

https://dzone.com/articles/crud-in-90-seconds

https://docs.oracle.com/cd/E40938_01/doc.74/e40142/dev_persistence.htm#BABCGACD

with Eclipse

Eclipse Neon Help: Generate entities from tables

Create JPA project

with JBoss

http://www.itbh.at/jpa-tools-generate-entities-from-tables-does-not-work-with-h2-database/?lang=en

with MyEclipse

https://www.genuitec.com/products/myeclipse/features/