Print Array in Java
Page content
In this tutorial, we’ll learn how to print the elements of a given Array in Java.
Simplest way
The Arrays.toString() and Arrays.deepToString() methods are the simplest way to print Arrays in Java and work well for all type of Arrays i.e. int, double, byte, String, etc.
Quick examples
System.out.println(Arrays.toString(new int[]{1, 2, 3}));
// prints [1, 2, 3]
System.out.println(Arrays.deepToString(new int[][]{{1, 2}, {3, 4}, {5, 6}}));
// prints [[1, 2], [3, 4], [5, 6]]
System.out.println(Arrays.deepToString(new int[][][]{{{1, 2}, {3}, {4}}, {{5, 6, 7}, {8}}, {{9, 10}}}));
// prints [[[1, 2], [3], [4]], [[5, 6, 7], [8]], [[9, 10]]]
Arrays.toString() for simple Array
The Arrays.toString() method is the simplest way to print elements of an Array in a single line in Java:-
String[] strArray = new String[] {"John", "Mary", "Bob"};
System.out.println(Arrays.toString(strArray));
// prints [John, Mary, Bob]
Limitation of Array.toString()
The Arrays.toString() method works well with simple Array but prints ClassName@hashCode for nested Arrays like this:-
String[][] nestedArray = new String[][] {{"John", "Mary"}, {"Alice", "Bob"}};
System.out.println(Arrays.toString(nestedArray));
// prints something like [[Ljava.lang.String;@566776ad, [Ljava.lang.String;@6108b2d7]
Nothing to worry about! We have Arrays.deepToString() to the rescue.
Arrays.deepToString() for nested Array
The Arrays.deepToString() method can be used to print all the nested elements of a multi-dimensional Array in a single line in Java:-
String[][] nestedArray = new String[][] {{"John", "Mary"}, {"Alice", "Bob"}};
System.out.println(Arrays.deepToString(nestedArray));
// prints [[John, Mary], [Alice, Bob]]
String[][][] deepNestedArray = new String[][][] {{{"John"}, {"Mary"}, {"Alice"}}, {{"Bob"}, {"Adam"}}, {{"Emily"}}};
System.out.println(Arrays.deepToString(deepNestedArray));
// prints [[[John], [Mary], [Alice]], [[Bob], [Adam]], [[Emily]]]
Other ways
There are many other ways to print an Array in Java:-
- Use
Arrays.toString()andArrays.deepToString()methods to convert an Array to a comma-separated String and print. - Use
Arrays.asList()andList.of()methods to convert an Array to a List and use its predefinedtoString()method to print elements in a comma-separated String. - Use
String.join()method to join elements of a String Array by any delimiter of your choice and print in a single line. - Use Java Streams to map elements of an Array to String, join by any delimiter of your choice, and print in a single line.
- Use forEach loop to iterate through elements of an Array and print each element in a new line.
Let’s look at the examples:-
// Primitive int
int[] ints = new int[] {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(ints));
System.out.println(IntStream.of(ints).mapToObj(Integer::toString).collect(Collectors.joining(", ")));
System.out.println(IntStream.of(ints).boxed().map(Object::toString).collect(Collectors.joining(", ")));
IntStream.of(ints).forEach(System.out::println);
Arrays.stream(ints).forEach(System.out::println);
// Object String
String[] strs = new String[] {"John", "Mary", "Bob"};
System.out.println(Arrays.toString(strs));
System.out.println(Arrays.asList(strs));
System.out.println(List.of(strs));
System.out.println(String.join(", ", strs));
System.out.println(Stream.of(strs).collect(Collectors.joining(", ")));
Stream.of(strs).forEach(System.out::println);
Arrays.stream(strs).forEach(System.out::println);
Arrays.asList(strs).forEach(System.out::println);
List.of(strs).forEach(System.out::println);
// Object Enum
DayOfWeek [] days = { FRIDAY, MONDAY, TUESDAY };
System.out.println(Arrays.toString(days));
System.out.println(Arrays.asList(days));
System.out.println(Stream.of(days).map(Object::toString).collect(Collectors.joining(", ")));
Stream.of(days).forEach(System.out::println);
Arrays.stream(days).forEach(System.out::println);
Arrays.asList(days).forEach(System.out::println);
List.of(days).forEach(System.out::println);
That’s a lot of one-liners doing similar things, so it’s worth understanding what each group is actually doing rather than copy-pasting whichever one compiles.
List-backed printing: Arrays.asList() and List.of()
Arrays.asList(strs) and List.of(strs) both wrap the array in a List, and List’s inherited toString() already produces the same [John, Mary, Bob] format you get from Arrays.toString() — so for printing purposes they’re equivalent to what you already had, just routed through a List. The difference only matters if you intend to keep the list around afterwards: Arrays.asList() returns a fixed-size view backed by the original array (you can set() elements, which writes through to the array, but add()/remove() throw UnsupportedOperationException), while List.of() returns a fully immutable list that also rejects null elements. Don’t reach for either one purely to print an array — that’s a longer detour to the same [a, b, c] output Arrays.toString() already gives you directly.
String.join() for String arrays
String.join(", ", strs) is the simplest option when you already have a String[] and want control over the delimiter — no brackets, a custom separator, whatever you need. Its one limitation is right there in the signature: it only accepts CharSequence arguments, so it works directly on String[] but not on int[] or DayOfWeek[] without first converting each element to a String.
Streams: IntStream, Stream, and Collectors.joining()
This is where the primitive/object split in the code above actually matters. Arrays of primitives (int[], long[], double[]) don’t implement Iterable and can’t be turned into a Stream<Integer> directly — that’s why the int[] example uses IntStream.of(ints) or Arrays.stream(ints) (both produce the same primitive-specialized IntStream), then .mapToObj(Integer::toString) or .boxed().map(Object::toString) to get from int to String before joining. Object arrays (String[], DayOfWeek[]) skip that step and go straight to Stream.of(strs) or Arrays.stream(strs).
Once you have a Stream<String>, .collect(Collectors.joining(", ")) builds the same comma-separated output as String.join(), but as part of a stream pipeline — which is the point: reach for the streams version when you’re already filtering, sorting, or transforming the array’s elements before printing, not as a replacement for String.join() on an untouched String[]. For a plain array with no other processing, Arrays.toString() or String.join() says the same thing in less code and is easier for the next person to read.
forEach for one-per-line output
Stream.of(strs).forEach(System.out::println), Arrays.stream(strs).forEach(...), and Arrays.asList(strs).forEach(...) all end up calling println once per element — the difference is purely which route gets you an Iterable/Stream to call forEach on, and functionally it doesn’t matter which one you pick. What does matter is the output shape: forEach prints each element on its own line, while Arrays.toString(), String.join(), and Collectors.joining() all print everything on a single line. Pick based on what you actually want to see, not which one happens to be shortest.
Performance and readability
For a debug println or a log line, none of this matters at the scale most applications run at — Arrays.toString() is one call, easy to read, and fast enough. The streams-based approaches add object allocation (a stream pipeline, boxed wrapper objects for primitives, intermediate String objects) for the same result, so they’re worth it only when you’re already mid-stream doing something else — filtering out blanks, upper-casing, sorting — and printing is just the last step in that pipeline. Don’t build a Stream solely to print an array; that’s solving a one-line problem with a five-line pipeline.