1

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?

2
  • 2
    You said, the desired output for a null list is “null”. Do you mean the string "null" or a null reference? Using an empty stream as fallback serves neither… Commented Feb 22, 2018 at 15:50
  • I would like to return a null reference Commented Feb 23, 2018 at 16:43

4 Answers 4

3

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 */);
Sign up to request clarification or add additional context in comments.

4 Comments

The OP’s code would result in "." (after fixing the error) when the list is null (though the OP said that the intended result is null)…
@Holger Yes, I think the OP is wrong about either his result expectations or his attempt to solve this with streams and optionals, I mean, beyond the error in Arrays::stream.
it would be nice for Java to introduce the null propagation operator, in which case we can do things like String result = myStringList?.stream().collect(Collectors.joining(".","","."));, IMO this will reduce NullPointerExceptions as well as reduce if statements or nested if statements that guard against nullity in many places. I know the Optional class does a similar thing but there are certain areas where null propagation is better and more suitable.
@Aominè Yes, but it wouldn't be java, then. Also the elvis operator :? would be nice
2

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(".","","."));

1 Comment

Yep, that was the error. As pointed out above, it's not a good use of an optional but that's my fault. Thank you for your help
2

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

Comments

0

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(".","","."));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.