Skip to content

Commit

Permalink
[#16] Joining collector class early draft; API proof-of-concept
Browse files Browse the repository at this point in the history
  • Loading branch information
amaembo committed Nov 1, 2015
1 parent daa1e80 commit d322c0c
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 4 deletions.
105 changes: 105 additions & 0 deletions src/main/java/javax/util/streamex/Joining.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2015 Tagir Valeev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.util.streamex;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import static javax.util.streamex.StreamExInternals.*;

/**
* @author Tagir Valeev
*/
public class Joining extends CancellableCollector<CharSequence, Joining.Accumulator, String>{
static class Accumulator {
List<CharSequence> data = new ArrayList<>();
int count = 0;
}

private final String delimiter;

private Joining(CharSequence delimiter) {
this.delimiter = delimiter.toString();
}

public static Joining with(CharSequence delimiter) {
return new Joining(delimiter);
}

@Override
public Supplier<Accumulator> supplier() {
return Accumulator::new;
}

@Override
public BiConsumer<Accumulator, CharSequence> accumulator() {
return (acc, str) -> {
if(!acc.data.isEmpty())
acc.count+=delimiter.length();
acc.count+=str.length();
acc.data.add(str);
};
}

@Override
public BinaryOperator<Accumulator> combiner() {
return (acc1, acc2) -> {
if(acc1.data.isEmpty())
return acc2;
if(acc2.data.isEmpty())
return acc1;
acc1.count+=delimiter.length()+acc2.count;
acc1.data.addAll(acc2.data);
return acc1;
};
}

@Override
public Function<Accumulator, String> finisher() {
return acc -> {
char[] buf = new char[acc.count];
int pos = 0;
int size = acc.data.size();
for(int i=0; i<size; i++) {
if(i > 0) {
delimiter.getChars(0, delimiter.length(), buf, pos);
pos+=delimiter.length();
}
String cs = acc.data.get(i).toString();
cs.getChars(0, cs.length(), buf, pos);
pos+=cs.length();
}
return new String(buf);
};
}

@Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
return Collections.emptySet();
}

@Override
Predicate<Accumulator> finished() {
return null;
}
}
38 changes: 38 additions & 0 deletions src/test/java/javax/util/streamex/JoiningTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2015 Tagir Valeev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.util.streamex;

import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static javax.util.streamex.TestHelpers.*;

import org.junit.Test;

/**
* @author Tagir Valeev
*/
public class JoiningTest {
@Test
public void testSimple() {
Collector<CharSequence, ?, String> joining = Joining.with(", ");
Supplier<Stream<String>> s = () -> IntStream.range(0, 100).mapToObj(String::valueOf);
checkCollector("joiningSimple", s.get().collect(Collectors.joining(", ")), s, joining);
}
}
8 changes: 4 additions & 4 deletions src/test/java/javax/util/streamex/TestHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ static <T, R> void checkCollectorEmpty(String message, R expected, Collector<T,
}

static <T, R> void checkShortCircuitCollector(String message, R expected, int expectedConsumedElements,
Supplier<Stream<T>> base, Collector<T, ?, R> collector) {
Supplier<Stream<T>> base, Collector<? super T, ?, R> collector) {
checkShortCircuitCollector(message, expected, expectedConsumedElements, base, collector, false);
}

static <T, R> void checkShortCircuitCollector(String message, R expected, int expectedConsumedElements,
Supplier<Stream<T>> base, Collector<T, ?, R> collector, boolean skipIdentity) {
Supplier<Stream<T>> base, Collector<? super T, ?, R> collector, boolean skipIdentity) {
assertNotNull(message, finished(collector));
Collector<T, ?, R> withIdentity = Collectors.collectingAndThen(collector, Function.identity());
Collector<? super T, ?, R> withIdentity = Collectors.collectingAndThen(collector, Function.identity());
for (StreamExSupplier<T> supplier : streamEx(base)) {
AtomicInteger counter = new AtomicInteger();
assertEquals(message + ": " + supplier, expected, supplier.get().peek(t -> counter.incrementAndGet())
Expand All @@ -128,7 +128,7 @@ static <T, R> void checkShortCircuitCollector(String message, R expected, int ex
}
}

static <T, R> void checkCollector(String message, R expected, Supplier<Stream<T>> base, Collector<T, ?, R> collector) {
static <T, R> void checkCollector(String message, R expected, Supplier<Stream<T>> base, Collector<? super T, ?, R> collector) {
// use checkShortCircuitCollector for CancellableCollector
assertNull(message, finished(collector));
for (StreamExSupplier<T> supplier : streamEx(base)) {
Expand Down

0 comments on commit d322c0c

Please sign in to comment.