Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
599cd1cc24
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class AmountBasedDiscountPolicy implements DiscountPolicy {
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
if (order.totalCost()
|
||||||
|
.isGreaterThan(Money.of(CurrencyUnit.USD, 500.00))) {
|
||||||
|
return 0.10;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
public interface DiscountPolicy {
|
||||||
|
double discount(Order order);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
public class FlatDiscountPolicy implements DiscountPolicy {
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0.01;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.OrderVisitor;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.Visitable;
|
||||||
|
|
||||||
|
public class Order extends com.baeldung.ddd.order.Order implements Visitable<OrderVisitor> {
|
||||||
|
public Order(List<OrderLine> orderLines) {
|
||||||
|
super(orderLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money totalCost(SpecialDiscountPolicy discountPolicy) {
|
||||||
|
return totalCost().multipliedBy(1 - applyDiscountPolicy(discountPolicy), RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double applyDiscountPolicy(SpecialDiscountPolicy discountPolicy) {
|
||||||
|
return discountPolicy.discount(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(OrderVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
public interface SpecialDiscountPolicy extends DiscountPolicy {
|
||||||
|
double discount(SpecialOrder order);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.OrderVisitor;
|
||||||
|
|
||||||
|
public class SpecialOrder extends Order {
|
||||||
|
|
||||||
|
private boolean eligibleForExtraDiscount;
|
||||||
|
|
||||||
|
public SpecialOrder(List<OrderLine> orderLines) {
|
||||||
|
super(orderLines);
|
||||||
|
this.eligibleForExtraDiscount = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpecialOrder(List<OrderLine> orderLines, boolean eligibleForSpecialDiscount) {
|
||||||
|
super(orderLines);
|
||||||
|
this.eligibleForExtraDiscount = eligibleForSpecialDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEligibleForExtraDiscount() {
|
||||||
|
return eligibleForExtraDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double applyDiscountPolicy(SpecialDiscountPolicy discountPolicy) {
|
||||||
|
return discountPolicy.discount(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(OrderVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch.visitor;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialOrder;
|
||||||
|
|
||||||
|
public class HtmlOrderViewCreator implements OrderVisitor {
|
||||||
|
|
||||||
|
private String html;
|
||||||
|
|
||||||
|
public String getHtml() {
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Order order) {
|
||||||
|
html = String.format("<p>Regular order total cost: %s</p>", order.totalCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(SpecialOrder order) {
|
||||||
|
html = String.format("<h1>Special Order</h1><p>total cost: %s</p>", order.totalCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch.visitor;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialOrder;
|
||||||
|
|
||||||
|
public interface OrderVisitor {
|
||||||
|
void visit(Order order);
|
||||||
|
void visit(SpecialOrder order);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch.visitor;
|
||||||
|
|
||||||
|
public interface Visitable<V> {
|
||||||
|
void accept(V visitor);
|
||||||
|
}
|
|
@ -92,7 +92,7 @@ class JpaOrder {
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeLineItem(int line) {
|
void removeLineItem(int line) {
|
||||||
JpaOrderLine removedLine = orderLines.remove(line);
|
orderLines.remove(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrencyUnit(String currencyUnit) {
|
void setCurrencyUnit(String currencyUnit) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ class JpaProduct {
|
||||||
public JpaProduct(BigDecimal price, String currencyUnit) {
|
public JpaProduct(BigDecimal price, String currencyUnit) {
|
||||||
super();
|
super();
|
||||||
this.price = price;
|
this.price = price;
|
||||||
currencyUnit = currencyUnit;
|
this.currencyUnit = currencyUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.ddd.order;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class OrderFixtureUtils {
|
||||||
|
public static List<OrderLine> anyOrderLines() {
|
||||||
|
return Arrays.asList(new OrderLine(new Product(Money.of(CurrencyUnit.USD, 100)), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<OrderLine> orderLineItemsWorthNDollars(int totalCost) {
|
||||||
|
return Arrays.asList(new OrderLine(new Product(Money.of(CurrencyUnit.USD, totalCost)), 1));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
|
||||||
|
public class DoubleDispatchDiscountPolicyUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given regular order with items worth $100 total, " +
|
||||||
|
"when apply 10% discount policy, " +
|
||||||
|
"then cost after discount is $90"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
Order order = new Order(OrderFixtureUtils.orderLineItemsWorthNDollars(100));
|
||||||
|
SpecialDiscountPolicy discountPolicy = new SpecialDiscountPolicy() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0.10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(SpecialOrder order) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
Money totalCostAfterDiscount = order.totalCost(discountPolicy);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(totalCostAfterDiscount).isEqualTo(Money.of(CurrencyUnit.USD, 90));
|
||||||
|
}
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given special order eligible for extra discount with items worth $100 total, " +
|
||||||
|
"when apply 20% discount policy for extra discount orders, " +
|
||||||
|
"then cost after discount is $80"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test1() throws Exception {
|
||||||
|
// given
|
||||||
|
boolean eligibleForExtraDiscount = true;
|
||||||
|
Order order = new SpecialOrder(OrderFixtureUtils.orderLineItemsWorthNDollars(100), eligibleForExtraDiscount);
|
||||||
|
SpecialDiscountPolicy discountPolicy = new SpecialDiscountPolicy() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(SpecialOrder order) {
|
||||||
|
if (order.isEligibleForExtraDiscount())
|
||||||
|
return 0.20;
|
||||||
|
return 0.10;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
Money totalCostAfterDiscount = order.totalCost(discountPolicy);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(totalCostAfterDiscount).isEqualTo(Money.of(CurrencyUnit.USD, 80.00));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.HtmlOrderViewCreator;
|
||||||
|
|
||||||
|
public class HtmlOrderViewCreatorUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given collection of regular and special orders, " +
|
||||||
|
"when create HTML view using visitor for each order, " +
|
||||||
|
"then the dedicated view is created for each order"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
List<OrderLine> anyOrderLines = OrderFixtureUtils.anyOrderLines();
|
||||||
|
List<Order> orders = Arrays.asList(new Order(anyOrderLines), new SpecialOrder(anyOrderLines));
|
||||||
|
HtmlOrderViewCreator htmlOrderViewCreator = new HtmlOrderViewCreator();
|
||||||
|
|
||||||
|
// when
|
||||||
|
orders.get(0)
|
||||||
|
.accept(htmlOrderViewCreator);
|
||||||
|
String regularOrderHtml = htmlOrderViewCreator.getHtml();
|
||||||
|
orders.get(1)
|
||||||
|
.accept(htmlOrderViewCreator);
|
||||||
|
String specialOrderHtml = htmlOrderViewCreator.getHtml();
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(regularOrderHtml).containsPattern("<p>Regular order total cost: .*</p>");
|
||||||
|
assertThat(specialOrderHtml).containsPattern("<h1>Special Order</h1><p>total cost: .*</p>");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialDiscountPolicy;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialOrder;
|
||||||
|
|
||||||
|
public class MethodOverloadExampleUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given discount policy accepting special orders, " +
|
||||||
|
"when apply the policy on special order declared as regular order, " +
|
||||||
|
"then regular discount method is used"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
SpecialDiscountPolicy specialPolicy = new SpecialDiscountPolicy() {
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(SpecialOrder order) {
|
||||||
|
return 0.10;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Order specialOrder = new SpecialOrder(anyOrderLines());
|
||||||
|
|
||||||
|
// when
|
||||||
|
double discount = specialPolicy.discount(specialOrder);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(discount).isEqualTo(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OrderLine> anyOrderLines() {
|
||||||
|
return OrderFixtureUtils.anyOrderLines();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
|
||||||
|
public class SingleDispatchDiscountPolicyUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given two discount policies, " +
|
||||||
|
"when use these policies, " +
|
||||||
|
"then single dispatch chooses the implementation based on runtime type"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
DiscountPolicy flatPolicy = new FlatDiscountPolicy();
|
||||||
|
DiscountPolicy amountPolicy = new AmountBasedDiscountPolicy();
|
||||||
|
Order orderWorth501Dollars = orderWorthNDollars(501);
|
||||||
|
|
||||||
|
// when
|
||||||
|
double flatDiscount = flatPolicy.discount(orderWorth501Dollars);
|
||||||
|
double amountDiscount = amountPolicy.discount(orderWorth501Dollars);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(flatDiscount).isEqualTo(0.01);
|
||||||
|
assertThat(amountDiscount).isEqualTo(0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Order orderWorthNDollars(int totalCost) {
|
||||||
|
return new Order(OrderFixtureUtils.orderLineItemsWorthNDollars(totalCost));
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,28 +15,6 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>${commons-io.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
<version>${log4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-codec</groupId>
|
|
||||||
<artifactId>commons-codec</artifactId>
|
|
||||||
<version>${commons-codec.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- test scoped -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>${assertj.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
<artifactId>jmh-core</artifactId>
|
<artifactId>jmh-core</artifactId>
|
||||||
|
@ -57,11 +35,6 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.vdurmont</groupId>
|
|
||||||
<artifactId>emoji-java</artifactId>
|
|
||||||
<version>${emoji-java.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
@ -73,38 +46,18 @@
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
|
||||||
<version>${junit-jupiter-api.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-library</artifactId>
|
<artifactId>hamcrest-library</artifactId>
|
||||||
<version>${org.hamcrest.version}</version>
|
<version>${org.hamcrest.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Added for password generation -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.passay</groupId>
|
|
||||||
<artifactId>passay</artifactId>
|
|
||||||
<version>${passay.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-text</artifactId>
|
<artifactId>commons-text</artifactId>
|
||||||
<version>${commons-text.version}</version>
|
<version>${commons-text.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ahocorasick</groupId>
|
|
||||||
<artifactId>ahocorasick</artifactId>
|
|
||||||
<version>${ahocorasick.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -131,18 +84,10 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- util -->
|
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||||
<commons-codec.version>1.10</commons-codec.version>
|
|
||||||
<!-- testing -->
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
|
||||||
<icu4j.version>61.1</icu4j.version>
|
<icu4j.version>61.1</icu4j.version>
|
||||||
<guava.version>27.0.1-jre</guava.version>
|
<guava.version>27.0.1-jre</guava.version>
|
||||||
<emoji-java.version>4.0.0</emoji-java.version>
|
|
||||||
<junit-jupiter-api.version>5.3.1</junit-jupiter-api.version>
|
|
||||||
<passay.version>1.3.1</passay.version>
|
|
||||||
<commons-text.version>1.4</commons-text.version>
|
<commons-text.version>1.4</commons-text.version>
|
||||||
<ahocorasick.version>0.4.0</ahocorasick.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.baeldung.string.performance;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
|
||||||
|
|
||||||
|
@Fork(value = 3, warmups = 1)
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
public class RemovingStopwordsPerformanceComparison {
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
private List<String> stopwords;
|
||||||
|
|
||||||
|
private String stopwordsRegex;
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() throws IOException {
|
||||||
|
data = new String(Files.readAllBytes(Paths.get("src/main/resources/shakespeare-hamlet.txt")));
|
||||||
|
data = data.toLowerCase();
|
||||||
|
stopwords = Files.readAllLines(Paths.get("src/main/resources/english_stopwords.txt"));
|
||||||
|
stopwordsRegex = stopwords.stream().collect(Collectors.joining("|", "\\b(", ")\\b\\s?"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String removeManually() {
|
||||||
|
String[] allWords = data.split(" ");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(String word:allWords) {
|
||||||
|
if(! stopwords.contains(word)) {
|
||||||
|
builder.append(word);
|
||||||
|
builder.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String removeAll() {
|
||||||
|
ArrayList<String> allWords = Stream.of(data.split(" "))
|
||||||
|
.collect(Collectors.toCollection(ArrayList<String>::new));
|
||||||
|
allWords.removeAll(stopwords);
|
||||||
|
return allWords.stream().collect(Collectors.joining(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String replaceRegex() {
|
||||||
|
return data.replaceAll(stopwordsRegex, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
i
|
||||||
|
me
|
||||||
|
my
|
||||||
|
myself
|
||||||
|
we
|
||||||
|
our
|
||||||
|
ours
|
||||||
|
ourselves
|
||||||
|
you
|
||||||
|
your
|
||||||
|
yours
|
||||||
|
yourself
|
||||||
|
yourselves
|
||||||
|
he
|
||||||
|
him
|
||||||
|
his
|
||||||
|
himself
|
||||||
|
she
|
||||||
|
her
|
||||||
|
hers
|
||||||
|
herself
|
||||||
|
it
|
||||||
|
its
|
||||||
|
itself
|
||||||
|
they
|
||||||
|
them
|
||||||
|
their
|
||||||
|
theirs
|
||||||
|
themselves
|
||||||
|
what
|
||||||
|
which
|
||||||
|
who
|
||||||
|
whom
|
||||||
|
this
|
||||||
|
that
|
||||||
|
these
|
||||||
|
those
|
||||||
|
am
|
||||||
|
is
|
||||||
|
are
|
||||||
|
was
|
||||||
|
were
|
||||||
|
be
|
||||||
|
been
|
||||||
|
being
|
||||||
|
have
|
||||||
|
has
|
||||||
|
had
|
||||||
|
having
|
||||||
|
do
|
||||||
|
does
|
||||||
|
did
|
||||||
|
doing
|
||||||
|
a
|
||||||
|
an
|
||||||
|
the
|
||||||
|
and
|
||||||
|
but
|
||||||
|
if
|
||||||
|
or
|
||||||
|
because
|
||||||
|
as
|
||||||
|
until
|
||||||
|
while
|
||||||
|
of
|
||||||
|
at
|
||||||
|
by
|
||||||
|
for
|
||||||
|
with
|
||||||
|
about
|
||||||
|
against
|
||||||
|
between
|
||||||
|
into
|
||||||
|
through
|
||||||
|
during
|
||||||
|
before
|
||||||
|
after
|
||||||
|
above
|
||||||
|
below
|
||||||
|
to
|
||||||
|
from
|
||||||
|
up
|
||||||
|
down
|
||||||
|
in
|
||||||
|
out
|
||||||
|
on
|
||||||
|
off
|
||||||
|
over
|
||||||
|
under
|
||||||
|
again
|
||||||
|
further
|
||||||
|
then
|
||||||
|
once
|
||||||
|
here
|
||||||
|
there
|
||||||
|
when
|
||||||
|
where
|
||||||
|
why
|
||||||
|
how
|
||||||
|
all
|
||||||
|
any
|
||||||
|
both
|
||||||
|
each
|
||||||
|
few
|
||||||
|
more
|
||||||
|
most
|
||||||
|
other
|
||||||
|
some
|
||||||
|
such
|
||||||
|
no
|
||||||
|
nor
|
||||||
|
not
|
||||||
|
only
|
||||||
|
own
|
||||||
|
same
|
||||||
|
so
|
||||||
|
than
|
||||||
|
too
|
||||||
|
very
|
||||||
|
s
|
||||||
|
t
|
||||||
|
can
|
||||||
|
will
|
||||||
|
just
|
||||||
|
don
|
||||||
|
should
|
||||||
|
now
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.string;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class RemoveStopwordsUnitTest {
|
||||||
|
final String original = "The quick brown fox jumps over the lazy dog";
|
||||||
|
final String target = "quick brown fox jumps lazy dog";
|
||||||
|
static List<String> stopwords;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void loadStopwords() throws IOException {
|
||||||
|
stopwords = Files.readAllLines(Paths.get("src/main/resources/english_stopwords.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRemoveStopwordsManually_thenSuccess() {
|
||||||
|
String[] allWords = original.toLowerCase()
|
||||||
|
.split(" ");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (String word : allWords) {
|
||||||
|
if (!stopwords.contains(word)) {
|
||||||
|
builder.append(word);
|
||||||
|
builder.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = builder.toString().trim();
|
||||||
|
assertEquals(result, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRemoveStopwordsUsingRemoveAll_thenSuccess() {
|
||||||
|
ArrayList<String> allWords = Stream.of(original.toLowerCase()
|
||||||
|
.split(" "))
|
||||||
|
.collect(Collectors.toCollection(ArrayList<String>::new));
|
||||||
|
allWords.removeAll(stopwords);
|
||||||
|
String result = allWords.stream().collect(Collectors.joining(" "));
|
||||||
|
assertEquals(result, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRemoveStopwordsUsingRegex_thenSuccess() {
|
||||||
|
String stopwordsRegex = stopwords.stream()
|
||||||
|
.collect(Collectors.joining("|", "\\b(", ")\\b\\s?"));
|
||||||
|
String result = original.toLowerCase().replaceAll(stopwordsRegex, "");
|
||||||
|
assertEquals(result, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue