Core Java

Java 8 Join Arrays Example

1. Introduction

An Array is a data structure which holds a fixed number of objects with the same type. Joining Arrays is to combine two arrays into one. Java 8 enhances Collection by providing a new Stream interface. A stream is not a data structure, instead it is created from Collection, Array, or I/O channels.

Java 8 provides a Stream interface which contains several methods that we can use to join two arrays.
 
 
 
 

Return typeMethodDescription
static <T> Stream<T>concat(Stream<? extends T> a, Stream<? extends T> b)Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
Object[]toArray()Returns an array containing the elements of this stream.
static <T> Stream<T>of(T... values)Returns a sequentially ordered stream whose elements are the specified values.
<R> Stream<R>flatMap(Function<? super T,? extends Stream<? extends R>> mapper)Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

 

Java 8 provides the same methods for primitive types: int, long, double as IntStream, LongStream, and DoubleStream respectively.

InterfaceReturn typeMethods
IntStreamstatic IntStreamconcat(IntStream a, IntStream b)
int[] toArray()
static IntStream of(int... values)
LongStreamstatic LongStreamconcat(LongStreama, LongStreamb)
long[] toArray()
static LongStream of(long... values)
DoubleStreamstatic DoubleStreamconcat(DoubleStreama, DoubleStreamb)
double[] toArray()
static DoubleStreamaof(double... values)

 

Java 8 enhances the Arrays class to add the stream method to create a stream from an Array.

Return typeMethodDescription
static IntStreamstream(int[] array)Returns a sequential IntStream with the specified array as its source.
static DoubleStreamstream(double[] array)Returns a sequential DoubleStream with the specified array as its source.
static LongStreamstream(long[] array)Returns a sequential LongStream with the specified array as its source.
<T> Stream<T>stream(T[] array)Returns a sequential Stream with the specified array as its source.

 

In this example, I will demonstrate how to join two arrays in three steps:

  1. Converting two arrays into two streams: with Stream.of or Arrays.stream.
  2. Joining two streams: with concat or flatMap.
  3. Using toArray on the joined stream to return it as an array.

2. Technologies Used

The example code in this article was built and run using:

  • Java 1.8.101
  • Maven 3.3.9
  • Eclipse Oxygen
  • Junit 4.12

3. Maven Project

3.1 Dependencies

I will include Junit in pom.xml.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>zheng.jcg.demo</groupId>
	<artifactId>java8-join-array</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

3.2 SimpleData

I will create a SimpleData class which will be used to create an array with a user defined data type.

SimpleData.java

package com.zheng.demo;

public class SimpleData {

	public SimpleData(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}

	private String name;
	private Integer age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "SimpleData [name=" + name + ", age=" + age + "]";
	}

}

3.3 Stream.concat

I will create a JoinArrays_concat class to join two arrays with the primitive data types – int, double, long and the user defined data type – SimpleData by using Stream’s concat method.

JoinArrays_concat.java

package com.zheng.demo;

import java.util.Arrays;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

public class JoinArrays_concat {

	public int[] by_IntStream_concat(int[] int1, int[] int2) {
		IntStream joinedStream = IntStream.concat(Arrays.stream(int1), Arrays.stream(int2));
		return joinedStream.toArray();
	}

	public double[] by_DoubleStream_concat(double[] double1, double[] double2) {
		DoubleStream joinedStream = DoubleStream.concat(Arrays.stream(double1), Arrays.stream(double2));
		return joinedStream.toArray();
	}

	public long[] by_LongStream_concat(long[] long1, long[] long2) {
		LongStream joinedStream = LongStream.concat(Arrays.stream(long1), Arrays.stream(long2));
		return joinedStream.toArray();
	}

	public String[] by_Stream_concat(String[] array1, String[] array2) {
		Stream stream1 = Arrays.stream(array1);
		Stream stream2 = Arrays.stream(array2);

		Stream joinedStream = Stream.concat(stream1, stream2);

		return joinedStream.toArray(String[]::new);
	}

	public String[] by_Stream_concat_2(String[] array1, String[] array2) {
		Stream stream1 = Stream.of(array1);
		Stream stream2 = Stream.of(array2);

		Stream joinedStream = Stream.concat(stream1, stream2);

		return joinedStream.toArray(String[]::new);
	}

	public SimpleData[] by_Stream_concat_Object(SimpleData[] data1, SimpleData[] data2) {
		Stream joined = Stream.concat(Arrays.stream(data1), Arrays.stream(data2));

		return joined.toArray(SimpleData[]::new);
	}

	public SimpleData[] by_Stream_concat_Object_2(SimpleData[] data1, SimpleData[] data2) {
		Stream joinedStream = Stream.concat(Stream.of(data1), Stream.of(data2));

		return joinedStream.toArray(SimpleData[]::new);
	}
}

3.4 Stream.flatMap

I will create a JoinArrays_flatmap class to join two arrays with Stream.flatMap for String. and a user defined data type.

JoinArrays_flatmap.java

package com.zheng.demo;

import java.util.stream.Stream;

public class JoinArrays_flatmap {
	public String[] by_Stream_of_flatMap(String[] array1, String[] array2) {
		Stream joinedStream = Stream.of(array1, array2).flatMap(Stream::of);
		return joinedStream.toArray(String[]::new);
	}

	public SimpleData[] by_Stream_of_flatMap_2(SimpleData[] data1, SimpleData[] data2) {
		Stream joined = Stream.of(data1,data2).flatMap(Stream::of);

		return joined.toArray(SimpleData[]::new);
	}
}

3.5 System.arraycopy

Java System class provides arraycopy to copy an array from the specified source array, beginning at the specified position, to the specified position of the destination array. I will create a JoinArrays_arraycopy class to join two arrays.

JoinArrays_arraycopy.java

package com.zheng.demo;

public class JoinArrays_arraycopy {

	public <T> T[] concat(T[] a, T[] b) {
		final int alen = a.length;
		final int blen = b.length;
		if (alen == 0) {
			return b;
		}
		if (blen == 0) {
			return a;
		}
		final T[] result = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), alen + blen);
		System.arraycopy(a, 0, result, 0, alen);
		System.arraycopy(b, 0, result, alen, blen);
		return result;
	}

}

4. Demo

We will demo this with the Junit test classes.

4.1 JoinArrays_concatTest

I will create test cases to join two arrays with different data types: int, long, double, String, and SimpleData.

JoinArrays_concatTest.java

package com.zheng.demo;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;

import org.junit.Test;


public class JoinArrays_concatTest {
	private JoinArrays_concat jArray = new JoinArrays_concat();

	@Test
	public void join_arrays_by_IntStream_concat() {
		int[] int1 = new int[] { 1, 2, 3 };
		int[] int2 = new int[] { 4, 5, 6 };

		int[] joinedIntArray = jArray.by_IntStream_concat(int1, int2);
		assertEquals(6, joinedIntArray.length);
		assertEquals( "[1, 2, 3, 4, 5, 6]" , Arrays.toString(joinedIntArray));
		
	}
	
	@Test
	public void join_arrays_by_DoubleStream_concat() {
		double[] int1 = new double[] { 1, 2, 3 };
		double[] int2 = new double[] { 4, 5, 6 };

		double[] joinedArray = jArray.by_DoubleStream_concat(int1, int2);
		assertEquals(6, joinedArray.length);
		assertEquals( "[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]" , Arrays.toString(joinedArray));
		
	}
	
	@Test
	public void join_arrays_by_LongStream_concat() {
		long[] int1 = new long[] { 1, 2, 3 };
		long[] int2 = new long[] { 4, 5, 6 };

		long[] joinedArray = jArray.by_LongStream_concat(int1, int2);
		assertEquals(6, joinedArray.length);
		assertEquals( "[1, 2, 3, 4, 5, 6]" , Arrays.toString(joinedArray));
		
	}
	
	@Test
	public void join_arrays_by_Stream_concat() {
		String[] animals1 = new String[] { "Dog", "Cat", "Bird" };
		String[] animals2 = new String[] { "Bird", "Cow" };		

		String[] joinedArray = jArray.by_Stream_concat(animals1, animals2);
	
		assertEquals(5, joinedArray.length);
		assertEquals( "[Dog, Cat, Bird, Bird, Cow]" , Arrays.toString(joinedArray));
		
	}
	
	@Test
	public void join_arrays_by_Stream_concat_2() {
		String[] animals1 = new String[] { "Dog", "Cat", "Bird" };
		String[] animals2 = new String[] { "Bird", "Cow" };		

		String[] joinedArray = jArray.by_Stream_concat_2(animals1, animals2);
	
		assertEquals(5, joinedArray.length);
		assertEquals( "[Dog, Cat, Bird, Bird, Cow]" , Arrays.toString(joinedArray));
		
	}
	

	@Test
	public void join_arrays_by_Stream_concat_Object() {
		SimpleData[] data1 =  {new SimpleData("Mary", 30), new SimpleData("Tom", 40)};
		SimpleData[] data2 =  {new SimpleData("Bob", 18), new SimpleData("John", 60)};
		
		SimpleData[] joinedArray = jArray.by_Stream_concat_Object(data1, data2);
		
		assertEquals(4, joinedArray.length);
		Arrays.stream(joinedArray).forEach(e->System.out.println(e.toString()));

	}
	
	@Test
	public void join_arrays_by_Stream_concat_Object_2() {
		SimpleData[] data1 =  {new SimpleData("Mary", 30), new SimpleData("Tom", 40)};
		SimpleData[] data2 =  {new SimpleData("Bob", 18), new SimpleData("John", 60)};
		
		SimpleData[] joinedArray = jArray.by_Stream_concat_Object_2(data1, data2);
		
		assertEquals(4, joinedArray.length);
		Arrays.stream(joinedArray).forEach(e->System.out.println(e.toString()));

	}	

}

4.2 JoinArrays_flatmapTest

I will create test cases to join two arrays for two data types: String and SimpleData.

JoinArrays_flatmapTest.java

package com.zheng.demo;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;

import org.junit.Test;

public class JoinArrays_flatmapTest {
	private JoinArrays_flatmap jArray = new JoinArrays_flatmap();

	@Test
	public void join_arrays_by_Stream_of_flatMap() {
		String[] animals1 = new String[] { "Dog", "Cat", "Bird" };
		String[] animals2 = new String[] { "Bird", "Cow" };

		String[] joinedArray = jArray.by_Stream_of_flatMap(animals1, animals2);

		assertEquals(5, joinedArray.length);
		assertEquals("[Dog, Cat, Bird, Bird, Cow]", Arrays.toString(joinedArray));

	}
	
	@Test
	public void join_arrays_by_Stream_of_flatMap_2() {
		SimpleData[] data1 =  {new SimpleData("Mary", 30), new SimpleData("Tom", 40)};
		SimpleData[] data2 =  {new SimpleData("Bob", 18), new SimpleData("John", 60)};
		
		SimpleData[] joinedArray = jArray.by_Stream_of_flatMap_2(data1, data2);
		
		assertEquals(4, joinedArray.length);
		Arrays.stream(joinedArray).forEach(e->System.out.println(e.toString()));

	}
	

}

4.1 JoinArrays_arraycopyTest

I will create test cases to join two arrays for data types: Integer, Long, String, and SimpleData.

JoinArrays_arraycopyTest.java

package com.zheng.demo;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;

public class JoinArrays_arraycopyTest {
	
	private JoinArrays_arraycopy testObject = new JoinArrays_arraycopy();

	@Test
	public void join_two_Integer_arrays() {
		Integer[] int1 = new Integer[] { 1, 2, 3 };
		Integer[] int2 = new Integer[] { 4, 5, 6 };
		Integer[] joinedArray = testObject.concat(int1, int2);
		
		assertEquals(6, joinedArray.length);
		assertEquals( "[1, 2, 3, 4, 5, 6]" , Arrays.toString(joinedArray));
	}
	
	@Test
	public void join_two_Long_arrays() {
		Long[] int1 = new Long[] { 1l, 2l, 3l };
		Long[] int2 = new Long[] { 4l, 5l, 6l };
		Long[] joinedArray = testObject.concat(int1, int2);
		
		assertEquals(6, joinedArray.length);
		assertEquals( "[1, 2, 3, 4, 5, 6]" , Arrays.toString(joinedArray));
	}
	
	@Test
	public void join_two_String_arrays() {
		String[] int1 = new String[] { "Dog", "Cat", "Bird"  };
		String[] int2 = new String[] { "Bird", "Cow" };
		String[] joinedArray = testObject.concat(int1, int2);
		
		assertEquals(5, joinedArray.length);
		assertEquals( "[Dog, Cat, Bird, Bird, Cow]" , Arrays.toString(joinedArray));
	}
	
	@Test
	public void join_two_SimpleData_Arrays() {
		SimpleData[] data1 =  {new SimpleData("Mary", 30), new SimpleData("Tom", 40)};
		SimpleData[] data2 =  {new SimpleData("Bob", 18), new SimpleData("John", 60)};
		
		SimpleData[] joinedArray = testObject.concat(data1, data2);
		
		assertEquals(4, joinedArray.length);
		Arrays.stream(joinedArray).forEach(e->System.out.println(e.toString()));
	}

}

5. Java 8 Join Arrays – Summary

In this article, I demonstrated how to join two arrays via System.arraycopyand Stream operations: concat, of, flatmap, and toArray.

6. Download the Source Code

This tutorial consists of a Maven project which includes three Java classes as well as their test classes to join two arrays.

Download
You can download the full source code of this example here: Java 8 Join Arrays Example

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button