Harshal
Harshal

Reputation: 55

Split string in a stream Java

I have a POJO class Product

List<Product> list = new ArrayList<>();
list.add(new Product(1, "HP Laptop Speakers", 25000));
list.add(new Product(30, "Acer Keyboard", 300));
list.add(new Product(2, "Dell Mouse", 150));

Now I want to split the list to get output as HP-Laptop-Speakers&&Acer-Keyboard&&Dell-Mouse.

I just want a single liner in stream. So far I have managed to get

Optional<String> temp = list.stream().
                   map(x -> x.name).
                   map(x -> x.split(" ")[0]).
                   reduce((str1, str2) -> str1 + "&&" + str2);
System.out.println(temp.get());

Output: HP&&Acer&&Dell

Can someone help me out. Thanks in advance.

Upvotes: 3

Views: 1357

Answers (6)

Patrick Parker
Patrick Parker

Reputation: 4959

First, the split() operation is not necessary. While you could split all the pieces and then join them together like that, it is far simpler to use a replace or replaceAll call instead.

Secondly, the reduce operation will not be very efficient since it is creating lots of intermediary Strings and StringBuilders. Instead, you should use the String joining Collector, which is more efficient:

 String temp = list.stream()
              .map(x -> x.name.replace(" ", "-"))
              .collect(Collectors.joining("&&"));

Upvotes: 3

Manish Karki
Manish Karki

Reputation: 503

you need to replace this portion map(x -> x.split(" ")) with map(x -> x.replaceAll("\\s","-"))

Upvotes: 0

Dinesh
Dinesh

Reputation: 1086

Optional<String> temp = list.stream().map(x -> x.name)
                  .map(x -> x.replaceAll("\\s", "-"))
                  .reduce((str1, str2) -> str1 + "&&" + str2);

Upvotes: 0

azro
azro

Reputation: 54148

The second map operation you write keep the first word.

Instead, here what you can do :

  1. Replace the spaces (\\s as regex) by a -

    Optional<String> temp = list.stream()
                                .map(x -> x.name)
                                .map(x -> x.replaceAll("\\s", "-"))
                                .reduce((str1, str2) -> str1 + "&&" + str2);
    
  2. Split on space, and then join with the -

    Optional<String> temp  = list.stream()
                                 .map(x -> x.name)
                                 .map(x -> String.join("-", x.split("\\s")))
                                 .reduce((str1, str2) -> str1 + "&&" + str2);
    

Upvotes: 2

A. K.
A. K.

Reputation: 160

One easy way to do this would be to override the toString() method in the Product class to print the name as you want it formatted and then iterate through the list concatenating each result onto a longer string.

Upvotes: 0

Max Farsikov
Max Farsikov

Reputation: 2763

Try to use collector on stream of strings:

.collect(Collectors.joining("&&"))

Upvotes: 1

Related Questions