Spliterator Java 8 -


i have number 1 10,000 stored in array of long. when adding them sequentially give result of 50,005,000.
have writing spliterator if size of array longer 1000, splitted array. here code. when run it, result addition far greater 50,005,000. can tell me wrong code?

thank much.

import java.util.arrays; import java.util.optional; import java.util.spliterator; import java.util.function.consumer; import java.util.stream.longstream; import java.util.stream.stream; import java.util.stream.streamsupport;  public class sumspliterator implements spliterator<long> {      private final long[] numbers;     private int currentposition = 0;      public sumspliterator(long[] numbers) {         super();         this.numbers = numbers;     }      @override     public boolean tryadvance(consumer<? super long> action) {         action.accept(numbers[currentposition++]);         return currentposition < numbers.length;     }      @override     public long estimatesize() {         return numbers.length - currentposition;     }      @override     public int characteristics() {         return subsized;     }      @override     public spliterator<long> trysplit() {         int currentsize = numbers.length - currentposition;          if( currentsize <= 1_000){             return null;         }else{             currentposition = currentposition + 1_000;             return new sumspliterator(arrays.copyofrange(numbers, 1_000, numbers.length));         }     }      public static void main(string[] args) {          long[] twothousandnumbers = longstream.rangeclosed(1, 10_000).toarray();          spliterator<long> spliterator = new sumspliterator(twothousandnumbers);         stream<long> stream = streamsupport.stream(spliterator, false);          system.out.println( sumvalues(stream) );     }      private static long sumvalues(stream<long> stream){         optional<long> optional = stream.reduce( ( t, u) ->  t + u );          return optional.get() != null ? optional.get() : long.valueof(0);     }  } 

i have strong feeling didn’t purpose of splitting right. it’s not meant copy underlying data provide access range of it. keep in mind spliterators provide read-only access. should pass original array new spliterator , configure appropriate position , length instead of copying array.

but besides inefficiency of copying, logic wrong: pass arrays.copyofrange(numbers, 1_000, numbers.length) new spliterator, new spliterator contains elements position 1000 end of array , advance current spliterator’s position 1000, old spliterator covers elements currentposition + 1_000 end of array. both spliterators cover elements @ end of array while @ same time, depending on previous value of currentposition, elements @ beginning might not covered @ all. when want advance currentposition 1_000 skipped range expressed arrays.copyofrange(numbers, currentposition, 1_000) instead, referring currentposition before advancing.

it’s should noted, spliterator should attempt split balanced, is, in middle if size known. splitting off thousand elements not right strategy array.

further, tryadvance method wrong. should not test after calling consumer before, returning false if there no more elements, implies consumer has not been called.

putting together, implementation may like

public class myarrayspliterator implements spliterator<long> {      private final long[] numbers;     private int currentposition, endposition;      public myarrayspliterator(long[] numbers) {         this(numbers, 0, numbers.length);     }     public myarrayspliterator(long[] numbers, int start, int end) {         this.numbers = numbers;         currentposition=start;         endposition=end;     }      @override     public boolean tryadvance(consumer<? super long> action) {         if(currentposition < endposition) {             action.accept(numbers[currentposition++]);             return true;         }         return false;     }      @override     public long estimatesize() {         return endposition - currentposition;     }      @override     public int characteristics() {         return ordered|nonnull|sized|subsized;     }      @override     public spliterator<long> trysplit() {         if(estimatesize()<=1000) return null;         int middle = (endposition + currentposition)>>>1;         myarrayspliterator prefix                            = new myarrayspliterator(numbers, currentposition, middle);         currentposition=middle;         return prefix;     } } 

but of course, it’s recommended provide specialized foreachremaining implementation, possible:

@override public void foreachremaining(consumer<? super long> action) {     int pos=currentposition, end=endposition;     currentposition=end;     for(;pos<end; pos++) action.accept(numbers[pos]); } 

as final note, task of summing longs array, spliterator.oflong , longstream preferred , work has been done, see arrays.spliterator() , longstream.sum(), making whole task simple arrays.stream(numbers).sum().


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -