D.Rees
D.Rees

Reputation: 303

Java stream to collection for nullable string list

I have a list that may be null. I would like to concatenate the strings in that list into one string.

eg. A
list = ["hello","there"]
desired output = "hello.there."

eg. B
list = null
desired output = null

I have a method that works for non-null lists:

List<String> myStringList = foo.getlist();
String result = myStringList.stream()
            .collect(Collectors.joining(".","","."));

but the stream will throw an error if myStringList is null.

I believe I should be using an optional stream similar to:

List<String> myStringList = foo.getlist();
String result = Optional.ofNullable(myStringList)
    .map(Arrays::stream)
    .orElseGet(Stream::empty)
    .collect(Collectors.joining(".","","."))

However when I try this i get errors like "can not resolve method 'stream'".

Am I going about this the right way? Why am I getting errors for the code?

Upvotes: 1

Views: 3110

Answers (4)

alexp3y
alexp3y

Reputation: 31

If third-party libraries are game, Apache CollectionUtils has a nice utility for making lists null-safe:

List<String> myStringList = foo.getlist();
String result = CollectionUtils.emptyIfNull(myStringList).stream()
            .collect(Collectors.joining(".","","."));

Upvotes: 0

Azzabi Haythem
Azzabi Haythem

Reputation: 2423

you can use Collections.emptyList()

1- List not null :

List<String> myStringList = new ArrayList<>() ;
            myStringList.add("hello");
            myStringList.add("hello");

            String result = Optional.ofNullable(myStringList).orElse(Collections.emptyList()).stream()
                    .collect(Collectors.joining(".","","."));
            System.out.println(result);

output : hello.hello.

2- List null :

 List<String> myStringList2 = null;


             result = Optional.ofNullable(myStringList2).orElse(Collections.emptyList()).stream()
                    .collect(Collectors.joining(".","","."));
            System.out.println(result);

output : .

you can edit your output if you want

Upvotes: 2

fps
fps

Reputation: 34470

This is a personal opinion, but I think you shouldn't use Optional that way. Optional is not intended to replace a simple null-check. If you already have the Optional, then use it, or use it as the possibly absent return value of a method. Otherwise, I think it's more expressive and readable to show your exact intention w.r.t. the list being null or not:

List<String> myStringList = foo.getlist();

String result = myStringList == null ? 
        null :
        myStringList.stream().collect(Collectors.joining(".","","."));

In this cases, the ternary operator does a nice work.


EDIT:

If the joined string was the return value of a method, then using Optional and returning it would be a perfect fit:

private Optional<String> joinedFooList(Foo foo) {
    List<String> myStringList = foo.getlist();
    return Optional.ofNullable(myStringList)
        .map(l -> l.stream().collect(Collectors.joining(".","",".")));
}

Then, you could use the returned Optional:

joinedFooList(someFooInstance)
        .ifPresent(joined -> /* so something with the joined string */);

Upvotes: 3

Jorn Vernee
Jorn Vernee

Reputation: 33905

The problem is that you're trying to use Arrays::stream to convert your List to a stream. But, Arrays::stream is for arrays.

You need List::stream (which is the inherited version of Collection::stream, so that one would work too):

String result = Optional.ofNullable(myStringList)
    .map(List::stream)
    .orElseGet(Stream::empty)
    .collect(Collectors.joining(".","","."));

Upvotes: 2

Related Questions