pull from master
This commit is contained in:
+129
@@ -0,0 +1,129 @@
|
||||
package com.baeldung.algorithms.connect4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GameBoard {
|
||||
private final List<List<Piece>> columns;
|
||||
|
||||
private final int rows;
|
||||
|
||||
public GameBoard(int columns, int rows) {
|
||||
this.rows = rows;
|
||||
this.columns = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < columns; ++i) {
|
||||
this.columns.add(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public int getColumns() {
|
||||
return columns.size();
|
||||
}
|
||||
|
||||
public Piece getCell(int x, int y) {
|
||||
assert(x >= 0 && x < getColumns());
|
||||
assert(y >= 0 && y < getRows());
|
||||
|
||||
List<Piece> column = columns.get(x);
|
||||
|
||||
if (column.size() > y) {
|
||||
return column.get(y);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean move(int x, Piece player) {
|
||||
assert(x >= 0 && x < getColumns());
|
||||
|
||||
List<Piece> column = columns.get(x);
|
||||
|
||||
if (column.size() >= this.rows) {
|
||||
throw new IllegalArgumentException("That column is full");
|
||||
}
|
||||
|
||||
column.add(player);
|
||||
|
||||
return checkWin(x, column.size() - 1, player);
|
||||
}
|
||||
|
||||
private boolean checkWin(int x, int y, Piece player) {
|
||||
// Vertical line
|
||||
if (checkLine(x, y, 0, -1, player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int offset = 0; offset < 4; ++offset) {
|
||||
// Horizontal line
|
||||
if (checkLine(x - 3 + offset, y, 1, 0, player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Leading diagonal
|
||||
if (checkLine(x - 3 + offset, y + 3 - offset, 1, -1, player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Trailing diagonal
|
||||
if (checkLine(x - 3 + offset, y - 3 + offset, 1, 1, player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkLine(int x1, int y1, int xDiff, int yDiff, Piece player) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int x = x1 + (xDiff * i);
|
||||
int y = y1 + (yDiff * i);
|
||||
|
||||
if (x < 0 || x > columns.size() - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (y < 0 || y > rows - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player != getCell(x, y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
for (int y = getRows() - 1; y >= 0; --y) {
|
||||
for (int x = 0; x < getColumns(); ++x) {
|
||||
Piece piece = getCell(x, y);
|
||||
|
||||
result.append("|");
|
||||
if (piece == null) {
|
||||
result.append(" ");
|
||||
} else if (piece == Piece.PLAYER_1) {
|
||||
result.append("X");
|
||||
} else if (piece == Piece.PLAYER_2) {
|
||||
result.append("O");
|
||||
}
|
||||
}
|
||||
|
||||
result.append("|\n");
|
||||
for (int i = 0; i < getColumns(); ++i) {
|
||||
result.append("+-");
|
||||
}
|
||||
result.append("+\n");
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.algorithms.connect4;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class GameUnitTest {
|
||||
@Test
|
||||
public void blankGame() {
|
||||
GameBoard gameBoard = new GameBoard(8, 6);
|
||||
|
||||
System.out.println(gameBoard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playedGame() {
|
||||
GameBoard gameBoard = new GameBoard(8, 6);
|
||||
|
||||
assertFalse(gameBoard.move(3, Piece.PLAYER_1));
|
||||
assertFalse(gameBoard.move(2, Piece.PLAYER_2));
|
||||
|
||||
assertFalse(gameBoard.move(4, Piece.PLAYER_1));
|
||||
assertFalse(gameBoard.move(3, Piece.PLAYER_2));
|
||||
|
||||
assertFalse(gameBoard.move(5, Piece.PLAYER_1));
|
||||
assertFalse(gameBoard.move(6, Piece.PLAYER_2));
|
||||
|
||||
assertFalse(gameBoard.move(5, Piece.PLAYER_1));
|
||||
assertFalse(gameBoard.move(4, Piece.PLAYER_2));
|
||||
|
||||
assertFalse(gameBoard.move(5, Piece.PLAYER_1));
|
||||
assertFalse(gameBoard.move(5, Piece.PLAYER_2));
|
||||
|
||||
assertFalse(gameBoard.move(6, Piece.PLAYER_1));
|
||||
assertTrue(gameBoard.move(4, Piece.PLAYER_2));
|
||||
|
||||
System.out.println(gameBoard);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.algorithms.connect4;
|
||||
|
||||
public enum Piece {
|
||||
PLAYER_1,
|
||||
PLAYER_2
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
## Relevant Articles
|
||||
- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game)
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package com.baeldung.rounddate;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
public class RoundDate {
|
||||
public static Date getDate(int year, int month, int day, int hour, int minute) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
calendar.set(Calendar.MONTH, month);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, day);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hour);
|
||||
calendar.set(Calendar.MINUTE, minute);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static Date roundToDay(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static Date roundToNearestUnit(Date date, int unit) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
|
||||
switch (unit) {
|
||||
case Calendar.HOUR:
|
||||
int minute = calendar.get(Calendar.MINUTE);
|
||||
if (minute >= 0 && minute < 15) {
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
} else if (minute >= 15 && minute < 45) {
|
||||
calendar.set(Calendar.MINUTE, 30);
|
||||
} else {
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.add(Calendar.HOUR_OF_DAY, 1);
|
||||
}
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
break;
|
||||
|
||||
case Calendar.DAY_OF_MONTH:
|
||||
int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
if (hour >= 12) {
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
}
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
break;
|
||||
|
||||
case Calendar.MONTH:
|
||||
int day = calendar.get(Calendar.DAY_OF_MONTH);
|
||||
if (day >= 15) {
|
||||
calendar.add(Calendar.MONTH, 1);
|
||||
}
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static LocalDateTime roundToStartOfMonthUsingLocalDateTime(LocalDateTime dateTime) {
|
||||
return dateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
||||
}
|
||||
|
||||
public static LocalDateTime roundToEndOfWeekUsingLocalDateTime(LocalDateTime dateTime) {
|
||||
return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY))
|
||||
.withHour(23)
|
||||
.withMinute(59)
|
||||
.withSecond(59)
|
||||
.withNano(999);
|
||||
}
|
||||
|
||||
public static ZonedDateTime roundToStartOfMonthUsingZonedDateTime(ZonedDateTime dateTime) {
|
||||
return dateTime.withDayOfMonth(1)
|
||||
.withHour(0)
|
||||
.withMinute(0)
|
||||
.withSecond(0)
|
||||
.with(ChronoField.MILLI_OF_SECOND, 0)
|
||||
.with(ChronoField.MICRO_OF_SECOND, 0)
|
||||
.with(ChronoField.NANO_OF_SECOND, 0);
|
||||
}
|
||||
|
||||
public static ZonedDateTime roundToEndOfWeekUsingZonedDateTime(ZonedDateTime dateTime) {
|
||||
return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY))
|
||||
.withHour(23)
|
||||
.withMinute(59)
|
||||
.withSecond(59)
|
||||
.with(ChronoField.MILLI_OF_SECOND, 999)
|
||||
.with(ChronoField.MICRO_OF_SECOND, 999)
|
||||
.with(ChronoField.NANO_OF_SECOND, 999);
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.rounddate;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class DateRoundingUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenDate_whenRoundToDay_thenBeginningOfDay() {
|
||||
Date date = RoundDate.getDate(2023, Calendar.JANUARY, 27, 14, 30);
|
||||
Date result = RoundDate.roundToDay(date);
|
||||
assertEquals(RoundDate.getDate(2023, Calendar.JANUARY, 27, 0, 0), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDate_whenRoundToNearestUnit_thenNearestUnit() {
|
||||
Date date = RoundDate.getDate(2023, Calendar.JANUARY, 27, 14, 12);
|
||||
Date result = RoundDate.roundToNearestUnit(date, Calendar.DAY_OF_MONTH);
|
||||
Date expected = RoundDate.getDate(2023, Calendar.JANUARY, 28, 0, 0);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTime_whenRoundToStartOfMonth_thenStartOfMonth() {
|
||||
LocalDateTime dateTime = LocalDateTime.of(2023, 1, 27, 14, 12);
|
||||
LocalDateTime result = RoundDate.roundToStartOfMonthUsingLocalDateTime(dateTime);
|
||||
LocalDateTime expected = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenZonedDateTime_whenRoundToStartOfMonth_thenStartOfMonth() {
|
||||
ZonedDateTime dateTime = ZonedDateTime.of(2023, 1, 27, 14, 12, 0, 0, ZoneId.systemDefault());
|
||||
ZonedDateTime result = RoundDate.roundToStartOfMonthUsingZonedDateTime(dateTime);
|
||||
ZonedDateTime expected = ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTime_whenRoundToEndOfWeek_thenEndOfWeek() {
|
||||
LocalDateTime dateTime = LocalDateTime.of(2023, 1, 27, 14, 12);
|
||||
LocalDateTime result = RoundDate.roundToEndOfWeekUsingLocalDateTime(dateTime);
|
||||
LocalDateTime expected = LocalDateTime.of(2023, 1, 28, 23, 59, 59, 999);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenZonedDateTime_whenRoundToEndOfWeek_thenEndOfWeek() {
|
||||
ZonedDateTime dateTime = ZonedDateTime.of(2023, 1, 27, 14, 12, 0, 0, ZoneId.systemDefault());
|
||||
ZonedDateTime result = RoundDate.roundToEndOfWeekUsingZonedDateTime(dateTime);
|
||||
ZonedDateTime expected = ZonedDateTime.of(2023, 1, 28, 23, 59, 59, 999, ZoneId.systemDefault());
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.spliterator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CustomSpliterator implements Spliterator<Integer> {
|
||||
private final List<Integer> elements;
|
||||
private int currentIndex;
|
||||
|
||||
public CustomSpliterator(List<Integer> elements) {
|
||||
this.elements = elements;
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super Integer> action) {
|
||||
if (currentIndex < elements.size()) {
|
||||
action.accept(elements.get(currentIndex));
|
||||
currentIndex++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Integer> trySplit() {
|
||||
int currentSize = elements.size() - currentIndex;
|
||||
if (currentSize < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int splitIndex = currentIndex + currentSize / 2;
|
||||
CustomSpliterator newSpliterator = new CustomSpliterator(elements.subList(currentIndex, splitIndex));
|
||||
currentIndex = splitIndex;
|
||||
return newSpliterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
return elements.size() - currentIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return ORDERED | SIZED | SUBSIZED | NONNULL;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.baeldung.spliterator;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Executor {
|
||||
|
||||
public static int countAutors(Stream<Author> stream) {
|
||||
RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true),
|
||||
RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine);
|
||||
return wordCounter.getCounter();
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
package com.baeldung.spliterator;
|
||||
|
||||
public class RelatedAuthorCounter {
|
||||
private final int counter;
|
||||
private final boolean isRelated;
|
||||
|
||||
public RelatedAuthorCounter(int counter, boolean isRelated) {
|
||||
this.counter = counter;
|
||||
this.isRelated = isRelated;
|
||||
}
|
||||
|
||||
public RelatedAuthorCounter accumulate(Author author) {
|
||||
if (author.getRelatedArticleId() == 0) {
|
||||
return isRelated ? this : new RelatedAuthorCounter(counter, true);
|
||||
} else {
|
||||
return isRelated ? new RelatedAuthorCounter(counter + 1, false) : this;
|
||||
}
|
||||
}
|
||||
|
||||
public RelatedAuthorCounter combine(RelatedAuthorCounter RelatedAuthorCounter) {
|
||||
return new RelatedAuthorCounter(counter + RelatedAuthorCounter.counter, RelatedAuthorCounter.isRelated);
|
||||
}
|
||||
|
||||
public int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
package com.baeldung.spliterator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class RelatedAuthorSpliterator implements Spliterator<Author> {
|
||||
private final List<Author> list;
|
||||
AtomicInteger current = new AtomicInteger();
|
||||
|
||||
public RelatedAuthorSpliterator(List<Author> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super Author> action) {
|
||||
|
||||
action.accept(list.get(current.getAndIncrement()));
|
||||
return current.get() < list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Author> trySplit() {
|
||||
int currentSize = list.size() - current.get();
|
||||
if (currentSize < 10) {
|
||||
return null;
|
||||
}
|
||||
for (int splitPos = currentSize / 2 + current.intValue(); splitPos < list.size(); splitPos++) {
|
||||
if (list.get(splitPos).getRelatedArticleId() == 0) {
|
||||
Spliterator<Author> spliterator = new RelatedAuthorSpliterator(list.subList(current.get(), splitPos));
|
||||
current.set(splitPos);
|
||||
return spliterator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
return list.size() - current.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return CONCURRENT;
|
||||
}
|
||||
|
||||
}
|
||||
+38
-12
@@ -6,10 +6,10 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -18,22 +18,50 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class ExecutorUnitTest {
|
||||
Article article;
|
||||
Stream<Author> stream;
|
||||
Spliterator<Author> spliterator;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0),
|
||||
new Author("Alice", 1), new Author("Mike", 0), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1),
|
||||
new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0);
|
||||
|
||||
spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAstreamOfAuthors_whenProcessedInParallelWithCustomSpliterator_coubtProducessRightOutput() {
|
||||
Stream<Author> stream2 = StreamSupport.stream(spliterator, true);
|
||||
assertThat(Executor.countAutors(stream2.parallel())).isEqualTo(9);
|
||||
public void givenAStreamOfIntegers_whenProcessedSequentialCustomSpliterator_countProducesRightOutput() {
|
||||
List<Integer> numbers = new ArrayList<>();
|
||||
numbers.add(1);
|
||||
numbers.add(2);
|
||||
numbers.add(3);
|
||||
numbers.add(4);
|
||||
numbers.add(5);
|
||||
|
||||
CustomSpliterator customSpliterator = new CustomSpliterator(numbers);
|
||||
|
||||
AtomicInteger sum = new AtomicInteger();
|
||||
|
||||
customSpliterator.forEachRemaining(sum::addAndGet);
|
||||
assertThat(sum.get()).isEqualTo(15);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAStreamOfIntegers_whenProcessedInParallelWithCustomSpliterator_countProducesRightOutput() {
|
||||
List<Integer> numbers = new ArrayList<>();
|
||||
numbers.add(1);
|
||||
numbers.add(2);
|
||||
numbers.add(3);
|
||||
numbers.add(4);
|
||||
numbers.add(5);
|
||||
|
||||
CustomSpliterator customSpliterator = new CustomSpliterator(numbers);
|
||||
|
||||
// Create a ForkJoinPool for parallel processing
|
||||
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
|
||||
|
||||
AtomicInteger sum = new AtomicInteger(0);
|
||||
|
||||
// Process elements in parallel using parallelStream
|
||||
forkJoinPool.submit(() -> customSpliterator.forEachRemaining(sum::addAndGet)).join();
|
||||
assertThat(sum.get()).isEqualTo(15);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -43,9 +71,7 @@ public class ExecutorUnitTest {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Spliterator<Article> spliterator = articles.spliterator();
|
||||
while (spliterator.tryAdvance(article -> article.setName(article.getName()
|
||||
.concat("- published by Baeldung"))))
|
||||
;
|
||||
while(spliterator.tryAdvance(article -> article.setName(article.getName().concat("- published by Baeldung"))));
|
||||
|
||||
articles.forEach(article -> assertThat(article.getName()).isEqualTo("Java- published by Baeldung"));
|
||||
}
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.baeldung.vectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class VectorOperationsUnitTest {
|
||||
|
||||
private static Vector<String> getVector() {
|
||||
Vector<String> vector = new Vector<String>();
|
||||
vector.add("Today");
|
||||
vector.add("is");
|
||||
vector.add("a");
|
||||
vector.add("great");
|
||||
vector.add("day!");
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAVector_whenAddElementsUsingAddMethod_thenElementsGetAddedAtEnd() {
|
||||
Vector<String> vector = getVector();
|
||||
vector.add("Hello");
|
||||
assertEquals(6, vector.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAVector_whenUpdateElementAtIndex_thenElementAtIndexGetsUpdated() {
|
||||
Vector<String> vector = getVector();
|
||||
assertEquals(5, vector.size());
|
||||
assertEquals("great", vector.get(3));
|
||||
vector.set(3, "good");
|
||||
assertEquals("good", vector.get(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAVector_whenRemoveAnElement_thenElementGetsRemovedFromTheVector() {
|
||||
Vector<String> vector = getVector();
|
||||
assertEquals(5, vector.size());
|
||||
|
||||
// remove a specific element
|
||||
vector.remove("a");
|
||||
assertEquals(4, vector.size());
|
||||
|
||||
// remove at specific index
|
||||
vector.remove(2);
|
||||
assertEquals("day!", vector.get(2));
|
||||
assertEquals(3, vector.size());
|
||||
|
||||
assertEquals(false, vector.remove("SomethingThatDoesn'tExist"));
|
||||
}
|
||||
|
||||
@Test(expected = ArrayIndexOutOfBoundsException.class)
|
||||
public void givenAVector_whenIndexIsBeyondRange_thenRemoveMethodThrowsArrayIndexOutOfBoundsException() {
|
||||
Vector<String> vector = getVector();
|
||||
assertEquals(5, vector.size());
|
||||
vector.remove(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAVector_whenGetElementWithinARange_thenGetMethodGetsAnElementFromTheVector() {
|
||||
Vector<String> vector = getVector();
|
||||
String fourthElement = vector.get(3);
|
||||
assertEquals("great", fourthElement);
|
||||
}
|
||||
|
||||
@Test(expected = ArrayIndexOutOfBoundsException.class)
|
||||
public void givenAVector_whenGetElementBeyondARange_thenGetMethodThrowsArrayIndexOutOfBoundsException() {
|
||||
Vector<String> vector = getVector();
|
||||
assertEquals(5, vector.size());
|
||||
vector.get(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAVector_whenAddElementFromACollection_thenAllElementsGetAdeddToTheVector() {
|
||||
Vector<String> vector = getVector();
|
||||
assertEquals(5, vector.size());
|
||||
ArrayList<String> words = new ArrayList<>(Arrays.asList("Baeldung", "is", "cool!"));
|
||||
vector.addAll(words);
|
||||
assertEquals(8, vector.size());
|
||||
assertEquals("cool!", vector.get(7));
|
||||
}
|
||||
}
|
||||
@@ -79,5 +79,18 @@
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package com.baeldung.map.linkedhashmapfirstandlastentry;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class GetFirstAndLastEntryFromLinkedHashMapUnitTest {
|
||||
private static final LinkedHashMap<String, String> THE_MAP = new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
THE_MAP.put("key one", "a1 b1 c1");
|
||||
THE_MAP.put("key two", "a2 b2 c2");
|
||||
THE_MAP.put("key three", "a3 b3 c3");
|
||||
THE_MAP.put("key four", "a4 b4 c4");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingEntrySet_thenGetExpectedResult() {
|
||||
Entry<String, String> firstEntry = THE_MAP.entrySet().iterator().next();
|
||||
assertEquals("key one", firstEntry.getKey());
|
||||
assertEquals("a1 b1 c1", firstEntry.getValue());
|
||||
|
||||
Entry<String, String> lastEntry = null;
|
||||
Iterator<Entry<String, String>> it = THE_MAP.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
lastEntry = it.next();
|
||||
}
|
||||
|
||||
assertNotNull(lastEntry);
|
||||
assertEquals("key four", lastEntry.getKey());
|
||||
assertEquals("a4 b4 c4", lastEntry.getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenConvertingEntriesToArray_thenGetExpectedResult() {
|
||||
|
||||
Entry<String, String>[] theArray = new Entry[THE_MAP.size()];
|
||||
THE_MAP.entrySet().toArray(theArray);
|
||||
|
||||
Entry<String, String> firstEntry = theArray[0];
|
||||
assertEquals("key one", firstEntry.getKey());
|
||||
assertEquals("a1 b1 c1", firstEntry.getValue());
|
||||
|
||||
Entry<String, String> lastEntry = theArray[THE_MAP.size() - 1];
|
||||
assertEquals("key four", lastEntry.getKey());
|
||||
assertEquals("a4 b4 c4", lastEntry.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingStreamAPI_thenGetExpectedResult() {
|
||||
Entry<String, String> firstEntry = THE_MAP.entrySet().stream().findFirst().get();
|
||||
assertEquals("key one", firstEntry.getKey());
|
||||
assertEquals("a1 b1 c1", firstEntry.getValue());
|
||||
|
||||
Entry<String, String> lastEntry = THE_MAP.entrySet().stream().skip(THE_MAP.size() - 1).findFirst().get();
|
||||
|
||||
assertNotNull(lastEntry);
|
||||
assertEquals("key four", lastEntry.getKey());
|
||||
assertEquals("a4 b4 c4", lastEntry.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingReflection_thenGetExpectedResult() throws NoSuchFieldException, IllegalAccessException {
|
||||
Field head = THE_MAP.getClass().getDeclaredField("head");
|
||||
head.setAccessible(true);
|
||||
Entry<String, String> firstEntry = (Entry<String, String>) head.get(THE_MAP);
|
||||
assertEquals("key one", firstEntry.getKey());
|
||||
assertEquals("a1 b1 c1", firstEntry.getValue());
|
||||
|
||||
Field tail = THE_MAP.getClass().getDeclaredField("tail");
|
||||
tail.setAccessible(true);
|
||||
Entry<String, String> lastEntry = (Entry<String, String>) tail.get(THE_MAP);
|
||||
assertEquals("key four", lastEntry.getKey());
|
||||
assertEquals("a4 b4 c4", lastEntry.getValue());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -11,4 +11,5 @@ This module contains articles about basic Java concurrency.
|
||||
- [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool)
|
||||
- [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join)
|
||||
- [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic)
|
||||
- [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert)
|
||||
- [[<-- Prev]](../core-java-concurrency-basic-2)
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.generictype;
|
||||
|
||||
/**
|
||||
* @param <T> The type of the first value in the {@code Pair<T,S>}.
|
||||
* @param <S> The type of the second value in the {@code Pair<T,S>}.
|
||||
*/
|
||||
|
||||
public class Pair<T, S> {
|
||||
public T first;
|
||||
public S second;
|
||||
|
||||
/**
|
||||
* Constructs a new Pair object with the specified values.
|
||||
*
|
||||
* @param a The first value.
|
||||
* @param b The second value.
|
||||
*/
|
||||
|
||||
public Pair(T a, S b) {
|
||||
first = a;
|
||||
second = b;
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,6 @@ This module contains articles about core Java input and output (IO)
|
||||
### Relevant Articles:
|
||||
- [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension)
|
||||
- [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks)
|
||||
- [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-4)
|
||||
|
||||
|
||||
@@ -8,3 +8,4 @@ This module contains articles about core Java input/output(IO) APIs.
|
||||
- [Check if a File Is Empty in Java](https://www.baeldung.com/java-check-file-empty)
|
||||
- [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths)
|
||||
- [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file)
|
||||
- [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference)
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
<json.version>20200518</json.version>
|
||||
<opencsv.version>4.1</opencsv.version>
|
||||
<opencsv.version>5.8</opencsv.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.baeldung.jndi;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.jndi.JndiTemplate;
|
||||
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class JndiNamingUnitTest {
|
||||
|
||||
private static InitialContext context;
|
||||
private static DriverManagerDataSource dataSource;
|
||||
|
||||
@BeforeAll
|
||||
static void setUp() throws Exception {
|
||||
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
|
||||
dataSource = new DriverManagerDataSource("jdbc:h2:mem:mydb");
|
||||
builder.activate();
|
||||
|
||||
JndiTemplate jndiTemplate = new JndiTemplate();
|
||||
context = (InitialContext) jndiTemplate.getContext();
|
||||
|
||||
dataSource.setDriverClassName("org.h2.Driver");
|
||||
context.bind("java:comp/env/jdbc/datasource", dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenACompositeName_whenAddingAnElement_thenNameIsAdded() throws Exception {
|
||||
Name objectName = new CompositeName("java:comp/env/jdbc");
|
||||
|
||||
Enumeration<String> items = objectName.getAll();
|
||||
while(items.hasMoreElements()) {
|
||||
System.out.println(items.nextElement());
|
||||
}
|
||||
|
||||
objectName.add("New Name");
|
||||
|
||||
assertEquals("env", objectName.get(1));
|
||||
assertEquals("New Name", objectName.get(objectName.size() - 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenContext_whenLookupByName_thenReturnsValidObject() throws Exception {
|
||||
DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource");
|
||||
|
||||
assertNotNull(ds);
|
||||
assertNotNull(ds.getConnection());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSubContext_whenLookupByName_thenReturnsValidObject() throws Exception {
|
||||
Context subContext = (Context) context.lookup("java:comp/env");
|
||||
DataSource ds = (DataSource) subContext.lookup("jdbc/datasource");
|
||||
|
||||
assertNotNull(ds);
|
||||
assertNotNull(ds.getConnection());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void tearDown() throws Exception {
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package com.baeldung.genericnumberscomparator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class GenericNumbersComparatorUnitTest {
|
||||
|
||||
public int compareDouble(Number num1, Number num2) {
|
||||
return Double.compare(num1.doubleValue(), num2.doubleValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseCompareDouble_thenWillExecuteComparison() {
|
||||
assertEquals(0, compareDouble(5, 5.0));
|
||||
}
|
||||
|
||||
public int compareTo(Integer int1, Integer int2) {
|
||||
return int1.compareTo(int2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseCompareTo_thenWillExecuteComparison() {
|
||||
assertEquals(-1, compareTo(5, 7));
|
||||
}
|
||||
|
||||
Map<Class<? extends Number>, BiFunction<Number, Number, Integer>> comparisonMap = new HashMap<>();
|
||||
|
||||
public int compareUsingMap(Number num1, Number num2) {
|
||||
comparisonMap.put(Integer.class, (a, b) -> ((Integer) num1).compareTo((Integer) num2));
|
||||
|
||||
return comparisonMap.get(num1.getClass())
|
||||
.apply(num1, num2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseCompareUsingMap_thenWillExecuteComparison() {
|
||||
assertEquals(-1, compareUsingMap(5, 7));
|
||||
}
|
||||
|
||||
public interface NumberComparator {
|
||||
int compare(Number num1, Number num2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseProxy_thenWillExecuteComparison() {
|
||||
NumberComparator proxy = (NumberComparator) Proxy.newProxyInstance(NumberComparator.class.getClassLoader(), new Class[] { NumberComparator.class },
|
||||
(p, method, args) -> Double.compare(((Number) args[0]).doubleValue(), ((Number) args[1]).doubleValue()));
|
||||
assertEquals(0, proxy.compare(5, 5.0));
|
||||
}
|
||||
|
||||
public int compareUsingReflection(Number num1, Number num2) throws Exception {
|
||||
Method method = num1.getClass()
|
||||
.getMethod("compareTo", num1.getClass());
|
||||
return (int) method.invoke(num1, num2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseCompareUsingReflection_thenWillExecuteComparison() throws Exception {
|
||||
assertEquals(-1, compareUsingReflection(5, 7));
|
||||
}
|
||||
|
||||
interface NumberComparatorFactory {
|
||||
Comparator<Number> getComparator();
|
||||
}
|
||||
|
||||
class IntegerComparatorFactory implements NumberComparatorFactory {
|
||||
@Override
|
||||
public Comparator<Number> getComparator() {
|
||||
return (num1, num2) -> ((Integer) num1).compareTo((Integer) num2);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseComparatorFactory_thenWillExecuteComparison() {
|
||||
NumberComparatorFactory factory = new IntegerComparatorFactory();
|
||||
Comparator<Number> comparator = factory.getComparator();
|
||||
assertEquals(-1, comparator.compare(5, 7));
|
||||
}
|
||||
|
||||
Function<Number, Double> toDouble = Number::doubleValue;
|
||||
BiPredicate<Number, Number> isEqual = (num1, num2) -> toDouble.apply(num1)
|
||||
.equals(toDouble.apply(num2));
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseIsEqual_thenWillExecuteComparison() {
|
||||
assertEquals(true, isEqual.test(5, 5.0));
|
||||
}
|
||||
|
||||
private Number someNumber = 5;
|
||||
private Number anotherNumber = 5.0;
|
||||
|
||||
Optional<Number> optNum1 = Optional.ofNullable(someNumber);
|
||||
Optional<Number> optNum2 = Optional.ofNullable(anotherNumber);
|
||||
int comparisonResult = optNum1.flatMap(n1 -> optNum2.map(n2 -> Double.compare(n1.doubleValue(), n2.doubleValue())))
|
||||
.orElse(0);
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseComparisonResult_thenWillExecuteComparison() {
|
||||
assertEquals(0, comparisonResult);
|
||||
}
|
||||
|
||||
private boolean someCondition = true;
|
||||
Function<Number, ?> dynamicFunction = someCondition ? Number::doubleValue : Number::intValue;
|
||||
Comparator<Number> dynamicComparator = (num1, num2) -> ((Comparable) dynamicFunction.apply(num1)).compareTo(dynamicFunction.apply(num2));
|
||||
|
||||
@Test
|
||||
void givenNumbers_whenUseDynamicComparator_thenWillExecuteComparison() {
|
||||
assertEquals(0, dynamicComparator.compare(5, 5.0));
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.optionalsasparameterrecords;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record Product(String name, double price, Optional<String> description) {
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.optionalsasparameterrecords;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class OptionalAsRecordParameterUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenRecordCreationWithOptional_thenCreateItProperly() {
|
||||
var emptyDescriptionProduct = new Product("television", 1699.99, Optional.empty());
|
||||
Assertions.assertEquals("television", emptyDescriptionProduct.name());
|
||||
Assertions.assertEquals(1699.99, emptyDescriptionProduct.price());
|
||||
Assertions.assertNull(emptyDescriptionProduct.description().orElse(null));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class AlphanumericPerformanceBenchmark {
|
||||
|
||||
public boolean isAlphanumeric(final int codePoint) {
|
||||
return (codePoint >= 65 && codePoint <= 90) ||
|
||||
(codePoint >= 97 && codePoint <= 172) ||
|
||||
(codePoint >= 97 && codePoint <= 122) ||
|
||||
(codePoint >= 48 && codePoint <= 57);
|
||||
}
|
||||
}
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.baeldung.streamtomapandmultimap;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class StreamToMapAndMultiMapUnitTest {
|
||||
@Test
|
||||
public void givenStringStream_whenConvertingToMapWithMerge_thenExpectedMapIsGenerated() {
|
||||
Stream<String> stringStream = Stream.of("one", "two", "three", "two");
|
||||
|
||||
Map<String, String> mergedMap = stringStream.collect(
|
||||
Collectors.toMap(s -> s, s -> s, (s1, s2) -> s1 + ", " + s2)
|
||||
);
|
||||
|
||||
// Define the expected map
|
||||
Map<String, String> expectedMap = Map.of(
|
||||
"one", "one",
|
||||
"two", "two, two",
|
||||
"three", "three"
|
||||
);
|
||||
|
||||
assertEquals(expectedMap, mergedMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringStream_whenConvertingToMultimap_thenExpectedMultimapIsGenerated() {
|
||||
Stream<String> stringStream = Stream.of("one", "two", "three", "two");
|
||||
|
||||
LinkedHashMultimap<Object, Object> multimap = LinkedHashMultimap.create();
|
||||
|
||||
stringStream.collect(Collectors.groupingBy(
|
||||
s -> s,
|
||||
Collectors.mapping(s -> s, Collectors.toList())
|
||||
)).forEach((key, value) -> multimap.putAll(key, value));
|
||||
|
||||
LinkedHashMultimap<Object, Object> expectedMultimap = LinkedHashMultimap.create();
|
||||
expectedMultimap.put("one", "one");
|
||||
expectedMultimap.put("two", "two");
|
||||
expectedMultimap.put("three", "three");
|
||||
|
||||
assertEquals(expectedMultimap, multimap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringStream_whenConvertingToMultimapWithStreamReduce_thenExpectedMultimapIsGenerated() {
|
||||
Stream<String> stringStream = Stream.of("one", "two", "three", "two");
|
||||
|
||||
Map<String, List<String>> multimap = stringStream.reduce(
|
||||
new HashMap<>(),
|
||||
(map, element) -> {
|
||||
map.computeIfAbsent(element, k -> new ArrayList<>()).add(element);
|
||||
return map;
|
||||
},
|
||||
(map1, map2) -> {
|
||||
map2.forEach((key, value) -> map1.merge(key, value, (list1, list2) -> {
|
||||
list1.addAll(list2);
|
||||
return list1;
|
||||
}));
|
||||
return map1;
|
||||
}
|
||||
);
|
||||
|
||||
Map<String, List<String>> expectedMultimap = new HashMap<>();
|
||||
expectedMultimap.put("one", Collections.singletonList("one"));
|
||||
expectedMultimap.put("two", Arrays.asList("two", "two"));
|
||||
expectedMultimap.put("three", Collections.singletonList("three"));
|
||||
|
||||
assertEquals(expectedMultimap, multimap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringStream_whenConvertingToMapWithStreamReduce_thenExpectedMapIsGenerated() {
|
||||
Stream<String> stringStream = Stream.of("one", "two", "three", "two");
|
||||
|
||||
Map<String, String> resultMap = stringStream.reduce(
|
||||
new HashMap<>(),
|
||||
(map, element) -> {
|
||||
map.put(element, element);
|
||||
return map;
|
||||
},
|
||||
(map1, map2) -> {
|
||||
map1.putAll(map2);
|
||||
return map1;
|
||||
}
|
||||
);
|
||||
|
||||
Map<String, String> expectedMap = new HashMap<>();
|
||||
expectedMap.put("one", "one");
|
||||
expectedMap.put("two", "two");
|
||||
expectedMap.put("three", "three");
|
||||
|
||||
assertEquals(expectedMap, resultMap);
|
||||
}
|
||||
}
|
||||
+38
-23
@@ -1,7 +1,11 @@
|
||||
package com.baeldung.streams;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -11,14 +15,12 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
class Java8StreamsUnitTest {
|
||||
|
||||
public class Java8StreamsUnitTest {
|
||||
private static List<String> list;
|
||||
|
||||
private List<String> list;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
@BeforeAll
|
||||
public static void init() {
|
||||
list = new ArrayList<>();
|
||||
list.add("One");
|
||||
list.add("OneAndOnly");
|
||||
@@ -42,60 +44,73 @@ public class Java8StreamsUnitTest {
|
||||
Stream<String> streamOf = Stream.of("a", "b", "c");
|
||||
assertEquals(streamOf.count(), 3);
|
||||
|
||||
long count = list.stream().distinct().count();
|
||||
long count = list.stream()
|
||||
.distinct()
|
||||
.count();
|
||||
assertEquals(count, 9);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkStreamCount_whenOperationFilter_thanCorrect() {
|
||||
Stream<String> streamFilter = list.stream().filter(element -> element.isEmpty());
|
||||
void checkStreamCount_whenOperationFilter_thanCorrect() {
|
||||
Stream<String> streamFilter = list.stream()
|
||||
.filter(element -> element.isEmpty());
|
||||
assertEquals(streamFilter.count(), 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkStreamCount_whenOperationMap_thanCorrect() {
|
||||
void checkStreamCount_whenOperationMap_thanCorrect() {
|
||||
List<String> uris = new ArrayList<>();
|
||||
uris.add("C:\\My.txt");
|
||||
Stream<Path> streamMap = uris.stream().map(uri -> Paths.get(uri));
|
||||
Stream<Path> streamMap = uris.stream()
|
||||
.map(uri -> Paths.get(uri));
|
||||
assertEquals(streamMap.count(), 1);
|
||||
|
||||
List<Detail> details = new ArrayList<>();
|
||||
details.add(new Detail());
|
||||
details.add(new Detail());
|
||||
Stream<String> streamFlatMap = details.stream().flatMap(detail -> detail.getParts().stream());
|
||||
Stream<String> streamFlatMap = details.stream()
|
||||
.flatMap(detail -> detail.getParts()
|
||||
.stream());
|
||||
assertEquals(streamFlatMap.count(), 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkStreamCount_whenOperationMatch_thenCorrect() {
|
||||
boolean isValid = list.stream().anyMatch(element -> element.contains("h"));
|
||||
boolean isValidOne = list.stream().allMatch(element -> element.contains("h"));
|
||||
boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h"));
|
||||
void checkStreamCount_whenOperationMatch_thenCorrect() {
|
||||
boolean isValid = list.stream()
|
||||
.anyMatch(element -> element.contains("h"));
|
||||
boolean isValidOne = list.stream()
|
||||
.allMatch(element -> element.contains("h"));
|
||||
boolean isValidTwo = list.stream()
|
||||
.noneMatch(element -> element.contains("h"));
|
||||
assertTrue(isValid);
|
||||
assertFalse(isValidOne);
|
||||
assertFalse(isValidTwo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkStreamReducedValue_whenOperationReduce_thenCorrect() {
|
||||
void checkStreamReducedValue_whenOperationReduce_thenCorrect() {
|
||||
List<Integer> integers = new ArrayList<>();
|
||||
integers.add(1);
|
||||
integers.add(1);
|
||||
integers.add(1);
|
||||
Integer reduced = integers.stream().reduce(23, (a, b) -> a + b);
|
||||
Integer reduced = integers.stream()
|
||||
.reduce(23, (a, b) -> a + b);
|
||||
assertTrue(reduced == 26);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkStreamContains_whenOperationCollect_thenCorrect() {
|
||||
List<String> resultList = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList());
|
||||
void checkStreamContains_whenOperationCollect_thenCorrect() {
|
||||
List<String> resultList = list.stream()
|
||||
.map(element -> element.toUpperCase())
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(resultList.size(), list.size());
|
||||
assertTrue(resultList.contains(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkParallelStream_whenDoWork() {
|
||||
list.parallelStream().forEach(element -> doWork(element));
|
||||
list.parallelStream()
|
||||
.forEach(element -> doWork(element));
|
||||
}
|
||||
|
||||
private void doWork(String string) {
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.baeldung.nthsubstring;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class FindNthSubstringIndexUnitTest {
|
||||
// "0 8 16 24 "
|
||||
private final static String INPUT = "a word, a word, a word, a word";
|
||||
|
||||
@Test
|
||||
void whenCallingIndexOfTwice_thenGetTheSecondSubstringIndex() {
|
||||
int firstIdx = INPUT.indexOf("a");
|
||||
int result = INPUT.indexOf("a", firstIdx + "a".length());
|
||||
assertEquals(8, result);
|
||||
}
|
||||
|
||||
// the recursive approach
|
||||
static int nthIndexOf(String input, String substring, int nth) {
|
||||
if (nth == 1) {
|
||||
return input.indexOf(substring);
|
||||
} else {
|
||||
return input.indexOf(substring, nthIndexOf(input, substring, nth - 1) + substring.length());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingRecursiveMethod_thenGetTheExpectedResult() {
|
||||
int result1 = nthIndexOf(INPUT, "a", 1);
|
||||
assertEquals(0, result1);
|
||||
|
||||
int result2 = nthIndexOf(INPUT, "a", 2);
|
||||
assertEquals(8, result2);
|
||||
|
||||
int result3 = nthIndexOf(INPUT, "a", 3);
|
||||
assertEquals(16, result3);
|
||||
|
||||
int result4 = nthIndexOf(INPUT, "a", 4);
|
||||
assertEquals(24, result4);
|
||||
|
||||
int result5 = nthIndexOf(INPUT, "a", 5);
|
||||
assertEquals(-1, result5);
|
||||
}
|
||||
|
||||
// loop-based approach
|
||||
static int nthIndexOf2(String input, String substring, int nth) {
|
||||
int index = -1;
|
||||
while (nth > 0) {
|
||||
index = input.indexOf(substring, index + substring.length());
|
||||
if (index == -1) {
|
||||
return -1;
|
||||
}
|
||||
nth--;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingLoopBasedMethod_thenGetTheExpectedResult() {
|
||||
int result1 = nthIndexOf2(INPUT, "a", 1);
|
||||
assertEquals(0, result1);
|
||||
|
||||
int result2 = nthIndexOf2(INPUT, "a", 2);
|
||||
assertEquals(8, result2);
|
||||
|
||||
int result3 = nthIndexOf2(INPUT, "a", 3);
|
||||
assertEquals(16, result3);
|
||||
|
||||
int result4 = nthIndexOf2(INPUT, "a", 4);
|
||||
assertEquals(24, result4);
|
||||
|
||||
int result5 = nthIndexOf2(INPUT, "a", 5);
|
||||
assertEquals(-1, result5);
|
||||
}
|
||||
|
||||
static int nthOccurrenceIndex(String input, String regexPattern, int nth) {
|
||||
Matcher matcher = Pattern.compile(regexPattern).matcher(INPUT);
|
||||
for (int i = 0; i < nth; i++) {
|
||||
if (!matcher.find()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return matcher.start();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingRegexBasedMethod_thenGetTheExpectedResult() {
|
||||
int result1 = nthOccurrenceIndex(INPUT, "a", 1);
|
||||
assertEquals(0, result1);
|
||||
|
||||
int result2 = nthOccurrenceIndex(INPUT, "a", 2);
|
||||
assertEquals(8, result2);
|
||||
|
||||
int result3 = nthOccurrenceIndex(INPUT, "a", 3);
|
||||
assertEquals(16, result3);
|
||||
|
||||
int result4 = nthOccurrenceIndex(INPUT, "a", 4);
|
||||
assertEquals(24, result4);
|
||||
|
||||
int result5 = nthOccurrenceIndex(INPUT, "a", 5);
|
||||
assertEquals(-1, result5);
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,11 @@
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring-core.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -95,6 +100,7 @@
|
||||
<javax.el-api.version>3.0.0</javax.el-api.version>
|
||||
<javax.el.version>2.2.6</javax.el.version>
|
||||
<commons-codec.version>1.14</commons-codec.version>
|
||||
<spring-core.version>5.3.0</spring-core.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+19
@@ -3,6 +3,7 @@ package com.baeldung.emptystrings;
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
@@ -109,6 +110,24 @@ public class EmptyStringsUnitTest {
|
||||
assertFalse(Strings.isNullOrEmpty(blankString));
|
||||
}
|
||||
|
||||
/*
|
||||
* Spring Core ObjectUtils
|
||||
*/
|
||||
@Test
|
||||
public void givenSomeEmptyString_thenObjectUtilsIsEmptyReturnsTrue() {
|
||||
assertTrue(ObjectUtils.isEmpty(emptyString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSomeNonEmptyString_thenObjectUtilsIsEmptyReturnsFalse() {
|
||||
assertFalse(ObjectUtils.isEmpty(nonEmptyString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSomeBlankString_thenObjectUtilsIsEmptyReturnsFalse() {
|
||||
assertFalse(ObjectUtils.isEmpty(blankString));
|
||||
}
|
||||
|
||||
/*
|
||||
* Bean Validation
|
||||
*/
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<opencsv.version>4.1</opencsv.version>
|
||||
<opencsv.version>5.8</opencsv.version>
|
||||
<spring-core.version>5.3.13</spring-core.version>
|
||||
<apache-commons-lang3.version>3.12.0</apache-commons-lang3.version>
|
||||
<apache-commons-text.version>1.10.0</apache-commons-text.version>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user