Merge remote-tracking branch 'refs/remotes/eugenp/master'

This commit is contained in:
iaforek
2017-04-16 08:22:10 +01:00
238 changed files with 6661 additions and 1174 deletions
+1
View File
@@ -0,0 +1 @@
/target/
+1
View File
@@ -4,3 +4,4 @@
- [Introduction to Cobertura](http://www.baeldung.com/cobertura)
- [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization)
- [Validating Input With Finite Automata in Java](http://www.baeldung.com/finite-automata-java)
- [Introduction to Jenetics Library](http://www.baeldung.com/jenetics)
+5
View File
@@ -31,6 +31,11 @@
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.jenetics</groupId>
<artifactId>jenetics</artifactId>
<version>3.7.0</version>
</dependency>
</dependencies>
<build>
@@ -0,0 +1,47 @@
package com.baeldung.algorithms.ga.jenetics;
import static org.jenetics.engine.EvolutionResult.toBestPhenotype;
import static org.jenetics.engine.limit.bySteadyFitness;
import java.util.stream.Stream;
import org.jenetics.BitChromosome;
import org.jenetics.BitGene;
import org.jenetics.Mutator;
import org.jenetics.Phenotype;
import org.jenetics.RouletteWheelSelector;
import org.jenetics.SinglePointCrossover;
import org.jenetics.TournamentSelector;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionStatistics;
//The main class.
public class Knapsack {
public static void main(String[] args) {
int nItems = 15;
double ksSize = nItems * 100.0 / 3.0;
KnapsackFF ff = new KnapsackFF(Stream.generate(KnapsackItem::random)
.limit(nItems)
.toArray(KnapsackItem[]::new), ksSize);
Engine<BitGene, Double> engine = Engine.builder(ff, BitChromosome.of(nItems, 0.5))
.populationSize(500)
.survivorsSelector(new TournamentSelector<>(5))
.offspringSelector(new RouletteWheelSelector<>())
.alterers(new Mutator<>(0.115), new SinglePointCrossover<>(0.16))
.build();
EvolutionStatistics<Double, ?> statistics = EvolutionStatistics.ofNumber();
Phenotype<BitGene, Double> best = engine.stream()
.limit(bySteadyFitness(7))
.limit(100)
.peek(statistics)
.collect(toBestPhenotype());
System.out.println(statistics);
System.out.println(best);
}
}
@@ -0,0 +1,25 @@
package com.baeldung.algorithms.ga.jenetics;
import java.util.function.Function;
import org.jenetics.BitChromosome;
import org.jenetics.BitGene;
import org.jenetics.Genotype;
public class KnapsackFF implements Function<Genotype<BitGene>, Double> {
private KnapsackItem[] items;
private double size;
public KnapsackFF(KnapsackItem[] items, double size) {
this.items = items;
this.size = size;
}
@Override
public Double apply(Genotype<BitGene> gt) {
KnapsackItem sum = ((BitChromosome) gt.getChromosome()).ones()
.mapToObj(i -> items[i])
.collect(KnapsackItem.toSum());
return sum.size <= this.size ? sum.value : 0;
}
}
@@ -0,0 +1,34 @@
package com.baeldung.algorithms.ga.jenetics;
import java.util.Random;
import java.util.stream.Collector;
import org.jenetics.util.RandomRegistry;
public class KnapsackItem {
public double size;
public double value;
public KnapsackItem(double size, double value) {
this.size = size;
this.value = value;
}
protected static KnapsackItem random() {
Random r = RandomRegistry.getRandom();
return new KnapsackItem(r.nextDouble() * 100, r.nextDouble() * 100);
}
protected static Collector<KnapsackItem, ?, KnapsackItem> toSum() {
return Collector.of(() -> new double[2], (a, b) -> {
a[0] += b.size;
a[1] += b.value;
} , (a, b) -> {
a[0] += b[0];
a[1] += b[1];
return a;
} , r -> new KnapsackItem(r[0], r[1]));
}
}
@@ -0,0 +1,33 @@
package com.baeldung.algorithms.ga.jenetics;
import org.jenetics.BitChromosome;
import org.jenetics.BitGene;
import org.jenetics.Genotype;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionResult;
import org.jenetics.util.Factory;
public class SimpleGeneticAlgorithm {
private static Integer eval(Genotype<BitGene> gt) {
return gt.getChromosome()
.as(BitChromosome.class)
.bitCount();
}
public static void main(String[] args) {
Factory<Genotype<BitGene>> gtf = Genotype.of(BitChromosome.of(10, 0.5));
System.out.println("Before the evolution:\n" + gtf);
Engine<BitGene, Integer> engine = Engine.builder(SimpleGeneticAlgorithm::eval, gtf)
.build();
Genotype<BitGene> result = engine.stream()
.limit(500)
.collect(EvolutionResult.toBestGenotype());
System.out.println("After the evolution:\n" + result);
}
}
@@ -0,0 +1,86 @@
package com.baeldung.algorithms.ga.jenetics;
import static java.util.Objects.requireNonNull;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.jenetics.BitGene;
import org.jenetics.engine.Codec;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionResult;
import org.jenetics.engine.Problem;
import org.jenetics.engine.codecs;
import org.jenetics.util.ISeq;
public class SpringsteenProblem implements Problem<ISeq<SpringsteenRecord>, BitGene, Double> {
private ISeq<SpringsteenRecord> records;
private double maxPricePerUniqueSong;
public SpringsteenProblem(ISeq<SpringsteenRecord> records, double maxPricePerUniqueSong) {
this.records = requireNonNull(records);
this.maxPricePerUniqueSong = maxPricePerUniqueSong;
}
@Override
public Function<ISeq<SpringsteenRecord>, Double> fitness() {
return SpringsteenRecords -> {
double cost = SpringsteenRecords.stream()
.mapToDouble(r -> r.price)
.sum();
int uniqueSongCount = SpringsteenRecords.stream()
.flatMap(r -> r.songs.stream())
.collect(Collectors.toSet())
.size();
double pricePerUniqueSong = cost / uniqueSongCount;
return pricePerUniqueSong <= maxPricePerUniqueSong ? uniqueSongCount : 0.0;
};
}
@Override
public Codec<ISeq<SpringsteenRecord>, BitGene> codec() {
return codecs.ofSubSet(records);
}
public static void main(String[] args) {
double maxPricePerUniqueSong = 2.5;
SpringsteenProblem springsteen = new SpringsteenProblem(
ISeq.of(new SpringsteenRecord("SpringsteenRecord1", 25, ISeq.of("Song1", "Song2", "Song3", "Song4", "Song5", "Song6")), new SpringsteenRecord("SpringsteenRecord2", 15, ISeq.of("Song2", "Song3", "Song4", "Song5", "Song6", "Song7")),
new SpringsteenRecord("SpringsteenRecord3", 35, ISeq.of("Song5", "Song6", "Song7", "Song8", "Song9", "Song10")), new SpringsteenRecord("SpringsteenRecord4", 17, ISeq.of("Song9", "Song10", "Song12", "Song4", "Song13", "Song14")),
new SpringsteenRecord("SpringsteenRecord5", 29, ISeq.of("Song1", "Song2", "Song13", "Song14", "Song15", "Song16")), new SpringsteenRecord("SpringsteenRecord6", 5, ISeq.of("Song18", "Song20", "Song30", "Song40"))),
maxPricePerUniqueSong);
Engine<BitGene, Double> engine = Engine.builder(springsteen)
.build();
ISeq<SpringsteenRecord> result = springsteen.codec()
.decoder()
.apply(engine.stream()
.limit(10)
.collect(EvolutionResult.toBestGenotype()));
double cost = result.stream()
.mapToDouble(r -> r.price)
.sum();
int uniqueSongCount = result.stream()
.flatMap(r -> r.songs.stream())
.collect(Collectors.toSet())
.size();
double pricePerUniqueSong = cost / uniqueSongCount;
System.out.println("Overall cost: " + cost);
System.out.println("Unique songs: " + uniqueSongCount);
System.out.println("Cost per song: " + pricePerUniqueSong);
System.out.println("Records: " + result.map(r -> r.name)
.toString(", "));
}
}
@@ -0,0 +1,24 @@
package com.baeldung.algorithms.ga.jenetics;
import static java.util.Objects.requireNonNull;
import org.jenetics.util.ISeq;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class SpringsteenRecord {
String name;
double price;
ISeq<String> songs;
public SpringsteenRecord(String name, double price, ISeq<String> songs) {
this.name = requireNonNull(name);
this.price = price;
this.songs = requireNonNull(songs);
}
}
@@ -0,0 +1,66 @@
package com.baeldung.algorithms.ga.jenetics;
import static java.util.Objects.requireNonNull;
import java.util.Random;
import java.util.function.Function;
import org.jenetics.EnumGene;
import org.jenetics.Mutator;
import org.jenetics.PartiallyMatchedCrossover;
import org.jenetics.Phenotype;
import org.jenetics.engine.Codec;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionResult;
import org.jenetics.engine.Problem;
import org.jenetics.engine.codecs;
import org.jenetics.engine.limit;
import org.jenetics.util.ISeq;
import org.jenetics.util.LCG64ShiftRandom;
public class SubsetSum implements Problem<ISeq<Integer>, EnumGene<Integer>, Integer> {
private ISeq<Integer> basicSet;
private int size;
public SubsetSum(ISeq<Integer> basicSet, int size) {
this.basicSet = requireNonNull(basicSet);
this.size = size;
}
@Override
public Function<ISeq<Integer>, Integer> fitness() {
return subset -> Math.abs(subset.stream()
.mapToInt(Integer::intValue)
.sum());
}
@Override
public Codec<ISeq<Integer>, EnumGene<Integer>> codec() {
return codecs.ofSubSet(basicSet, size);
}
public static SubsetSum of(int n, int k, Random random) {
return new SubsetSum(random.doubles()
.limit(n)
.mapToObj(d -> (int) ((d - 0.5) * n))
.collect(ISeq.toISeq()), k);
}
public static void main(String[] args) {
SubsetSum problem = of(500, 15, new LCG64ShiftRandom(101010));
Engine<EnumGene<Integer>, Integer> engine = Engine.builder(problem)
.minimizing()
.maximalPhenotypeAge(5)
.alterers(new PartiallyMatchedCrossover<>(0.4), new Mutator<>(0.3))
.build();
Phenotype<EnumGene<Integer>, Integer> result = engine.stream()
.limit(limit.bySteadyFitness(55))
.collect(EvolutionResult.toBestPhenotype());
System.out.print(result);
}
}
@@ -0,0 +1,67 @@
package com.baeldung.algorithms.ga.jenetics;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
import static java.lang.Math.sin;
import static org.jenetics.engine.EvolutionResult.toBestPhenotype;
import static org.jenetics.engine.limit.bySteadyFitness;
import java.util.stream.IntStream;
import org.jenetics.EnumGene;
import org.jenetics.Optimize;
import org.jenetics.PartiallyMatchedCrossover;
import org.jenetics.Phenotype;
import org.jenetics.SwapMutator;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionStatistics;
import org.jenetics.engine.codecs;
public class TravelingSalesman {
private static final int STOPS = 50;
private static final double[][] ADJACENCE = matrix(STOPS);
private static double[][] matrix(int stops) {
final double radius = 100.0;
double[][] matrix = new double[stops][stops];
for (int i = 0; i < stops; ++i) {
for (int j = 0; j < stops; ++j) {
matrix[i][j] = chord(stops, abs(i - j), radius);
}
}
return matrix;
}
private static double chord(int stops, int i, double r) {
return 2.0 * r * abs(sin(PI * i / stops));
}
private static double dist(final int[] path) {
return IntStream.range(0, STOPS)
.mapToDouble(i -> ADJACENCE[path[i]][path[(i + 1) % STOPS]])
.sum();
}
public static void main(String[] args) {
final Engine<EnumGene<Integer>, Double> engine = Engine.builder(TravelingSalesman::dist, codecs.ofPermutation(STOPS))
.optimize(Optimize.MINIMUM)
.maximalPhenotypeAge(11)
.populationSize(500)
.alterers(new SwapMutator<>(0.2), new PartiallyMatchedCrossover<>(0.35))
.build();
final EvolutionStatistics<Double, ?> statistics = EvolutionStatistics.ofNumber();
final Phenotype<EnumGene<Integer>, Double> best = engine.stream()
.limit(bySteadyFitness(15))
.limit(250)
.peek(statistics)
.collect(toBestPhenotype());
System.out.println(statistics);
System.out.println(best);
}
}
@@ -2,10 +2,10 @@ package com.baeldung.algorithms.primechecker;
import java.math.BigInteger;
public class BigIntegerPrimeChecker implements PrimeChecker{
public class BigIntegerPrimeChecker implements PrimeChecker<Long>{
@Override
public boolean isPrime(int number) {
public boolean isPrime(Long number) {
BigInteger bigInt = BigInteger.valueOf(number);
return bigInt.isProbablePrime(100);
}
@@ -1,12 +1,15 @@
package com.baeldung.algorithms.primechecker;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class BruteForcePrimeChecker implements PrimeChecker{
public class BruteForcePrimeChecker implements PrimeChecker<Integer>{
@Override
public boolean isPrime(int number) {
return IntStream.range(2, number).noneMatch(n -> (number % n == 0));
public boolean isPrime(Integer number) {
return number > 2 ? IntStream.range(2, number)
.noneMatch(n -> (number % n == 0)) : false;
}
@@ -1,13 +1,14 @@
package com.baeldung.algorithms.primechecker;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class OptimisedPrimeChecker implements PrimeChecker{
public class OptimisedPrimeChecker implements PrimeChecker<Integer>{
@Override
public boolean isPrime(int number) {
return IntStream.range(2, (int)Math.sqrt(number) + 1)
.noneMatch(n -> (number % n == 0));
public boolean isPrime(Integer number) {
return number > 2 ? IntStream.rangeClosed(2, (int) Math.sqrt(number))
.noneMatch(n -> (number % n == 0)) : false;
}
@@ -1,6 +1,6 @@
package com.baeldung.algorithms.primechecker;
public interface PrimeChecker {
public interface PrimeChecker <T> {
public boolean isPrime( int number );
public boolean isPrime( T number );
}
@@ -2,10 +2,10 @@ package com.baeldung.algorithms.primechecker;
import org.apache.commons.math3.primes.Primes;
public class PrimesPrimeChecker implements PrimeChecker{
public class PrimesPrimeChecker implements PrimeChecker<Integer>{
@Override
public boolean isPrime(int number) {
public boolean isPrime(Integer number) {
return Primes.isPrime(number);
}
@@ -9,18 +9,20 @@ import com.baeldung.algorithms.primechecker.PrimeChecker;
public class BigIntegerPrimeCheckerTest {
PrimeChecker primeChecker = new BigIntegerPrimeChecker();
BigIntegerPrimeChecker primeChecker = new BigIntegerPrimeChecker();
@Test
public void givenPrimeNumber_whenCheckIsPrime_thenTrue(){
assertTrue(primeChecker.isPrime(13));
assertTrue(primeChecker.isPrime(1009));
assertTrue(primeChecker.isPrime(13l));
assertTrue(primeChecker.isPrime(1009L));
assertTrue(primeChecker.isPrime(74207281L));
}
@Test
public void givenNonPrimeNumber_whenCheckIsPrime_thenFalse(){
assertTrue(!primeChecker.isPrime(50));
assertTrue(!primeChecker.isPrime(1001));
assertTrue(!primeChecker.isPrime(50L));
assertTrue(!primeChecker.isPrime(1001L));
assertTrue(!primeChecker.isPrime(74207282L));
}
}
@@ -9,7 +9,7 @@ import com.baeldung.algorithms.primechecker.PrimeChecker;
public class OptimisedPrimeCheckerTest {
PrimeChecker primeChecker = new OptimisedPrimeChecker();
OptimisedPrimeChecker primeChecker = new OptimisedPrimeChecker();
@Test
public void givenPrimeNumber_whenCheckIsPrime_thenTrue(){
@@ -8,7 +8,7 @@ import com.baeldung.algorithms.primechecker.PrimeChecker;
import com.baeldung.algorithms.primechecker.PrimesPrimeChecker;
public class PrimesPrimeCheckerTest {
PrimeChecker primeChecker = new PrimesPrimeChecker();
PrimesPrimeChecker primeChecker = new PrimesPrimeChecker();
@Test
public void givenPrimeNumber_whenCheckIsPrime_thenTrue() {
+3 -3
View File
@@ -101,9 +101,7 @@
<dependency>
<groupId>org.dbdoclet</groupId>
<artifactId>herold</artifactId>
<version>6.1.0</version>
<scope>system</scope>
<systemPath>${basedir}/src/test/resources/jars/herold.jar</systemPath>
<version>8.0.4</version>
</dependency>
<dependency>
@@ -140,6 +138,8 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
<exclude>**/*LiveTest.java</exclude>
@@ -19,21 +19,21 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.xmlgraphics.util.MimeConstants;
import org.dbdoclet.trafo.html.docbook.DocBookTransformer;
import org.dbdoclet.trafo.html.docbook.HtmlDocBookTrafo;
import org.dbdoclet.trafo.script.Script;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.tidy.Tidy;
public class ApacheFOPConvertHTMLIntegrationTest {
private String inputFile = "src/test/resources/input.html";
private String style = "src/test/resources/xhtml2fo.xsl";
private String style1 = "src/test/resources/docbook-xsl/fo/docbook.xsl";
private String output_jtidy = "src/test/resources/output_jtidy.pdf";
private String output_html2fo = "src/test/resources/output_html2fo.pdf";
private String output_herold = "src/test/resources/output_herold.pdf";
private String foFile = "src/test/resources/input.fo";
private String xmlFile = "src/test/resources/input.xml";
private final String inputFile = "src/test/resources/input.html";
private final String style = "src/test/resources/xhtml2fo.xsl";
private final String style1 = "src/test/resources/docbook-xsl/fo/docbook.xsl";
private final String output_jtidy = "src/test/resources/output_jtidy.pdf";
private final String output_html2fo = "src/test/resources/output_html2fo.pdf";
private final String output_herold = "src/test/resources/output_herold.pdf";
private final String foFile = "src/test/resources/input.fo";
private final String xmlFile = "src/test/resources/input.xml";
@Test
public void whenTransformHTMLToPDFUsingJTidy_thenCorrect() throws Exception {
@@ -114,8 +114,9 @@ public class ApacheFOPConvertHTMLIntegrationTest {
private void fromHTMLTOXMLUsingHerold() throws Exception {
final Script script = new Script();
final DocBookTransformer transformer = new DocBookTransformer();
transformer.setScript(script);
transformer.convert(new FileInputStream(inputFile), new FileOutputStream(xmlFile));
final HtmlDocBookTrafo transformer = new HtmlDocBookTrafo();
transformer.setInputStream(new FileInputStream(inputFile));
transformer.setOutputStream(new FileOutputStream(xmlFile));
transformer.transform(script);
}
}
@@ -10,6 +10,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.xml.transform.Result;
@@ -25,19 +26,15 @@ import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.xmlgraphics.util.MimeConstants;
import org.dbdoclet.trafo.TrafoScriptManager;
import org.dbdoclet.trafo.html.docbook.DocBookTransformer;
import org.dbdoclet.trafo.html.docbook.HtmlDocBookTrafo;
import org.dbdoclet.trafo.script.Script;
import org.junit.Test;
import org.w3c.dom.Document;
public class ApacheFOPHeroldLiveTest {
private String[] inputUrls = {// @formatter:off
"http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/",
"http://www.baeldung.com/2011/10/25/building-a-restful-web-service-with-spring-3-1-and-java-based-configuration-part-2/",
"http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/",
"http://www.baeldung.com/spring-security-basic-authentication",
"http://www.baeldung.com/spring-security-digest-authentication",
"http://www.baeldung.com/2011/11/20/basic-and-digest-authentication-for-a-restful-service-with-spring-security-3-1/",
private final String[] inputUrls = {// @formatter:off
// "http://www.baeldung.com/spring-security-basic-authentication",
"http://www.baeldung.com/spring-security-digest-authentication"
//"http://www.baeldung.com/spring-httpmessageconverter-rest",
//"http://www.baeldung.com/2011/11/06/restful-web-service-discoverability-part-4/",
//"http://www.baeldung.com/2011/11/13/rest-service-discoverability-with-spring-part-5/",
@@ -49,10 +46,10 @@ public class ApacheFOPHeroldLiveTest {
//"http://www.baeldung.com/2013/01/18/testing-rest-with-multiple-mime-types/"
}; // @formatter:on
private String style_file = "src/test/resources/docbook-xsl/fo/docbook.xsl";
private String output_file = "src/test/resources/final_output.pdf";
private String xmlInput = "src/test/resources/input.xml";
private String xmlOutput = "src/test/resources/output.xml";
private final String style_file = "src/test/resources/docbook-xsl/fo/docbook.xsl";
private final String output_file = "src/test/resources/final_output.pdf";
private final String xmlInput = "src/test/resources/input.xml";
private final String xmlOutput = "src/test/resources/output.xml";
// tests
@@ -75,10 +72,11 @@ public class ApacheFOPHeroldLiveTest {
final TrafoScriptManager mgr = new TrafoScriptManager();
final File profileFile = new File("src/test/resources/default.her");
script = mgr.parseScript(profileFile);
final DocBookTransformer transformer = new DocBookTransformer();
transformer.setScript(script);
final HtmlDocBookTrafo transformer = new HtmlDocBookTrafo();
transformer.setInputStream(getInputStream(input));
transformer.setOutputStream(new FileOutputStream(xmlInput, append));
transformer.convert(getInputStream(input), new FileOutputStream(xmlInput, append));
transformer.transform(script);
}
private Document fromXMLFileToFO() throws Exception {
@@ -112,7 +110,9 @@ public class ApacheFOPHeroldLiveTest {
private InputStream getInputStream(final String input) throws IOException {
final URL url = new URL(input);
return url.openStream();
final HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
httpcon.addRequestProperty("User-Agent", "Mozilla/4.0");
return httpcon.getInputStream();
}
private void fixXML(final String input, final String output) throws IOException {
@@ -127,7 +127,7 @@ public class ApacheFOPHeroldLiveTest {
if (line.contains("info>")) {
writer.write(line.replace("info>", "section>"));
} else if (!((line.startsWith("<?xml") || line.startsWith("<article") || line.startsWith("</article")) && count > 4)) {
} else if (!((line.startsWith("<?xml") || line.startsWith("<article") || line.startsWith("</article")) && (count > 4))) {
writer.write(line.replaceAll("xml:id=\"", "xml:id=\"" + count));
}
writer.write("\n");
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,82 @@
package com.baeldung.java9.reactive;
import java.util.ArrayList;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;
public class BaeldungBatchSubscriberImpl<T> implements Subscriber<String> {
private Subscription subscription;
private boolean completed = false;
private int counter;
private ArrayList<String> buffer;
public static final int BUFFER_SIZE = 5;
public BaeldungBatchSubscriberImpl() {
buffer = new ArrayList<String>();
}
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
subscription.request(BUFFER_SIZE);
}
@Override
public void onNext(String item) {
buffer.add(item);
// if buffer is full, process the items.
if (buffer.size() >= BUFFER_SIZE) {
processBuffer();
}
//request more items.
subscription.request(1);
}
private void processBuffer() {
if (buffer.isEmpty())
return;
// Process all items in the buffer. Here, we just print it and sleep for 1 second.
System.out.print("Processed items: ");
buffer.stream()
.forEach(item -> {
System.out.print(" " + item);
});
System.out.println();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter = counter + buffer.size();
buffer.clear();
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onComplete() {
completed = true;
// process any remaining items in buffer before
processBuffer();
subscription.cancel();
}
}
@@ -0,0 +1,55 @@
package com.baeldung.java9.reactive;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;
public class BaeldungSubscriberImpl<T> implements Subscriber<String> {
private Subscription subscription;
private boolean completed = false;
private int counter;
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
subscription.request(1);
}
@Override
public void onNext(String item) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter++;
System.out.println("Processed item : " + item);
subscription.request(1);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onComplete() {
completed = true;
subscription.cancel();
}
}
@@ -0,0 +1,75 @@
package com.baeldung.java9.reactive;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.SubmissionPublisher;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Stopwatch;
public class BaeldungBatchSubscriberImplTest {
private static final int ITEM_SIZE = 10;
private SubmissionPublisher<String> publisher;
private BaeldungBatchSubscriberImpl<String> subscriber;
@Before
public void initialize() {
this.publisher = new SubmissionPublisher<String>(ForkJoinPool.commonPool(), 6);
this.subscriber = new BaeldungBatchSubscriberImpl<String>();
publisher.subscribe(subscriber);
}
@Rule
public Stopwatch stopwatch = new Stopwatch() {
};
@Test
public void testReactiveStreamCount() {
IntStream.range(0, ITEM_SIZE)
.forEach(item -> publisher.submit(item + ""));
publisher.close();
do {
// wait for subscribers to complete all processing.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (!subscriber.isCompleted());
int count = subscriber.getCounter();
assertEquals(ITEM_SIZE, count);
}
@Test
public void testReactiveStreamTime() {
IntStream.range(0, ITEM_SIZE)
.forEach(item -> publisher.submit(item + ""));
publisher.close();
do {
// wait for subscribers to complete all processing.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (!subscriber.isCompleted());
// The runtime in seconds should be equal to the number of items in each batch.
assertTrue(stopwatch.runtime(TimeUnit.SECONDS) >= (ITEM_SIZE / subscriber.BUFFER_SIZE));
}
}
@@ -0,0 +1,100 @@
package com.baeldung.java9.reactive;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.SubmissionPublisher;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Stopwatch;
public class BaeldungSubscriberImplTest {
private static final int ITEM_SIZE = 10;
private SubmissionPublisher<String> publisher;
private BaeldungSubscriberImpl<String> subscriber;
@Before
public void initialize() {
// create Publisher with max buffer capacity 3.
this.publisher = new SubmissionPublisher<String>(ForkJoinPool.commonPool(), 3);
this.subscriber = new BaeldungSubscriberImpl<String>();
publisher.subscribe(subscriber);
}
@Rule
public Stopwatch stopwatch = new Stopwatch() {
};
@Test
public void testReactiveStreamCount() {
IntStream.range(0, ITEM_SIZE)
.forEach(item -> publisher.submit(item + ""));
publisher.close();
do {
// wait for subscribers to complete all processing.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (!subscriber.isCompleted());
int count = subscriber.getCounter();
assertEquals(ITEM_SIZE, count);
}
@Test
public void testReactiveStreamTime() {
IntStream.range(0, ITEM_SIZE)
.forEach(item -> publisher.submit(item + ""));
publisher.close();
do {
// wait for subscribers to complete all processing.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (!subscriber.isCompleted());
// The runtime in seconds should be equal to the number of items.
assertTrue(stopwatch.runtime(TimeUnit.SECONDS) >= ITEM_SIZE);
}
@Test
public void testReactiveStreamOffer() {
IntStream.range(0, ITEM_SIZE)
.forEach(item -> publisher.offer(item + "", (subscriber, string) -> {
// Returning false means this item will be dropped (no retry), if blocked.
return false;
}));
publisher.close();
do {
// wait for subscribers to complete all processing.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (!subscriber.isCompleted());
int count = subscriber.getCounter();
// Because 10 items were offered and the buffer capacity was 3, few items will not be processed.
assertTrue(ITEM_SIZE > count);
}
}
+6
View File
@@ -11,6 +11,9 @@
- [Converting between a List and a Set in Java](http://www.baeldung.com/convert-list-to-set-and-set-to-list)
- [Convert a Map to an Array, List or Set in Java](http://www.baeldung.com/convert-map-values-to-array-list-set)
- [Java – Write to File](http://www.baeldung.com/java-write-to-file)
- [Java - Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream)
- [Java – Random Long, Float, Integer and Double](http://www.baeldung.com/java-generate-random-long-float-integer-double)
- [Java – Generate Random String](http://www.baeldung.com/java-random-string)
- [Java Scanner](http://www.baeldung.com/java-scanner)
- [Java Timer](http://www.baeldung.com/java-timer-and-timertask)
- [Java – Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer)
@@ -85,4 +88,7 @@
- [Java Primitive Conversions](http://www.baeldung.com/java-primitive-conversions)
- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency)
- [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing)
- [Avoiding ConcurrentModificationException when iterating and removing](http://www.baeldung.com/avoiding-concurrentmodificationexception-when-iterating-and-removing)
- [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list)
- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list)
+8 -2
View File
@@ -170,7 +170,13 @@
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>1.1</version>
</dependency>
</dependency>
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>2.1.0.1</version>
</dependency>
</dependencies>
@@ -391,4 +397,4 @@
</properties>
</project>
</project>

Some files were not shown because too many files have changed in this diff Show More