'Java stream API to find length of each string in list

I have a String array in java as follows.

String[] text = {"hello", "bye"};

Now I need to use Java stream API to calculate the length of each string in this array. I do not want to use for loop. How can I do that?

Update: I have checked this link and got the following code to get the sum of the length of each string of this array.

Arrays.stream(text)
      .filter(Objects::nonNull)
      .mapToInt(String::length)
      .reduce(0,Integer::sum);


Solution 1:[1]

tl;dr

Use code points rather than char & String#length.

Arrays
    .stream( inputs )                          // A stream of each `String` object in the array.
    .mapToLong( s -> s.codePoints().count() )  // Get the count of code points for each string. Returns a `LongStream`. 
    .toArray() ;                               // Returns an array of `long` primitives. 

Code points

Your code snippet and the other Answers use String#length. Unfortunately that method is legacy, based on the legacy type char.

That approach fails with most characters. Here is a demonstration of such a failure.

String input = "A?C" ;
int len = input.length() ;
System.out.println( len ) ;

See that code run live at IdeOne.com.

4

Result is incorrect, reporting “4” for a string of 3 characters.

Instead of char, use code point integer numbers when working with individual characters. A code point is the number permanently assigned to each character defined in Unicode.

For each string of our stream of inputs, get an IntStream whose elements are the code points of each character in that string. Get the count of that stream of code points, which returns a long. Report those code point counts as a LongStream. Collect results to an array of long primitive values.

    String[] inputs = { "hello" , "bye" ,  "A?C" } ;
    long[] lengths =
        Arrays
            .stream( inputs )                          // A stream of each `String` object in the array.
            .mapToLong( s -> s.codePoints().count() )  // Get the count of code points for each string. Returns a `LongStream`. 
            .toArray() ;

See this code run live at IdeOne.com.

[5, 3, 3]

Solution 2:[2]

You could simply collect after mapping to String::length:

List<Integer> length = Arrays.stream(text)
    .filter(Objects::nonNull)
    .map(String::length)
    .toList();

This would give you a list with the lengths in the same order as defined in the array. (If below JDK 16, you need to use collect(Collectors.toList()) instead of toList()).

Another option would be to collect to a Map:

Map<String, Integer> stringToLength = Arrays.stream(text)
    .filter(Objects::nonNull)
    .distinct()
    .collect(Collectors.toMap(Function.identity(), String::length));

This would give you a map with the strings as keys, and the length as values. distinct() is used in order to protect yourself from multiple copies of the same string, the map collecting would throw an exception in case of duplicates.

Solution 3:[3]

Since you are starting with an array you may want to return an array so this will work.

String[] text = {"hello", "bye"};

int[] lengths = Arrays.stream(text)
    .mapToInt(String::length)
    .toArray();
System.out.println(Arrays.toString(lengths));

prints

[5, 3]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Magnilex
Solution 3 WJS