#Best way to get sublist in a stream?

68 messages · Page 1 of 1 (latest)

uneven mango
#

hi there
does anyone know when you are streaming through a list, how do you make a sublist that goes from element 1 to the final element

        List<Integer> timeNumbers =
                Arrays.stream(s.split("\n")[0].split(" ")).filter(b -> !(b.isEmpty())).collect(Collectors.toList()).subList(1, 5).stream().map(Integer::valueOf).collect(Collectors.toList());

i was trying to make this list of integers from this input:

Time:        57     72     69     92
Distance:   291   1172   1176   2026

(for advent of code)

foggy micaBOT
#

This post has been reserved for your question.

Hey @uneven mango! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

rapid epoch
#

Your code does that already

uneven mango
#

sorry, i meant like

#

whats a better way

#

i.e. if i didnt know how long my list of times and distances were

rapid epoch
#

slightly simplified

List<Integer> timeNumbers = Arrays.stream(s.split("\n")[0].split(" "))
        .filter(b -> !(b.isEmpty()))
        .mapToInt(Integer::valueOf)
        .collect(ArrayList<Integer>::new, (a, b) -> a.add(b), (a, b) -> a.addAll(b))
        .subList(1, 5);
#

If you want to have it flexible for the length of the array, you can extract the array to a variable and then use the length in the sublist method:

#
String[] array = s.split("\n")[0].split(" ");
List<Integer> timeNumbers = Arrays.stream(array)
        .filter(b -> !(b.isEmpty()))
        .mapToInt(Integer::valueOf)
        .collect(ArrayList<Integer>::new, (a, b) -> a.add(b), (a, b) -> a.addAll(b))
        .subList(1, array.length);
foggy micaBOT
#

💤 Post marked as dormant

This post has been inactive for over 300 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.
In case your post is not getting any attention, you can try to use /help ping.
Warning: abusing this will result in moderative actions taken against you.

random smelt
#

You are not looking to create a sublist but to skip the first element:

Arrays.stream(s.split("\n")[0].split(" +"))
                .skip(1)
                .map(Integer::valueOf)
                .collect(Collectors.toCollection(ArrayList::new));

(Note: I used + instead of as the pattern since the former matches any number of consecutive spaces meaning that you won't get any empty Strings in your stream)

uneven mango
#

is that a regex?

#

like \n?

#

or whatever its called

random smelt
#

Thats regex. The + matches the preceeding charqcter between one and unlimited times.

uneven mango
#

ohhh i see

#

so i could do like, "o+"

#

and itd be however many o's in a row

random smelt
uneven mango
#

ah right, backslash is escape, i forgot the word

random smelt
uneven mango
#

so, since the original text

#

has 2 lines

#

and i want both rows to do the same thing, but for each line

#

is there a way to repeat it and spit out 2 separate lists

#

im just trying to be more concise with my code where possible and automate more, as practise and to learn different things that can be done in a language

random smelt
#

Well if your goal is to have two separate lists at the end then no that is not possible.
If you want a nested list or an Array of Lists then you could do that. However, generally I would prioritize more readable code. So if you have to repeat the same lambda expresison for a second time but the code is cleaner definitely do that.

uneven mango
#

also, what is this line doing -
.collect(Collectors.toCollection(ArrayList::new));

#

the arrayist part

random smelt
#

The ArrayList::new ?

uneven mango
#

yea the arraylist::new

random smelt
#

Thats a method reference.

mellow niche
#

collects all elements into one collection, created by the method reference (ArrayList::new references the constructor on ArrayList, fitting the supplier interface's parameter list)

uneven mango
#

but is new a method in arraylist?

mellow niche
#

in this case it references the constructor taking no arguments, since a Supplier (the actual functional interface toCollection wants) doesn't allow for any arguments

uneven mango
#

i thought that new was like public or static or whatever

random smelt
#

Its referencing the constructor

mellow niche
#

"new" by itself isn't a method, but using "new" here references the constructor

#

if you were to do ArrayList::someMethod, that would actually reference "someMethod" in ArrayList

uneven mango
#

is this because there isnt a collect method called toArrayList?

random smelt
uneven mango
#

could you theoretically do (List::new) instead of toList

mellow niche
#

toCollection is more generic

uneven mango
#

thank you

foggy micaBOT
# uneven mango thank you

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.

uneven mango
#

ive been using the method operator to do simple things like toString or valueOf so far

#

is there a way to make an incrementing variable inside a lambda expression?

#

i know there is stream().forEach

#

but is there a way to increment for numbers?

random smelt
#

If your goal is to generate a stream of incrementing numbers you should use IntStream.range()

uneven mango
#

also, i saw above someone posted this:

.collect(ArrayList<Integer>::new, (a, b) -> a.add(b), (a, b) -> a.addAll(b))
#

what actually is going on here?

uneven mango
#

also sorry for all the questions, its just rare to have someone who actually can explain things well

random smelt
#

You cant use range in a for loop like in python. IntStream.range is a speical method exlusively belonging to IntStream that allows you to generate an IntStream of incrementing numbers. But you are correct that method has the same behavior as pythons range method.

uneven mango
#

i see, gotcha

#

were you able to explain what is happening in the collect? is it declaring 2 variables where you go a.add(b)? but what is a and b

random smelt
# uneven mango also, i saw above someone posted this: ```java .collect(ArrayList<Integer>::new,...

That method is basically implementing the Collector yourself. A Collector consists of 3 parts

  1. The supplier
  2. The accumulator
  3. The combiner

The supplier specifies in what kind of container the stream should be stored in. In our case this is an ArrayList
The accumulator defines what should happen to our elements when reducing the actual stream.
In our case ArrayList::add just means that the elements of the stream should be added to the arraylist.
The combiner only has a function when it comes to parallel streams. It combines the results of partial reductions. In our case we are just combining our Arraylists

#

But this is really simplified I recommend looking at the tutorial on this site : dev.java/learn

uneven mango
#

okay i willl do thank you

foggy micaBOT
# uneven mango okay i willl do thank you

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.

uneven mango
#

they didnt really cover anything useful in the course that was essentially intro to java at my uni

#

it was just the same stuff we did in python with some extra theory like liskovs substitution principle

random smelt
#

Yeah you'll learn the most stuff by just writing code yourself, so its a good thing that you started with advent of code. Small problems like these really help getting to know the language