1

I have an ArrayList which follows this form { a/b/c ; d/e/f ; ...} and I want to mutate it and have it in this form { a ; b ; c ; d ; e ; ...}. I mean I know I can make two functions, one that takes care of removing the / character and one that does the rest. But I'm really curious if I can use some built-in functions that can help me do that quickly for me.

Ok here is one try:

List<String> purgedList = new ArrayList<>();
        for (String s : listFromFile) {
            purgedList.addAll(Arrays.asList(s.split("/")));
        }
legenw84it
  • 51
  • 7

2 Answers2

3

Try this.

public static void main(String[] args) {
    List<String> input = List.of("a/b/c", "d/e/f", "g");

    List<String> output = input.stream()
        .flatMap(s -> Arrays.stream(s.split("/")))
        .collect(Collectors.toList());

    System.out.println(output);
}

See this code run live at IdeOne.com.

[a, b, c, d, e, f, g]
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 3
    Tip: In Java 16+, replace `.collect(Collectors.toList());` with [`.toList();`](https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/stream/Stream.html#toList()). – Basil Bourque Aug 29 '21 at 01:31
  • Very interesting. I'm curious how would you compare that to the solution I just added? Especially, if I'm dealing with a big amount of data. – legenw84it Aug 29 '21 at 02:14
  • Also, I think it should be wrapped in a `try-with-resources` statement, right? in order to close the stream. – legenw84it Aug 29 '21 at 02:24
  • 1
    @serving__ Streams have a BaseStream.close() method and implement AutoCloseable, but nearly all stream instances do not actually need to be closed after use. Generally, only streams whose source is an IO channel (such as those returned by Files.lines(Path, Charset)) will require closing. –  Aug 29 '21 at 04:08
  • 1
    @serving__ Wow, your question about try-with-resources turns out to be a surprising and subtlety complicated one. See post, [*Closing Java Streams with `AutoCloseable`*](https://mikemybytes.com/2021/01/26/closing-java-streams-with-autocloseable/) – Basil Bourque Aug 29 '21 at 04:13
  • "when a Stream is dealing with I/O operations (files, connections, etc.) it should be closed" Got it! I'll also get the SonarLint plugin for my editor, just in case, if I get too lazy. Thank you guys for your suggestions! Greatly appreciated! – legenw84it Aug 29 '21 at 14:49
  • 1
    @serving__ That advice about closing a stream also applies to streams for **JDBC objects** such as statements, result sets, and connections. In other words, if you would close a thing without a stream, then close a stream that wraps that thing. – Basil Bourque Aug 29 '21 at 21:02
1

Make sample data.

List < String > inputs = List.of( "a/b/c" , "d/e/f" , "g/h/i" );

Make an empty array in which to put results.

List < String > result = new ArrayList <>( inputs.size() * 3 );

Make a stream of the elements of our input list.

For each of those elements, those String objects, call String#split to produce an array of three separate String object. Each of the three is the individual letter. Convert the array into a List via List.of. Add that list of String objects (letters) to our results list.

inputs
        .stream()
        .forEach( s -> result.addAll( List.of( s.split( "/" ) ) ) );

Dump to console.

System.out.println( "result = " + result );

There is probably a way to fold the results list creation into the line of stream code, similar to this. But I am not yet a Streams Ninja.

Lastly, usually best to return an unmodifiable collection. Call List.copyOf.

return List.copyOf( result ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • I just came back and added a solution that worked for me, and you used a similar one. I'm curious, is stream() a fine thing to use even if I'm dealing with large data? wouldn't it "overload" the memory? – legenw84it Aug 29 '21 at 02:16
  • 1
    @serving__ No problem with that. Streams basically work like loops, processing one element at a time, at least for the scenario shown in my Answer. Your code and mine are equivalent. I prefer your code. My use of streams adds no value over yours. – Basil Bourque Aug 29 '21 at 04:18