BAEL-2569 Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
b45b5cd909
@ -17,3 +17,4 @@
|
|||||||
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
|
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
|
||||||
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
||||||
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
||||||
|
- [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm)
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung.algorithms.relativelyprime;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
class RelativelyPrime {
|
||||||
|
|
||||||
|
static boolean iterativeRelativelyPrime(int a, int b) {
|
||||||
|
return iterativeGCD(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean recursiveRelativelyPrime(int a, int b) {
|
||||||
|
return recursiveGCD(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean bigIntegerRelativelyPrime(int a, int b) {
|
||||||
|
return BigInteger.valueOf(a).gcd(BigInteger.valueOf(b)).equals(BigInteger.ONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int iterativeGCD(int a, int b) {
|
||||||
|
int tmp;
|
||||||
|
while (b != 0) {
|
||||||
|
if (a < b) {
|
||||||
|
tmp = a;
|
||||||
|
a = b;
|
||||||
|
b = tmp;
|
||||||
|
}
|
||||||
|
tmp = b;
|
||||||
|
b = a % b;
|
||||||
|
a = tmp;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int recursiveGCD(int a, int b) {
|
||||||
|
if (b == 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (a < b) {
|
||||||
|
return recursiveGCD(b, a);
|
||||||
|
}
|
||||||
|
return recursiveGCD(b, a % b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.baeldung.algorithms.reversingtree;
|
||||||
|
|
||||||
|
public class TreeNode {
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
private TreeNode rightChild;
|
||||||
|
private TreeNode leftChild;
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode getRightChild() {
|
||||||
|
return rightChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightChild(TreeNode rightChild) {
|
||||||
|
this.rightChild = rightChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode getLeftChild() {
|
||||||
|
return leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftChild(TreeNode leftChild) {
|
||||||
|
this.leftChild = leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode(int value, TreeNode rightChild, TreeNode leftChild) {
|
||||||
|
this.value = value;
|
||||||
|
this.rightChild = rightChild;
|
||||||
|
this.leftChild = leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package com.baeldung.algorithms.reversingtree;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class TreeReverser {
|
||||||
|
|
||||||
|
public TreeNode createBinaryTree() {
|
||||||
|
|
||||||
|
TreeNode leaf1 = new TreeNode(3);
|
||||||
|
TreeNode leaf2 = new TreeNode(1);
|
||||||
|
TreeNode leaf3 = new TreeNode(9);
|
||||||
|
TreeNode leaf4 = new TreeNode(6);
|
||||||
|
|
||||||
|
TreeNode nodeLeft = new TreeNode(2, leaf1, leaf2);
|
||||||
|
TreeNode nodeRight = new TreeNode(7, leaf3, leaf4);
|
||||||
|
|
||||||
|
TreeNode root = new TreeNode(4, nodeRight, nodeLeft);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reverseRecursive(TreeNode treeNode) {
|
||||||
|
if (treeNode == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode temp = treeNode.getLeftChild();
|
||||||
|
treeNode.setLeftChild(treeNode.getRightChild());
|
||||||
|
treeNode.setRightChild(temp);
|
||||||
|
|
||||||
|
reverseRecursive(treeNode.getLeftChild());
|
||||||
|
reverseRecursive(treeNode.getRightChild());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reverseIterative(TreeNode treeNode) {
|
||||||
|
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
|
||||||
|
|
||||||
|
if (treeNode != null) {
|
||||||
|
queue.add(treeNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
|
||||||
|
TreeNode node = queue.poll();
|
||||||
|
if (node.getLeftChild() != null)
|
||||||
|
queue.add(node.getLeftChild());
|
||||||
|
if (node.getRightChild() != null)
|
||||||
|
queue.add(node.getRightChild());
|
||||||
|
|
||||||
|
TreeNode temp = node.getLeftChild();
|
||||||
|
node.setLeftChild(node.getRightChild());
|
||||||
|
node.setRightChild(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(TreeNode root) {
|
||||||
|
if (root == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer buffer = new StringBuffer(String.valueOf(root.getValue())).append(" ");
|
||||||
|
|
||||||
|
buffer.append(toString(root.getLeftChild()));
|
||||||
|
buffer.append(toString(root.getRightChild()));
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.baeldung.algorithms.relativelyprime;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static com.baeldung.algorithms.relativelyprime.RelativelyPrime.*;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class RelativelyPrimeUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnFalse() {
|
||||||
|
|
||||||
|
boolean result = iterativeRelativelyPrime(45, 35);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnTrue() {
|
||||||
|
|
||||||
|
boolean result = iterativeRelativelyPrime(500, 501);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnFalse() {
|
||||||
|
|
||||||
|
boolean result = recursiveRelativelyPrime(45, 35);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnTrue() {
|
||||||
|
|
||||||
|
boolean result = recursiveRelativelyPrime(500, 501);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonRelativelyPrimeNumbers_whenCheckingUsingBigIntegers_shouldReturnFalse() {
|
||||||
|
|
||||||
|
boolean result = bigIntegerRelativelyPrime(45, 35);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRelativelyPrimeNumbers_whenCheckingBigIntegers_shouldReturnTrue() {
|
||||||
|
|
||||||
|
boolean result = bigIntegerRelativelyPrime(500, 501);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.algorithms.reversingtree;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TreeReverserUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTreeWhenReversingRecursivelyThenReversed() {
|
||||||
|
TreeReverser reverser = new TreeReverser();
|
||||||
|
|
||||||
|
TreeNode treeNode = reverser.createBinaryTree();
|
||||||
|
|
||||||
|
reverser.reverseRecursive(treeNode);
|
||||||
|
|
||||||
|
assertEquals("4 7 9 6 2 3 1", reverser.toString(treeNode)
|
||||||
|
.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTreeWhenReversingIterativelyThenReversed() {
|
||||||
|
TreeReverser reverser = new TreeReverser();
|
||||||
|
|
||||||
|
TreeNode treeNode = reverser.createBinaryTree();
|
||||||
|
|
||||||
|
reverser.reverseIterative(treeNode);
|
||||||
|
|
||||||
|
assertEquals("4 7 9 6 2 3 1", reverser.toString(treeNode)
|
||||||
|
.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,7 +3,3 @@
|
|||||||
## Core Java Cookbooks and Examples
|
## Core Java Cookbooks and Examples
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
|
|
||||||
- [Java - Reading a Large File Efficiently](http://www.baeldung.com/java-read-lines-large-file)
|
|
||||||
- [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string)
|
|
||||||
|
|
||||||
|
68
cloud-foundry-uaa/cf-uaa-config/uaa.yml
Normal file
68
cloud-foundry-uaa/cf-uaa-config/uaa.yml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
issuer:
|
||||||
|
uri: http://localhost:8080/uaa
|
||||||
|
|
||||||
|
spring_profiles: default,hsqldb
|
||||||
|
|
||||||
|
encryption:
|
||||||
|
active_key_label: CHANGE-THIS-KEY
|
||||||
|
encryption_keys:
|
||||||
|
- label: CHANGE-THIS-KEY
|
||||||
|
passphrase: CHANGEME
|
||||||
|
|
||||||
|
login:
|
||||||
|
serviceProviderKey: |
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXQIBAAKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5
|
||||||
|
L39WqS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vA
|
||||||
|
fpOwznoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQAB
|
||||||
|
AoGAVOj2Yvuigi6wJD99AO2fgF64sYCm/BKkX3dFEw0vxTPIh58kiRP554Xt5ges
|
||||||
|
7ZCqL9QpqrChUikO4kJ+nB8Uq2AvaZHbpCEUmbip06IlgdA440o0r0CPo1mgNxGu
|
||||||
|
lhiWRN43Lruzfh9qKPhleg2dvyFGQxy5Gk6KW/t8IS4x4r0CQQD/dceBA+Ndj3Xp
|
||||||
|
ubHfxqNz4GTOxndc/AXAowPGpge2zpgIc7f50t8OHhG6XhsfJ0wyQEEvodDhZPYX
|
||||||
|
kKBnXNHzAkEAyCA76vAwuxqAd3MObhiebniAU3SnPf2u4fdL1EOm92dyFs1JxyyL
|
||||||
|
gu/DsjPjx6tRtn4YAalxCzmAMXFSb1qHfwJBAM3qx3z0gGKbUEWtPHcP7BNsrnWK
|
||||||
|
vw6By7VC8bk/ffpaP2yYspS66Le9fzbFwoDzMVVUO/dELVZyBnhqSRHoXQcCQQCe
|
||||||
|
A2WL8S5o7Vn19rC0GVgu3ZJlUrwiZEVLQdlrticFPXaFrn3Md82ICww3jmURaKHS
|
||||||
|
N+l4lnMda79eSp3OMmq9AkA0p79BvYsLshUJJnvbk76pCjR28PK4dV1gSDUEqQMB
|
||||||
|
qy45ptdwJLqLJCeNoR0JUcDNIRhOCuOPND7pcMtX6hI/
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
serviceProviderKeyPassword: password
|
||||||
|
serviceProviderCertificate: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDSTCCArKgAwIBAgIBADANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJhdzEO
|
||||||
|
MAwGA1UECBMFYXJ1YmExDjAMBgNVBAoTBWFydWJhMQ4wDAYDVQQHEwVhcnViYTEO
|
||||||
|
MAwGA1UECxMFYXJ1YmExDjAMBgNVBAMTBWFydWJhMR0wGwYJKoZIhvcNAQkBFg5h
|
||||||
|
cnViYUBhcnViYS5hcjAeFw0xNTExMjAyMjI2MjdaFw0xNjExMTkyMjI2MjdaMHwx
|
||||||
|
CzAJBgNVBAYTAmF3MQ4wDAYDVQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAM
|
||||||
|
BgNVBAcTBWFydWJhMQ4wDAYDVQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAb
|
||||||
|
BgkqhkiG9w0BCQEWDmFydWJhQGFydWJhLmFyMIGfMA0GCSqGSIb3DQEBAQUAA4GN
|
||||||
|
ADCBiQKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5L39W
|
||||||
|
qS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vAfpOw
|
||||||
|
znoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQABo4Ha
|
||||||
|
MIHXMB0GA1UdDgQWBBTx0lDzjH/iOBnOSQaSEWQLx1syGDCBpwYDVR0jBIGfMIGc
|
||||||
|
gBTx0lDzjH/iOBnOSQaSEWQLx1syGKGBgKR+MHwxCzAJBgNVBAYTAmF3MQ4wDAYD
|
||||||
|
VQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAMBgNVBAcTBWFydWJhMQ4wDAYD
|
||||||
|
VQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAbBgkqhkiG9w0BCQEWDmFydWJh
|
||||||
|
QGFydWJhLmFyggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYvBJ
|
||||||
|
0HOZbbHClXmGUjGs+GS+xC1FO/am2suCSYqNB9dyMXfOWiJ1+TLJk+o/YZt8vuxC
|
||||||
|
KdcZYgl4l/L6PxJ982SRhc83ZW2dkAZI4M0/Ud3oePe84k8jm3A7EvH5wi5hvCkK
|
||||||
|
RpuRBwn3Ei+jCRouxTbzKPsuCVB+1sNyxMTXzf0=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
#The secret that an external login server will use to authenticate to the uaa using the id `login`
|
||||||
|
LOGIN_SECRET: loginsecret
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
token:
|
||||||
|
signing-key: |
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEAqUeygEfDGxI6c1VDQ6xIyUSLrP6iz1y97iHFbtXSxXaArL4a
|
||||||
|
...
|
||||||
|
v6Mtt5LcRAAVP7pemunTdju4h8Q/noKYlVDVL30uLYUfKBL4UKfOBw==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
verification-key: |
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUeygEfDGxI6c1VDQ6xI
|
||||||
|
...
|
||||||
|
AwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
43
cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml
Normal file
43
cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.example</groupId>
|
||||||
|
<artifactId>cf-uaa-oauth2-client</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>uaa-client-webapp</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.client;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class CFUAAOAuth2ClientApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CFUAAOAuth2ClientApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.client;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
||||||
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class CFUAAOAuth2ClientController {
|
||||||
|
|
||||||
|
@Value("${resource.server.url}")
|
||||||
|
private String remoteResourceServer;
|
||||||
|
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
private OAuth2AuthorizedClientService authorizedClientService;
|
||||||
|
|
||||||
|
public CFUAAOAuth2ClientController(OAuth2AuthorizedClientService authorizedClientService) {
|
||||||
|
this.authorizedClientService = authorizedClientService;
|
||||||
|
this.restTemplate = new RestTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
public String index(OAuth2AuthenticationToken authenticationToken) {
|
||||||
|
OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName());
|
||||||
|
OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken();
|
||||||
|
|
||||||
|
String response = "Hello, " + authenticationToken.getPrincipal().getName();
|
||||||
|
response += "</br></br>";
|
||||||
|
response += "Here is your accees token :</br>" + oAuth2AccessToken.getTokenValue();
|
||||||
|
response += "</br>";
|
||||||
|
response += "</br>You can use it to call these Resource Server APIs:";
|
||||||
|
response += "</br></br>";
|
||||||
|
response += "<a href='/read'>Call Resource Server Read API</a>";
|
||||||
|
response += "</br>";
|
||||||
|
response += "<a href='/write'>Call Resource Server Write API</a>";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/read")
|
||||||
|
public String read(OAuth2AuthenticationToken authenticationToken) {
|
||||||
|
String url = remoteResourceServer + "/read";
|
||||||
|
return callResourceServer(authenticationToken, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/write")
|
||||||
|
public String write(OAuth2AuthenticationToken authenticationToken) {
|
||||||
|
String url = remoteResourceServer + "/write";
|
||||||
|
return callResourceServer(authenticationToken, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String callResourceServer(OAuth2AuthenticationToken authenticationToken, String url) {
|
||||||
|
OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName());
|
||||||
|
OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken();
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Authorization", "Bearer " + oAuth2AccessToken.getTokenValue());
|
||||||
|
|
||||||
|
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
|
||||||
|
ResponseEntity<String> responseEntity = null;
|
||||||
|
|
||||||
|
String response = null;
|
||||||
|
try {
|
||||||
|
responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
|
||||||
|
response = responseEntity.getBody();
|
||||||
|
} catch (HttpClientErrorException e) {
|
||||||
|
response = e.getMessage();
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
server.port=8081
|
||||||
|
|
||||||
|
resource.server.url=http://localhost:8082
|
||||||
|
|
||||||
|
spring.security.oauth2.client.registration.uaa.client-name=Web App Client
|
||||||
|
spring.security.oauth2.client.registration.uaa.client-id=webappclient
|
||||||
|
spring.security.oauth2.client.registration.uaa.client-secret=webappclientsecret
|
||||||
|
spring.security.oauth2.client.registration.uaa.scope=resource.read,resource.write,openid,profile
|
||||||
|
|
||||||
|
spring.security.oauth2.client.provider.uaa.issuer-uri=http://localhost:8080/uaa/oauth/token
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
tintin
|
43
cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml
Normal file
43
cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.baeldung.cfuaa</groupId>
|
||||||
|
<artifactId>cf-uaa-oauth2-resource-server</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>cf-uaa-oauth2-resource-server</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class CFUAAOAuth2ResourceServerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CFUAAOAuth2ResourceServerApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||||
|
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class CFUAAOAuth2ResourceServerRestController {
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index(@AuthenticationPrincipal Jwt jwt) {
|
||||||
|
return String.format("Hello, %s!", jwt.getSubject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/read")
|
||||||
|
public String read(JwtAuthenticationToken jwtAuthenticationToken) {
|
||||||
|
return "Hello write: " + jwtAuthenticationToken.getTokenAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/write")
|
||||||
|
public String write(Principal principal) {
|
||||||
|
return "Hello write: " + principal.getName();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||||
|
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class CFUAAOAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/read/**").hasAuthority("SCOPE_resource.read")
|
||||||
|
.antMatchers("/write/**").hasAuthority("SCOPE_resource.write")
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
.and()
|
||||||
|
.oauth2ResourceServer()
|
||||||
|
.jwt();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
server.port=8082
|
||||||
|
|
||||||
|
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/uaa/oauth/token
|
@ -8,3 +8,6 @@
|
|||||||
- [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings)
|
- [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings)
|
||||||
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
|
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
|
||||||
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
|
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
|
||||||
|
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
|
||||||
|
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||||
|
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
||||||
|
37
core-groovy/src/main/groovy/com/baeldung/Person.groovy
Normal file
37
core-groovy/src/main/groovy/com/baeldung/Person.groovy
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung
|
||||||
|
|
||||||
|
class Person {
|
||||||
|
private String firstname
|
||||||
|
private String lastname
|
||||||
|
private Integer age
|
||||||
|
|
||||||
|
Person(String firstname, String lastname, Integer age) {
|
||||||
|
this.firstname = firstname
|
||||||
|
this.lastname = lastname
|
||||||
|
this.age = age
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFirstname() {
|
||||||
|
return firstname
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLastname() {
|
||||||
|
return lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastname(String lastname) {
|
||||||
|
this.lastname = lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getAge() {
|
||||||
|
return age
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAge(Integer age) {
|
||||||
|
this.age = age
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
class Closures {
|
||||||
|
|
||||||
|
def printWelcome = {
|
||||||
|
println "Welcome to Closures!"
|
||||||
|
}
|
||||||
|
|
||||||
|
def print = { name ->
|
||||||
|
println name
|
||||||
|
}
|
||||||
|
|
||||||
|
def formatToLowerCase(name) {
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
def formatToLowerCaseClosure = { name ->
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
def count=0
|
||||||
|
|
||||||
|
def increaseCount = {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
def greet = {
|
||||||
|
return "Hello! ${it}"
|
||||||
|
}
|
||||||
|
|
||||||
|
def multiply = { x, y ->
|
||||||
|
return x*y
|
||||||
|
}
|
||||||
|
|
||||||
|
def calculate = {int x, int y, String operation ->
|
||||||
|
|
||||||
|
//log closure
|
||||||
|
def log = {
|
||||||
|
println "Performing $it"
|
||||||
|
}
|
||||||
|
|
||||||
|
def result = 0
|
||||||
|
switch(operation) {
|
||||||
|
case "ADD":
|
||||||
|
log("Addition")
|
||||||
|
result = x+y
|
||||||
|
break
|
||||||
|
case "SUB":
|
||||||
|
log("Subtraction")
|
||||||
|
result = x-y
|
||||||
|
break
|
||||||
|
case "MUL":
|
||||||
|
log("Multiplication")
|
||||||
|
result = x*y
|
||||||
|
break
|
||||||
|
case "DIV":
|
||||||
|
log("Division")
|
||||||
|
result = x/y
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
def addAll = { int... args ->
|
||||||
|
return args.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
def volume(Closure areaCalculator, int... dimensions) {
|
||||||
|
if(dimensions.size() == 3) {
|
||||||
|
|
||||||
|
//consider dimension[0] = length, dimension[1] = breadth, dimension[2] = height
|
||||||
|
//for cube and cuboid
|
||||||
|
return areaCalculator(dimensions[0], dimensions[1]) * dimensions[2]
|
||||||
|
} else if(dimensions.size() == 2) {
|
||||||
|
|
||||||
|
//consider dimension[0] = radius, dimension[1] = height
|
||||||
|
//for cylinder and cone
|
||||||
|
return areaCalculator(dimensions[0]) * dimensions[1]
|
||||||
|
} else if(dimensions.size() == 1) {
|
||||||
|
|
||||||
|
//consider dimension[0] = radius
|
||||||
|
//for sphere
|
||||||
|
return areaCalculator(dimensions[0]) * dimensions[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
class Employee {
|
||||||
|
|
||||||
|
String fullName
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
class ClosuresUnitTest extends GroovyTestCase {
|
||||||
|
|
||||||
|
Closures closures = new Closures()
|
||||||
|
|
||||||
|
void testDeclaration() {
|
||||||
|
|
||||||
|
closures.print("Hello! Closure")
|
||||||
|
closures.formatToLowerCaseClosure("Hello! Closure")
|
||||||
|
|
||||||
|
closures.print.call("Hello! Closure")
|
||||||
|
closures.formatToLowerCaseClosure.call("Hello! Closure")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testClosureVsMethods() {
|
||||||
|
assert closures.formatToLowerCase("TONY STARK") == closures.formatToLowerCaseClosure("Tony STark")
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParameters() {
|
||||||
|
//implicit parameter
|
||||||
|
assert closures.greet("Alex") == "Hello! Alex"
|
||||||
|
|
||||||
|
//multiple parameters
|
||||||
|
assert closures.multiply(2, 4) == 8
|
||||||
|
|
||||||
|
assert closures.calculate(12, 4, "ADD") == 16
|
||||||
|
assert closures.calculate(12, 4, "SUB") == 8
|
||||||
|
assert closures.calculate(43, 8, "DIV") == 5.375
|
||||||
|
|
||||||
|
//varags
|
||||||
|
assert closures.addAll(12, 10, 14) == 36
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testClosureAsAnArgument() {
|
||||||
|
assert closures.volume({ l, b -> return l*b }, 12, 6, 10) == 720
|
||||||
|
|
||||||
|
assert closures.volume({ radius -> return Math.PI*radius*radius/3 }, 5, 10) == Math.PI * 250/3
|
||||||
|
}
|
||||||
|
|
||||||
|
void testGStringsLazyEvaluation() {
|
||||||
|
def name = "Samwell"
|
||||||
|
def welcomeMsg = "Welcome! $name"
|
||||||
|
|
||||||
|
assert welcomeMsg == "Welcome! Samwell"
|
||||||
|
|
||||||
|
// changing the name does not affect original interpolated value
|
||||||
|
name = "Tarly"
|
||||||
|
assert welcomeMsg != "Welcome! Tarly"
|
||||||
|
|
||||||
|
def fullName = "Tarly Samson"
|
||||||
|
def greetStr = "Hello! ${-> fullName}"
|
||||||
|
|
||||||
|
assert greetStr == "Hello! Tarly Samson"
|
||||||
|
|
||||||
|
// this time changing the variable affects the interpolated String's value
|
||||||
|
fullName = "Jon Smith"
|
||||||
|
assert greetStr == "Hello! Jon Smith"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testClosureInLists() {
|
||||||
|
def list = [10, 11, 12, 13, 14, true, false, "BUNTHER"]
|
||||||
|
list.each {
|
||||||
|
println it
|
||||||
|
}
|
||||||
|
|
||||||
|
assert [13, 14] == list.findAll{ it instanceof Integer && it >= 13}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testClosureInMaps() {
|
||||||
|
def map = [1:10, 2:30, 4:5]
|
||||||
|
|
||||||
|
assert [10, 60, 20] == map.collect{it.key * it.value}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -129,13 +129,13 @@ class ListTest{
|
|||||||
assertTrue(filterList.findAll{it > 3} == [4, 5, 6, 76])
|
assertTrue(filterList.findAll{it > 3} == [4, 5, 6, 76])
|
||||||
|
|
||||||
assertTrue(filterList.findAll{ it instanceof Number} == [2, 1, 3, 4, 5, 6, 76])
|
assertTrue(filterList.findAll{ it instanceof Number} == [2, 1, 3, 4, 5, 6, 76])
|
||||||
|
|
||||||
assertTrue(filterList.grep( Number )== [2, 1, 3, 4, 5, 6, 76])
|
assertTrue(filterList.grep( Number )== [2, 1, 3, 4, 5, 6, 76])
|
||||||
|
|
||||||
assertTrue(filterList.grep{ it> 6 }== [76])
|
assertTrue(filterList.grep{ it> 6 }== [76])
|
||||||
|
|
||||||
def conditionList = [2, 1, 3, 4, 5, 6, 76]
|
def conditionList = [2, 1, 3, 4, 5, 6, 76]
|
||||||
|
|
||||||
assertFalse(conditionList.every{ it < 6})
|
assertFalse(conditionList.every{ it < 6})
|
||||||
|
|
||||||
assertTrue(conditionList.any{ it%2 == 0})
|
assertTrue(conditionList.any{ it%2 == 0})
|
||||||
@ -165,7 +165,7 @@ class ListTest{
|
|||||||
|
|
||||||
def strList = ["na", "ppp", "as"]
|
def strList = ["na", "ppp", "as"]
|
||||||
assertTrue(strList.max() == "ppp")
|
assertTrue(strList.max() == "ppp")
|
||||||
|
|
||||||
Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1}
|
Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1}
|
||||||
def numberList = [3, 2, 0, 7]
|
def numberList = [3, 2, 0, 7]
|
||||||
assertTrue(numberList.min(minc) == 0)
|
assertTrue(numberList.min(minc) == 0)
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.baeldung.lists
|
||||||
|
|
||||||
|
import com.baeldung.Person
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.*
|
||||||
|
|
||||||
|
class ListUnitTest {
|
||||||
|
|
||||||
|
private final personList = [
|
||||||
|
new Person("Regina", "Fitzpatrick", 25),
|
||||||
|
new Person("Abagail", "Ballard", 26),
|
||||||
|
new Person("Lucian", "Walter", 30),
|
||||||
|
]
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenListContainsElement_thenCheckReturnsTrue() {
|
||||||
|
def list = ['a', 'b', 'c']
|
||||||
|
|
||||||
|
assertTrue(list.indexOf('a') > -1)
|
||||||
|
assertTrue(list.contains('a'))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenListContainsElement_thenCheckWithMembershipOperatorReturnsTrue() {
|
||||||
|
def list = ['a', 'b', 'c']
|
||||||
|
|
||||||
|
assertTrue('a' in list)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenListOfPerson_whenUsingStreamMatching_thenShouldEvaluateList() {
|
||||||
|
assertTrue(personList.stream().anyMatch {it.age > 20})
|
||||||
|
assertFalse(personList.stream().allMatch {it.age < 30})
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenListOfPerson_whenUsingCollectionMatching_thenShouldEvaluateList() {
|
||||||
|
assertTrue(personList.any {it.age > 20})
|
||||||
|
assertFalse(personList.every {it.age < 30})
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements() {
|
||||||
|
assertTrue(personList.stream().filter {it.age > 20}.findAny().isPresent())
|
||||||
|
assertFalse(personList.stream().filter {it.age > 30}.findAny().isPresent())
|
||||||
|
assertTrue(personList.stream().filter {it.age > 20}.findAll().size() == 3)
|
||||||
|
assertTrue(personList.stream().filter {it.age > 30}.findAll().isEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenListOfPerson_whenUsingCollectionFind_thenShouldReturnMatchingElements() {
|
||||||
|
assertNotNull(personList.find {it.age > 20})
|
||||||
|
assertNull(personList.find {it.age > 30})
|
||||||
|
assertTrue(personList.findAll {it.age > 20}.size() == 3)
|
||||||
|
assertTrue(personList.findAll {it.age > 30}.isEmpty())
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,18 @@
|
|||||||
package com.baeldung.map
|
package com.baeldung.map
|
||||||
|
|
||||||
import static org.junit.Assert.*
|
import com.baeldung.Person
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.*
|
||||||
|
|
||||||
class MapUnitTest {
|
class MapUnitTest {
|
||||||
|
|
||||||
|
private final personMap = [
|
||||||
|
Regina : new Person("Regina", "Fitzpatrick", 25),
|
||||||
|
Abagail: new Person("Abagail", "Ballard", 26),
|
||||||
|
Lucian : new Person("Lucian", "Walter", 30)
|
||||||
|
]
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void whenUsingEach_thenMapIsIterated() {
|
void whenUsingEach_thenMapIsIterated() {
|
||||||
def map = [
|
def map = [
|
||||||
@ -63,7 +71,7 @@ class MapUnitTest {
|
|||||||
'FF6347' : 'Tomato',
|
'FF6347' : 'Tomato',
|
||||||
'FF4500' : 'Orange Red'
|
'FF4500' : 'Orange Red'
|
||||||
]
|
]
|
||||||
|
|
||||||
map.eachWithIndex { key, val, index ->
|
map.eachWithIndex { key, val, index ->
|
||||||
def indent = ((index == 0 || index % 2 == 0) ? " " : "")
|
def indent = ((index == 0 || index % 2 == 0) ? " " : "")
|
||||||
println "$indent Hex Code: $key = Color Name: $val"
|
println "$indent Hex Code: $key = Color Name: $val"
|
||||||
@ -82,4 +90,65 @@ class MapUnitTest {
|
|||||||
println "Hex Code: $entry.key = Color Name: $entry.value"
|
println "Hex Code: $entry.key = Color Name: $entry.value"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenMapContainsKeyElement_thenCheckReturnsTrue() {
|
||||||
|
def map = [a: 'd', b: 'e', c: 'f']
|
||||||
|
|
||||||
|
assertTrue(map.containsKey('a'))
|
||||||
|
assertFalse(map.containsKey('e'))
|
||||||
|
assertTrue(map.containsValue('e'))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenMapContainsKeyElement_thenCheckByMembershipReturnsTrue() {
|
||||||
|
def map = [a: 'd', b: 'e', c: 'f']
|
||||||
|
|
||||||
|
assertTrue('a' in map)
|
||||||
|
assertFalse('f' in map)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenMapContainsFalseBooleanValues_thenCheckReturnsFalse() {
|
||||||
|
def map = [a: true, b: false, c: null]
|
||||||
|
|
||||||
|
assertTrue(map.containsKey('b'))
|
||||||
|
assertTrue('a' in map)
|
||||||
|
assertFalse('b' in map)
|
||||||
|
assertFalse('c' in map)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap() {
|
||||||
|
assertTrue(personMap.keySet().stream().anyMatch {it == "Regina"})
|
||||||
|
assertFalse(personMap.keySet().stream().allMatch {it == "Albert"})
|
||||||
|
assertFalse(personMap.values().stream().allMatch {it.age < 30})
|
||||||
|
assertTrue(personMap.entrySet().stream().anyMatch {it.key == "Abagail" && it.value.lastname == "Ballard"})
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap() {
|
||||||
|
assertTrue(personMap.keySet().any {it == "Regina"})
|
||||||
|
assertFalse(personMap.keySet().every {it == "Albert"})
|
||||||
|
assertFalse(personMap.values().every {it.age < 30})
|
||||||
|
assertTrue(personMap.any {firstname, person -> firstname == "Abagail" && person.lastname == "Ballard"})
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenMapOfPerson_whenUsingCollectionFind_thenShouldReturnElements() {
|
||||||
|
assertNotNull(personMap.find {it.key == "Abagail" && it.value.lastname == "Ballard"})
|
||||||
|
assertTrue(personMap.findAll {it.value.age > 20}.size() == 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenMapOfPerson_whenUsingStreamFind_thenShouldReturnElements() {
|
||||||
|
assertTrue(
|
||||||
|
personMap.entrySet().stream()
|
||||||
|
.filter {it.key == "Abagail" && it.value.lastname == "Ballard"}
|
||||||
|
.findAny().isPresent())
|
||||||
|
assertTrue(
|
||||||
|
personMap.entrySet().stream()
|
||||||
|
.filter {it.value.age > 20}
|
||||||
|
.findAll().size() == 3)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung.set
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue
|
||||||
|
|
||||||
|
class SetUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenSetContainsElement_thenCheckReturnsTrue() {
|
||||||
|
def set = ['a', 'b', 'c'] as Set
|
||||||
|
|
||||||
|
assertTrue(set.contains('a'))
|
||||||
|
assertTrue('a' in set)
|
||||||
|
}
|
||||||
|
}
|
@ -4,3 +4,5 @@
|
|||||||
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
|
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
|
||||||
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
||||||
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
|
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
|
||||||
|
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||||
|
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.jlink;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class HelloWorld {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(HelloWorld.class.getName());
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
LOG.info("Hello World!");
|
||||||
|
}
|
||||||
|
}
|
3
core-java-11/src/modules/jlinkModule/module-info.java
Normal file
3
core-java-11/src/modules/jlinkModule/module-info.java
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module jlinkModule {
|
||||||
|
requires java.logging;
|
||||||
|
}
|
48
core-java-12/pom.xml
Normal file
48
core-java-12/pom.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>core-java-12</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-12</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source.version}</source>
|
||||||
|
<target>${maven.compiler.target.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source.version>12</maven.compiler.source.version>
|
||||||
|
<maven.compiler.target.version>12</maven.compiler.target.version>
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.baeldung.collectors;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.maxBy;
|
||||||
|
import static java.util.stream.Collectors.minBy;
|
||||||
|
import static java.util.stream.Collectors.teeing;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for collectors additions in Java 12.
|
||||||
|
*/
|
||||||
|
public class CollectorsUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTeeing_ItShouldCombineTheResultsAsExpected() {
|
||||||
|
List<Integer> numbers = Arrays.asList(42, 4, 2, 24);
|
||||||
|
Range range = numbers.stream()
|
||||||
|
.collect(teeing(minBy(Integer::compareTo), maxBy(Integer::compareTo), (min, max) -> new Range(min.orElse(null), max.orElse(null))));
|
||||||
|
|
||||||
|
assertThat(range).isEqualTo(new Range(2, 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a closed range of numbers between {@link #min} and
|
||||||
|
* {@link #max}, both inclusive.
|
||||||
|
*/
|
||||||
|
private static class Range {
|
||||||
|
|
||||||
|
private final Integer min;
|
||||||
|
|
||||||
|
private final Integer max;
|
||||||
|
|
||||||
|
Range(Integer min, Integer max) {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
Range range = (Range) o;
|
||||||
|
return Objects.equals(getMin(), range.getMin()) && Objects.equals(getMax(), range.getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getMin(), getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Range{" + "min=" + min + ", max=" + max + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -124,11 +124,44 @@ public class Java8SortUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
|
public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
|
||||||
|
|
||||||
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
|
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
|
||||||
final Comparator<Human> nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
|
final Comparator<Human> nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
|
||||||
|
|
||||||
final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList());
|
final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList());
|
||||||
Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
|
Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenStreamComparatorOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
|
||||||
|
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
|
||||||
|
|
||||||
|
final List<Human> sortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName)).collect(Collectors.toList());
|
||||||
|
Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenStreamNaturalOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
|
||||||
|
final List<String> letters = Lists.newArrayList("B", "A", "C");
|
||||||
|
|
||||||
|
final List<String> reverseSortedLetters = letters.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
|
||||||
|
Assert.assertThat(reverseSortedLetters.get(0), equalTo("C"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenStreamCustomOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
|
||||||
|
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
|
||||||
|
final Comparator<Human> reverseNameComparator = (h1, h2) -> h2.getName().compareTo(h1.getName());
|
||||||
|
|
||||||
|
final List<Human> reverseSortedHumans = humans.stream().sorted(reverseNameComparator).collect(Collectors.toList());
|
||||||
|
Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenStreamComparatorOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
|
||||||
|
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
|
||||||
|
|
||||||
|
final List<Human> reverseSortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName, Comparator.reverseOrder())).collect(Collectors.toList());
|
||||||
|
Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.baeldung.java8.optional;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class OptionalChainingUnitTest {
|
||||||
|
|
||||||
|
private boolean getEmptyEvaluated;
|
||||||
|
private boolean getHelloEvaluated;
|
||||||
|
private boolean getByeEvaluated;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
getEmptyEvaluated = false;
|
||||||
|
getHelloEvaluated = false;
|
||||||
|
getByeEvaluated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturned() {
|
||||||
|
Optional<String> found = Stream.of(getEmpty(), getHello(), getBye())
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertEquals(getHello(), found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoEmptyOptionals_whenChaining_thenEmptyOptionalIsReturned() {
|
||||||
|
Optional<String> found = Stream.of(getEmpty(), getEmpty())
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertFalse(found.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoEmptyOptionals_whenChaining_thenDefaultIsReturned() {
|
||||||
|
String found = Stream.<Supplier<Optional<String>>>of(
|
||||||
|
() -> createOptional("empty"),
|
||||||
|
() -> createOptional("empty")
|
||||||
|
)
|
||||||
|
.map(Supplier::get)
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.findFirst()
|
||||||
|
.orElseGet(() -> "default");
|
||||||
|
|
||||||
|
assertEquals("default", found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturnedAndRestNotEvaluated() {
|
||||||
|
Optional<String> found = Stream.<Supplier<Optional<String>>>of(this::getEmpty, this::getHello, this::getBye)
|
||||||
|
.map(Supplier::get)
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertTrue(this.getEmptyEvaluated);
|
||||||
|
assertTrue(this.getHelloEvaluated);
|
||||||
|
assertFalse(this.getByeEvaluated);
|
||||||
|
assertEquals(getHello(), found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoOptionalsReturnedByOneArgMethod_whenChaining_thenFirstNonEmptyIsReturned() {
|
||||||
|
Optional<String> found = Stream.<Supplier<Optional<String>>>of(
|
||||||
|
() -> createOptional("empty"),
|
||||||
|
() -> createOptional("hello")
|
||||||
|
)
|
||||||
|
.map(Supplier::get)
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertEquals(createOptional("hello"), found);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> getEmpty() {
|
||||||
|
this.getEmptyEvaluated = true;
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> getHello() {
|
||||||
|
this.getHelloEvaluated = true;
|
||||||
|
return Optional.of("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> getBye() {
|
||||||
|
this.getByeEvaluated = true;
|
||||||
|
return Optional.of("bye");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> createOptional(String input) {
|
||||||
|
if (input == null || input == "" || input == "empty") {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(input);
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@
|
|||||||
- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)
|
- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)
|
||||||
- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
|
- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
|
||||||
- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture)
|
- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture)
|
||||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
|
||||||
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
|
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
|
||||||
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
||||||
- [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional)
|
- [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional)
|
||||||
@ -25,7 +24,9 @@
|
|||||||
- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range)
|
- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range)
|
||||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||||
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
|
||||||
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
||||||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
||||||
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
||||||
|
- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api)
|
||||||
|
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
||||||
|
|
||||||
|
@ -30,3 +30,4 @@
|
|||||||
- [Determine If All Elements Are the Same in a Java List](https://www.baeldung.com/java-list-all-equal)
|
- [Determine If All Elements Are the Same in a Java List](https://www.baeldung.com/java-list-all-equal)
|
||||||
- [List of Primitive Integer Values in Java](https://www.baeldung.com/java-list-primitive-int)
|
- [List of Primitive Integer Values in Java](https://www.baeldung.com/java-list-primitive-int)
|
||||||
- [Performance Comparison of Primitive Lists in Java](https://www.baeldung.com/java-list-primitive-performance)
|
- [Performance Comparison of Primitive Lists in Java](https://www.baeldung.com/java-list-primitive-performance)
|
||||||
|
- [Filtering a Java Collection by a List](https://www.baeldung.com/java-filter-collection-by-list)
|
||||||
|
@ -33,3 +33,4 @@
|
|||||||
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
||||||
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
|
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
|
||||||
- [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
|
- [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
|
||||||
|
- [Time Comparison of Arrays.sort(Object[]) and Arrays.sort(int[])](https://www.baeldung.com/arrays-sortobject-vs-sortint)
|
||||||
|
@ -21,4 +21,5 @@
|
|||||||
- [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch)
|
- [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch)
|
||||||
- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
|
- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
|
||||||
- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random)
|
- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random)
|
||||||
- [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join)
|
- [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join)
|
||||||
|
- [Passing Parameters to Java Threads](https://www.baeldung.com/java-thread-parameters)
|
||||||
|
@ -16,3 +16,4 @@
|
|||||||
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
|
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
|
||||||
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
|
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
|
||||||
- [What is Thread-Safety and How to Achieve it](https://www.baeldung.com/java-thread-safety)
|
- [What is Thread-Safety and How to Achieve it](https://www.baeldung.com/java-thread-safety)
|
||||||
|
- [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread)
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
- [Download a File From an URL in Java](http://www.baeldung.com/java-download-file)
|
- [Download a File From an URL in Java](http://www.baeldung.com/java-download-file)
|
||||||
- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink)
|
- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink)
|
||||||
- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter)
|
- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter)
|
||||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
|
||||||
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
||||||
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
||||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||||
@ -40,3 +39,4 @@
|
|||||||
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
||||||
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
||||||
- [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files)
|
- [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files)
|
||||||
|
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
||||||
|
6
core-java-jvm/README.md
Normal file
6
core-java-jvm/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
=========
|
||||||
|
|
||||||
|
## Core Java JVM Cookbooks and Examples
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Method Inlining in the JVM](http://www.baeldung.com/method-inlining-in-the-jvm/)
|
40
core-java-jvm/pom.xml
Normal file
40
core-java-jvm/pom.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>core-java-jvm</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>core-java-jvm</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.inlining;
|
||||||
|
|
||||||
|
public class ConsecutiveNumbersSum {
|
||||||
|
|
||||||
|
private long totalSum;
|
||||||
|
private int totalNumbers;
|
||||||
|
|
||||||
|
public ConsecutiveNumbersSum(int totalNumbers) {
|
||||||
|
this.totalNumbers = totalNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalSum() {
|
||||||
|
totalSum = 0;
|
||||||
|
for (int i = 1; i <= totalNumbers; i++) {
|
||||||
|
totalSum += i;
|
||||||
|
}
|
||||||
|
return totalSum;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung.inlining;
|
||||||
|
|
||||||
|
public class InliningExample {
|
||||||
|
|
||||||
|
public static final int NUMBERS_OF_ITERATIONS = 15000;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for (int i = 1; i < NUMBERS_OF_ITERATIONS; i++) {
|
||||||
|
calculateSum(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long calculateSum(int n) {
|
||||||
|
return new ConsecutiveNumbersSum(n).getTotalSum();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.inlining;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ConsecutiveNumbersSumUnitTest {
|
||||||
|
|
||||||
|
private static final int TOTAL_NUMBERS = 10;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTotalIntegersNumber_whenSumCalculated_thenEquals() {
|
||||||
|
ConsecutiveNumbersSum consecutiveNumbersSum = new ConsecutiveNumbersSum(TOTAL_NUMBERS);
|
||||||
|
long expectedSum = calculateExpectedSum(TOTAL_NUMBERS);
|
||||||
|
|
||||||
|
assertEquals(expectedSum, consecutiveNumbersSum.getTotalSum());
|
||||||
|
}
|
||||||
|
|
||||||
|
private long calculateExpectedSum(int totalNumbers) {
|
||||||
|
return totalNumbers * (totalNumbers + 1) / 2;
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Guide to hashCode() in Java](http://www.baeldung.com/java-hashcode)
|
- [Guide to hashCode() in Java](http://www.baeldung.com/java-hashcode)
|
||||||
- [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static)
|
- [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static)
|
||||||
- [A Guide to Java Initialization](http://www.baeldung.com/java-initialization)
|
|
||||||
- [Polymorphism in Java](http://www.baeldung.com/java-polymorphism)
|
- [Polymorphism in Java](http://www.baeldung.com/java-polymorphism)
|
||||||
- [Method Overloading and Overriding in Java](http://www.baeldung.com/java-method-overload-override)
|
- [Method Overloading and Overriding in Java](http://www.baeldung.com/java-method-overload-override)
|
||||||
- [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy)
|
- [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy)
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
### Relevant Articles:
|
|
||||||
- [A Guide to Java Enums](http://www.baeldung.com/a-guide-to-java-enums)
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung.generics;
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -28,4 +29,10 @@ public class Generics {
|
|||||||
buildings.forEach(Building::paint);
|
buildings.forEach(Building::paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Integer> createList(int a) {
|
||||||
|
List<Integer> list = new ArrayList<>();
|
||||||
|
list.add(a);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.hasItems;
|
import static org.hamcrest.CoreMatchers.hasItems;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
@ -66,4 +67,12 @@ public class GenericsUnitTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAnInt_whenAddedToAGenericIntegerList_thenAListItemCanBeAssignedToAnInt() {
|
||||||
|
int number = 7;
|
||||||
|
List<Integer> list = Generics.createList(number);
|
||||||
|
int otherNumber = list.get(0);
|
||||||
|
assertThat(otherNumber, is(number));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.baeldung.socket.read;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class Client {
|
||||||
|
|
||||||
|
public void runClient(String ip, int port) {
|
||||||
|
try {
|
||||||
|
Socket socket = new Socket(ip, port);
|
||||||
|
System.out.println("Connected to server ...");
|
||||||
|
DataInputStream in = new DataInputStream(System.in);
|
||||||
|
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
||||||
|
|
||||||
|
char type = 's'; // s for string
|
||||||
|
int length = 29;
|
||||||
|
String data = "This is a string of length 29";
|
||||||
|
byte[] dataInBytes = data.getBytes(StandardCharsets.UTF_8);
|
||||||
|
//Sending data in TLV format
|
||||||
|
out.writeChar(type);
|
||||||
|
out.writeInt(length);
|
||||||
|
out.write(dataInBytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.socket.read;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
|
||||||
|
public void runServer(int port) {
|
||||||
|
//Start the server and wait for connection
|
||||||
|
try {
|
||||||
|
ServerSocket server = new ServerSocket(port);
|
||||||
|
System.out.println("Server Started. Waiting for connection ...");
|
||||||
|
Socket socket = server.accept();
|
||||||
|
System.out.println("Got connection from client.");
|
||||||
|
//Get input stream from socket variable and convert the same to DataInputStream
|
||||||
|
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
|
||||||
|
//Read type and length of data
|
||||||
|
char dataType = in.readChar();
|
||||||
|
int length = in.readInt();
|
||||||
|
System.out.println("Type : "+dataType);
|
||||||
|
System.out.println("Lenght :"+length);
|
||||||
|
if(dataType == 's') {
|
||||||
|
//Read String data in bytes
|
||||||
|
byte[] messageByte = new byte[length];
|
||||||
|
boolean end = false;
|
||||||
|
StringBuilder dataString = new StringBuilder(length);
|
||||||
|
int totalBytesRead = 0;
|
||||||
|
//We need to run while loop, to read all data in that stream
|
||||||
|
while(!end) {
|
||||||
|
int currentBytesRead = in.read(messageByte);
|
||||||
|
totalBytesRead = currentBytesRead + totalBytesRead;
|
||||||
|
if(totalBytesRead <= length) {
|
||||||
|
dataString.append(new String(messageByte,0,currentBytesRead,StandardCharsets.UTF_8));
|
||||||
|
} else {
|
||||||
|
dataString.append(new String(messageByte,0,length - totalBytesRead + currentBytesRead,StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
if(dataString.length()>=length) {
|
||||||
|
end = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Read "+length+" bytes of message from client. Message = "+dataString);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.socket.read;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class SocketReadAllDataLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenServerAndClient_whenClientSendsAndServerReceivesData_thenCorrect() {
|
||||||
|
//Run server in new thread
|
||||||
|
Runnable runnable1 = () -> { runServer(); };
|
||||||
|
Thread thread1 = new Thread(runnable1);
|
||||||
|
thread1.start();
|
||||||
|
//Wait for 10 seconds
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
//Run client in a new thread
|
||||||
|
Runnable runnable2 = () -> { runClient(); };
|
||||||
|
Thread thread2 = new Thread(runnable2);
|
||||||
|
thread2.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runServer() {
|
||||||
|
//Run Server
|
||||||
|
Server server = new Server();
|
||||||
|
server.runServer(5555);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runClient() {
|
||||||
|
//Run Client
|
||||||
|
Client client = new Client();
|
||||||
|
client.runClient("127.0.0.1", 5555);
|
||||||
|
}
|
||||||
|
}
|
26
core-java-os/.gitignore
vendored
Normal file
26
core-java-os/.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
0.*
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
.resourceCache
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# Files generated by integration tests
|
||||||
|
*.txt
|
||||||
|
backup-pom.xml
|
||||||
|
/bin/
|
||||||
|
/temp
|
||||||
|
|
||||||
|
#IntelliJ specific
|
||||||
|
.idea/
|
||||||
|
*.iml
|
10
core-java-os/README.md
Normal file
10
core-java-os/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
=========
|
||||||
|
|
||||||
|
This module uses Java 9, so make sure to have the JDK 9 installed to run it.
|
||||||
|
|
||||||
|
##
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
||||||
|
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
||||||
|
- [Guide to java.lang.ProcessBuilder API](https://www.baeldung.com/java-lang-processbuilder-api)
|
||||||
|
|
82
core-java-os/pom.xml
Normal file
82
core-java-os/pom.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>core-java-os</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-os</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${commons-collections4.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons-io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>${log4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>core-java-os</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- util -->
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<commons-collections4.version>4.1</commons-collections4.version>
|
||||||
|
<collections-generic.version>4.01</collections-generic.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<asspectj.version>1.8.9</asspectj.version>
|
||||||
|
<maven.compiler.source>1.9</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.9</maven.compiler.target>
|
||||||
|
<guava.version>25.1-jre</guava.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
@ -3,5 +3,5 @@ package com.baeldung.java9.process;
|
|||||||
public class ProcessCompilationError {
|
public class ProcessCompilationError {
|
||||||
//This method has been written to generate error to display
|
//This method has been written to generate error to display
|
||||||
//how process errorStream() can consume error
|
//how process errorStream() can consume error
|
||||||
public static void();
|
//public static void();
|
||||||
}
|
}
|
13
core-java-os/src/main/resources/logback.xml
Normal file
13
core-java-os/src/main/resources/logback.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
@ -18,13 +18,13 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
public class ProcessAPIEnhancementsUnitTest {
|
public class ProcessAPIEnhancementsUnitTest {
|
||||||
|
|
||||||
Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsTest.class);
|
Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsUnitTest.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
||||||
ProcessHandle processHandle = ProcessHandle.current();
|
ProcessHandle processHandle = ProcessHandle.current();
|
||||||
ProcessHandle.Info processInfo = processHandle.info();
|
ProcessHandle.Info processInfo = processHandle.info();
|
||||||
assertNotNull(processHandle.getPid());
|
assertNotNull(processHandle.pid());
|
||||||
assertEquals(false, processInfo.arguments()
|
assertEquals(false, processInfo.arguments()
|
||||||
.isPresent());
|
.isPresent());
|
||||||
assertEquals(true, processInfo.command()
|
assertEquals(true, processInfo.command()
|
||||||
@ -51,7 +51,7 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||||||
.start();
|
.start();
|
||||||
ProcessHandle processHandle = process.toHandle();
|
ProcessHandle processHandle = process.toHandle();
|
||||||
ProcessHandle.Info processInfo = processHandle.info();
|
ProcessHandle.Info processInfo = processHandle.info();
|
||||||
assertNotNull(processHandle.getPid());
|
assertNotNull(processHandle.pid());
|
||||||
assertEquals(false, processInfo.arguments()
|
assertEquals(false, processInfo.arguments()
|
||||||
.isPresent());
|
.isPresent());
|
||||||
assertEquals(true, processInfo.command()
|
assertEquals(true, processInfo.command()
|
||||||
@ -72,7 +72,7 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||||||
Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();
|
Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();
|
||||||
liveProcesses.filter(ProcessHandle::isAlive)
|
liveProcesses.filter(ProcessHandle::isAlive)
|
||||||
.forEach(ph -> {
|
.forEach(ph -> {
|
||||||
assertNotNull(ph.getPid());
|
assertNotNull(ph.pid());
|
||||||
assertEquals(true, ph.info()
|
assertEquals(true, ph.info()
|
||||||
.command()
|
.command()
|
||||||
.isPresent());
|
.isPresent());
|
||||||
@ -102,12 +102,12 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||||||
Stream<ProcessHandle> children = ProcessHandle.current()
|
Stream<ProcessHandle> children = ProcessHandle.current()
|
||||||
.children();
|
.children();
|
||||||
children.filter(ProcessHandle::isAlive)
|
children.filter(ProcessHandle::isAlive)
|
||||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
|
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
||||||
.command()));
|
.command()));
|
||||||
Stream<ProcessHandle> descendants = ProcessHandle.current()
|
Stream<ProcessHandle> descendants = ProcessHandle.current()
|
||||||
.descendants();
|
.descendants();
|
||||||
descendants.filter(ProcessHandle::isAlive)
|
descendants.filter(ProcessHandle::isAlive)
|
||||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
|
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
||||||
.command()));
|
.command()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,12 +121,12 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||||||
.start();
|
.start();
|
||||||
ProcessHandle processHandle = process.toHandle();
|
ProcessHandle processHandle = process.toHandle();
|
||||||
|
|
||||||
log.info("PID: {} has started", processHandle.getPid());
|
log.info("PID: {} has started", processHandle.pid());
|
||||||
CompletableFuture<ProcessHandle> onProcessExit = processHandle.onExit();
|
CompletableFuture<ProcessHandle> onProcessExit = processHandle.onExit();
|
||||||
onProcessExit.get();
|
onProcessExit.get();
|
||||||
assertEquals(false, processHandle.isAlive());
|
assertEquals(false, processHandle.isAlive());
|
||||||
onProcessExit.thenAccept(ph -> {
|
onProcessExit.thenAccept(ph -> {
|
||||||
log.info("PID: {} has stopped", ph.getPid());
|
log.info("PID: {} has stopped", ph.pid());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +30,7 @@ public class ProcessApiUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public void processInfoExample() throws NoSuchAlgorithmException {
|
public void processInfoExample() throws NoSuchAlgorithmException {
|
||||||
ProcessHandle self = ProcessHandle.current();
|
ProcessHandle self = ProcessHandle.current();
|
||||||
long PID = self.getPid();
|
long PID = self.pid();
|
||||||
ProcessHandle.Info procInfo = self.info();
|
ProcessHandle.Info procInfo = self.info();
|
||||||
Optional<String[]> args = procInfo.arguments();
|
Optional<String[]> args = procInfo.arguments();
|
||||||
Optional<String> cmd = procInfo.commandLine();
|
Optional<String> cmd = procInfo.commandLine();
|
||||||
@ -45,7 +45,7 @@ public class ProcessApiUnitTest {
|
|||||||
|
|
||||||
Stream<ProcessHandle> allProc = ProcessHandle.current().children();
|
Stream<ProcessHandle> allProc = ProcessHandle.current().children();
|
||||||
allProc.forEach(p -> {
|
allProc.forEach(p -> {
|
||||||
System.out.println("Proc " + p.getPid());
|
System.out.println("Proc " + p.pid());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ public class ProcessApiUnitTest {
|
|||||||
public void createAndDestroyProcess() throws IOException, InterruptedException {
|
public void createAndDestroyProcess() throws IOException, InterruptedException {
|
||||||
int numberOfChildProcesses = 5;
|
int numberOfChildProcesses = 5;
|
||||||
for (int i = 0; i < numberOfChildProcesses; i++) {
|
for (int i = 0; i < numberOfChildProcesses; i++) {
|
||||||
createNewJVM(ServiceMain.class, i).getPid();
|
createNewJVM(ServiceMain.class, i).pid();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<ProcessHandle> childProc = ProcessHandle.current().children();
|
Stream<ProcessHandle> childProc = ProcessHandle.current().children();
|
||||||
@ -62,10 +62,10 @@ public class ProcessApiUnitTest {
|
|||||||
|
|
||||||
childProc = ProcessHandle.current().children();
|
childProc = ProcessHandle.current().children();
|
||||||
childProc.forEach(processHandle -> {
|
childProc.forEach(processHandle -> {
|
||||||
assertTrue("Process " + processHandle.getPid() + " should be alive!", processHandle.isAlive());
|
assertTrue("Process " + processHandle.pid() + " should be alive!", processHandle.isAlive());
|
||||||
CompletableFuture<ProcessHandle> onProcExit = processHandle.onExit();
|
CompletableFuture<ProcessHandle> onProcExit = processHandle.onExit();
|
||||||
onProcExit.thenAccept(procHandle -> {
|
onProcExit.thenAccept(procHandle -> {
|
||||||
System.out.println("Process with PID " + procHandle.getPid() + " has stopped");
|
System.out.println("Process with PID " + procHandle.pid() + " has stopped");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -73,14 +73,14 @@ public class ProcessApiUnitTest {
|
|||||||
|
|
||||||
childProc = ProcessHandle.current().children();
|
childProc = ProcessHandle.current().children();
|
||||||
childProc.forEach(procHandle -> {
|
childProc.forEach(procHandle -> {
|
||||||
assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy());
|
assertTrue("Could not kill process " + procHandle.pid(), procHandle.destroy());
|
||||||
});
|
});
|
||||||
|
|
||||||
Thread.sleep(5000);
|
Thread.sleep(5000);
|
||||||
|
|
||||||
childProc = ProcessHandle.current().children();
|
childProc = ProcessHandle.current().children();
|
||||||
childProc.forEach(procHandle -> {
|
childProc.forEach(procHandle -> {
|
||||||
assertFalse("Process " + procHandle.getPid() + " should not be alive!", procHandle.isAlive());
|
assertFalse("Process " + procHandle.pid() + " should not be alive!", procHandle.isAlive());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ import java.lang.Integer;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
class ProcessUnderstandingTest {
|
class ProcessUnderstandingUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenSourceProgram_whenExecutedFromAnotherProgram_thenSourceProgramOutput3() throws IOException {
|
public void givenSourceProgram_whenExecutedFromAnotherProgram_thenSourceProgramOutput3() throws IOException {
|
13
core-java-os/src/test/resources/.gitignore
vendored
Normal file
13
core-java-os/src/test/resources/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
@ -29,7 +29,6 @@
|
|||||||
- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid)
|
- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid)
|
||||||
- [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle)
|
- [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle)
|
||||||
- [Class Loaders in Java](http://www.baeldung.com/java-classloaders)
|
- [Class Loaders in Java](http://www.baeldung.com/java-classloaders)
|
||||||
- [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking)
|
|
||||||
- [Guide to Java Clock Class](http://www.baeldung.com/java-clock)
|
- [Guide to Java Clock Class](http://www.baeldung.com/java-clock)
|
||||||
- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class)
|
- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class)
|
||||||
- [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler)
|
- [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler)
|
||||||
@ -51,3 +50,4 @@
|
|||||||
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
||||||
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
||||||
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
||||||
|
- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post)
|
||||||
|
@ -2,3 +2,5 @@
|
|||||||
|
|
||||||
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
|
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
|
||||||
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
|
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
|
||||||
|
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
||||||
|
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)
|
||||||
|
@ -13,4 +13,66 @@
|
|||||||
<relativePath>../parent-kotlin</relativePath>
|
<relativePath>../parent-kotlin</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-test</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<kotlin.version>1.2.71</kotlin.version>
|
||||||
|
<junit.platform.version>1.1.1</junit.platform.version>
|
||||||
|
<junit.vintage.version>5.2.0</junit.vintage.version>
|
||||||
|
<assertj.version>3.10.0</assertj.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.annotations
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FIELD)
|
||||||
|
annotation class Positive
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FIELD)
|
||||||
|
annotation class AllowedNames(val names: Array<String>)
|
@ -0,0 +1,3 @@
|
|||||||
|
package com.baeldung.annotations
|
||||||
|
|
||||||
|
class Item(@Positive val amount: Float, @AllowedNames(["Alice", "Bob"]) val name: String)
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.annotations
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val item = Item(amount = 1.0f, name = "Bob")
|
||||||
|
val validator = Validator()
|
||||||
|
println("Is instance valid? ${validator.isValid(item)}")
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.annotations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Naive annotation-based validator.
|
||||||
|
* @author A.Shcherbakov
|
||||||
|
*/
|
||||||
|
class Validator() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if every item's property annotated with @Positive is positive and if
|
||||||
|
* every item's property annotated with @AllowedNames has a value specified in that annotation.
|
||||||
|
*/
|
||||||
|
fun isValid(item: Item): Boolean {
|
||||||
|
val fields = item::class.java.declaredFields
|
||||||
|
for (field in fields) {
|
||||||
|
field.isAccessible = true
|
||||||
|
for (annotation in field.annotations) {
|
||||||
|
val value = field.get(item)
|
||||||
|
if (field.isAnnotationPresent(Positive::class.java)) {
|
||||||
|
val amount = value as Float
|
||||||
|
if (amount < 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (field.isAnnotationPresent(AllowedNames::class.java)) {
|
||||||
|
val allowedNames = field.getAnnotation(AllowedNames::class.java)?.names
|
||||||
|
val name = value as String
|
||||||
|
allowedNames?.let {
|
||||||
|
if (!it.contains(name)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
for (ch in 'a'..'f') {
|
||||||
|
print(ch)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
|
||||||
|
for (ch in 'f' downTo 'a') {
|
||||||
|
print(ch)
|
||||||
|
}
|
||||||
|
}
|
21
core-kotlin-2/src/main/kotlin/com/baeldung/range/Color.kt
Normal file
21
core-kotlin-2/src/main/kotlin/com/baeldung/range/Color.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
enum class Color(val rgb: Int) {
|
||||||
|
BLUE(0x0000FF),
|
||||||
|
GREEN(0x008000),
|
||||||
|
RED(0xFF0000),
|
||||||
|
MAGENTA(0xFF00FF),
|
||||||
|
YELLOW(0xFFFF00);
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
println(Color.values().toList());
|
||||||
|
val red = Color.RED
|
||||||
|
val yellow = Color.YELLOW
|
||||||
|
val range = red..yellow
|
||||||
|
|
||||||
|
println(range.contains(Color.MAGENTA))
|
||||||
|
println(range.contains(Color.BLUE))
|
||||||
|
println(range.contains(Color.GREEN))
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import java.lang.IllegalStateException
|
||||||
|
|
||||||
|
class CustomColor(val rgb: Int): Comparable<CustomColor> {
|
||||||
|
|
||||||
|
override fun compareTo(other: CustomColor): Int {
|
||||||
|
return this.rgb.compareTo(other.rgb)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun rangeTo(that: CustomColor) = ColorRange(this,that)
|
||||||
|
|
||||||
|
operator fun inc(): CustomColor {
|
||||||
|
return CustomColor(rgb + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if(rgb < 0x000000 || rgb > 0xFFFFFF){
|
||||||
|
throw IllegalStateException("RGB must be between 0 and 16777215")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "CustomColor(rgb=$rgb)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ColorRange(override val start: CustomColor,
|
||||||
|
override val endInclusive: CustomColor) : ClosedRange<CustomColor>, Iterable<CustomColor>{
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<CustomColor> {
|
||||||
|
return ColorIterator(start, endInclusive)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColorIterator(val start: CustomColor, val endInclusive: CustomColor) : Iterator<CustomColor> {
|
||||||
|
|
||||||
|
var initValue = start
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return initValue <= endInclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): CustomColor {
|
||||||
|
return initValue++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a = CustomColor(0xABCDEF)
|
||||||
|
val b = CustomColor(-1)
|
||||||
|
val c = CustomColor(0xABCDFF)
|
||||||
|
|
||||||
|
for(color in a..c){
|
||||||
|
println(color)
|
||||||
|
}
|
||||||
|
}
|
18
core-kotlin-2/src/main/kotlin/com/baeldung/range/Filter.kt
Normal file
18
core-kotlin-2/src/main/kotlin/com/baeldung/range/Filter.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val r = 1..10
|
||||||
|
|
||||||
|
//Apply filter
|
||||||
|
val f = r.filter { it -> it % 2 == 0 }
|
||||||
|
println(f)
|
||||||
|
|
||||||
|
//Map
|
||||||
|
val m = r.map { it -> it * it }
|
||||||
|
println(m)
|
||||||
|
|
||||||
|
//Reduce
|
||||||
|
val rdc = r.reduce { a, b -> a + b }
|
||||||
|
println(rdc)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
println((1..9).first)
|
||||||
|
println((1..9 step 2).step)
|
||||||
|
println((3..9).reversed().last)
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
val r = 1..20
|
||||||
|
println(r.min())
|
||||||
|
println(r.max())
|
||||||
|
println(r.sum())
|
||||||
|
println(r.average())
|
||||||
|
println(r.count())
|
||||||
|
|
||||||
|
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
|
||||||
|
println(repeated.distinct())
|
||||||
|
}
|
28
core-kotlin-2/src/main/kotlin/com/baeldung/range/Range.kt
Normal file
28
core-kotlin-2/src/main/kotlin/com/baeldung/range/Range.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
for (i in 1..9) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
|
||||||
|
for (i in 9 downTo 1) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
|
||||||
|
for (i in 1.rangeTo(9)) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
|
||||||
|
for (i in 9.downTo(1)) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
|
||||||
|
for (i in 1 until 9) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
(1..9).reversed().forEach {
|
||||||
|
print(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
println()
|
||||||
|
|
||||||
|
(1..9).reversed().step(3).forEach {
|
||||||
|
print(it)
|
||||||
|
}
|
||||||
|
}
|
15
core-kotlin-2/src/main/kotlin/com/baeldung/range/Step.kt
Normal file
15
core-kotlin-2/src/main/kotlin/com/baeldung/range/Step.kt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
for(i in 1..9 step 2){
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
println()
|
||||||
|
|
||||||
|
for (i in 9 downTo 1 step 2){
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
for (i in 1 until 9) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.scope
|
||||||
|
|
||||||
|
data class Student(var studentId: String = "", var name: String = "", var surname: String = "") {
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Teacher(var teacherId: Int = 0, var name: String = "", var surname: String = "") {
|
||||||
|
fun setId(anId: Int): Teacher = apply { teacherId = anId }
|
||||||
|
fun setName(aName: String): Teacher = apply { name = aName }
|
||||||
|
fun setSurname(aSurname: String): Teacher = apply { surname = aSurname }
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Headers(val headerInfo: String)
|
||||||
|
|
||||||
|
data class Response(val headers: Headers)
|
||||||
|
|
||||||
|
data class RestClient(val url: String) {
|
||||||
|
fun getResponse() = Response(Headers("some header info"))
|
||||||
|
}
|
||||||
|
|
||||||
|
data class BankAccount(val id: Int) {
|
||||||
|
fun checkAuthorization(username: String) = Unit
|
||||||
|
fun addPayee(payee: String) = Unit
|
||||||
|
fun makePayment(paymentDetails: String) = Unit
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.baeldung.annotations
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
|
class ValidationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenAmountIsOneAndNameIsAlice_thenTrue() {
|
||||||
|
assertTrue(Validator().isValid(Item(1f, "Alice")))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenAmountIsOneAndNameIsBob_thenTrue() {
|
||||||
|
assertTrue(Validator().isValid(Item(1f, "Bob")))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenAmountIsMinusOneAndNameIsAlice_thenFalse() {
|
||||||
|
assertFalse(Validator().isValid(Item(-1f, "Alice")))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenAmountIsMinusOneAndNameIsBob_thenFalse() {
|
||||||
|
assertFalse(Validator().isValid(Item(-1f, "Bob")))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenAmountIsOneAndNameIsTom_thenFalse() {
|
||||||
|
assertFalse(Validator().isValid(Item(1f, "Tom")))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenAmountIsMinusOneAndNameIsTom_thenFalse() {
|
||||||
|
assertFalse(Validator().isValid(Item(-1f, "Tom")))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class CharRangeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCharRange() {
|
||||||
|
assertEquals(listOf('a', 'b', 'c'), ('a'..'c').toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCharDownRange() {
|
||||||
|
assertEquals(listOf('c', 'b', 'a'), ('c'.downTo('a')).toList())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class ColorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEnumRange() {
|
||||||
|
|
||||||
|
println(Color.values().toList());
|
||||||
|
val red = Color.RED
|
||||||
|
val yellow = Color.YELLOW
|
||||||
|
val range = red..yellow
|
||||||
|
|
||||||
|
assertTrue { range.contains(Color.MAGENTA) }
|
||||||
|
assertFalse { range.contains(Color.BLUE) }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import java.lang.IllegalStateException
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class CustomColorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInvalidConstructor(){
|
||||||
|
assertFailsWith(IllegalStateException::class){
|
||||||
|
CustomColor(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun assertHas10Colors(){
|
||||||
|
assertTrue {
|
||||||
|
val a = CustomColor(1)
|
||||||
|
val b = CustomColor(10)
|
||||||
|
val range = a..b
|
||||||
|
for(cc in range){
|
||||||
|
println(cc)
|
||||||
|
}
|
||||||
|
range.toList().size == 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun assertContains0xCCCCCC(){
|
||||||
|
assertTrue {
|
||||||
|
val a = CustomColor(0xBBBBBB)
|
||||||
|
val b = CustomColor(0xDDDDDD)
|
||||||
|
val range = a..b
|
||||||
|
range.contains(CustomColor(0xCCCCCC))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class FilterTest {
|
||||||
|
|
||||||
|
val r = 1..10
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun filterTest() {
|
||||||
|
assertEquals(listOf(2, 4, 6, 8, 10), r.filter { it -> it % 2 == 0 }.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun mapTest() {
|
||||||
|
assertEquals(listOf(1, 4, 9, 16, 25, 36, 49, 64, 81, 100), r.map { it -> it * it }.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun reduceTest() {
|
||||||
|
assertEquals(55, r.reduce { a, b -> a + b })
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class FirstLastTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFirst() {
|
||||||
|
assertEquals(1, (1..9).first)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testLast() {
|
||||||
|
assertEquals(9, (1..9).last)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testStep() {
|
||||||
|
assertEquals(2, (1..9 step 2).step)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class OtherRangeFunctionsTest {
|
||||||
|
|
||||||
|
val r = 1..20
|
||||||
|
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMin() {
|
||||||
|
assertEquals(1, r.min())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMax() {
|
||||||
|
assertEquals(20, r.max())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSum() {
|
||||||
|
assertEquals(210, r.sum())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAverage() {
|
||||||
|
assertEquals(10.5, r.average())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCount() {
|
||||||
|
assertEquals(20, r.count())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDistinct() {
|
||||||
|
assertEquals(listOf(1, 2, 4, 6, 10), repeated.distinct())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class RangeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRange() {
|
||||||
|
assertEquals(listOf(1,2,3), (1.rangeTo(3).toList()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDownTo(){
|
||||||
|
assertEquals(listOf(3,2,1), (3.downTo(1).toList()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUntil(){
|
||||||
|
assertEquals(listOf(1,2), (1.until(3).toList()))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class ReverseRangeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun reversedTest() {
|
||||||
|
assertEquals(listOf(9, 6, 3), (1..9).reversed().step(3).toList())
|
||||||
|
}
|
||||||
|
}
|
17
core-kotlin-2/src/test/kotlin/com/baeldung/range/StepTest.kt
Normal file
17
core-kotlin-2/src/test/kotlin/com/baeldung/range/StepTest.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class StepTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testStep() {
|
||||||
|
assertEquals(listOf(1, 3, 5, 7, 9), (1..9 step 2).toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testStepDown() {
|
||||||
|
assertEquals(listOf(9, 7, 5, 3, 1), (9 downTo 1 step 2).toList())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class UntilRangeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUntil() {
|
||||||
|
assertEquals(listOf(1, 2, 3, 4), (1 until 5).toList())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.baeldung.scope
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
|
||||||
|
class ScopeFunctionsUnitTest {
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
|
||||||
|
var called : Boolean = false
|
||||||
|
|
||||||
|
fun info(message: String) {
|
||||||
|
called = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun wasCalled() = called
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldTransformWhenLetFunctionUsed() {
|
||||||
|
val stringBuider = StringBuilder()
|
||||||
|
val numberOfCharacters = stringBuider.let {
|
||||||
|
it.append("This is a transformation function.")
|
||||||
|
it.append("It takes a StringBuilder instance and returns the number of characters in the generated String")
|
||||||
|
it.length
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
numberOfCharacters == 128
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldHandleNullabilityWhenLetFunctionUsed() {
|
||||||
|
|
||||||
|
val message: String? = "hello there!"
|
||||||
|
val charactersInMessage = message?.let {
|
||||||
|
"At this point is safe to reference the variable. Let's print the message: $it"
|
||||||
|
} ?: "default value"
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!")
|
||||||
|
}
|
||||||
|
|
||||||
|
val aNullMessage = null
|
||||||
|
val thisIsNull = aNullMessage?.let {
|
||||||
|
"At this point it would be safe to reference the variable. But it will not really happen because it is null. Let's reference: $it"
|
||||||
|
} ?: "default value"
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
thisIsNull.equals("default value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldInitializeObjectWhenUsingApply() {
|
||||||
|
val aStudent = Student().apply {
|
||||||
|
studentId = "1234567"
|
||||||
|
name = "Mary"
|
||||||
|
surname = "Smith"
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
aStudent.name.equals("Mary")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldAllowBuilderStyleObjectDesignWhenApplyUsedInClassMethods() {
|
||||||
|
val teacher = Teacher()
|
||||||
|
.setId(1000)
|
||||||
|
.setName("Martha")
|
||||||
|
.setSurname("Spector")
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
teacher.surname.equals("Spector")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldAllowSideEffectWhenUsingAlso() {
|
||||||
|
val restClient = RestClient("http://www.someurl.com")
|
||||||
|
|
||||||
|
val logger = Logger()
|
||||||
|
|
||||||
|
val headers = restClient
|
||||||
|
.getResponse()
|
||||||
|
.also { logger.info(it.toString()) }
|
||||||
|
.headers
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
logger.wasCalled() && headers.headerInfo.equals("some header info")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldInitializeFieldWhenAlsoUsed() {
|
||||||
|
val aStudent = Student().also { it.name = "John"}
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
aStudent.name.equals("John")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldLogicallyGroupObjectCallsWhenUsingWith() {
|
||||||
|
val bankAccount = BankAccount(1000)
|
||||||
|
with (bankAccount) {
|
||||||
|
checkAuthorization("someone")
|
||||||
|
addPayee("some payee")
|
||||||
|
makePayment("payment information")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldConvertObjectWhenRunUsed() {
|
||||||
|
val stringBuider = StringBuilder()
|
||||||
|
val numberOfCharacters = stringBuider.run {
|
||||||
|
append("This is a transformation function.")
|
||||||
|
append("It takes a StringBuilder instance and returns the number of characters in the generated String")
|
||||||
|
length
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
numberOfCharacters == 128
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldHandleNullabilityWhenRunIsUsed() {
|
||||||
|
val message: String? = "hello there!"
|
||||||
|
val charactersInMessage = message?.run {
|
||||||
|
"At this point is safe to reference the variable. Let's print the message: $this"
|
||||||
|
} ?: "default value"
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package com.baeldung.lambda
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class SplittingTest {
|
||||||
|
private val evenList = listOf(0, "a", 1, "b", 2, "c");
|
||||||
|
|
||||||
|
private val unevenList = listOf(0, "a", 1, "b", 2, "c", 3);
|
||||||
|
|
||||||
|
private fun verifyList(resultList: List<List<Any>>) {
|
||||||
|
assertEquals("[[0, a], [1, b], [2, c]]", resultList.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun verifyPartialList(resultList: List<List<Any>>) {
|
||||||
|
assertEquals("[[0, a], [1, b], [2, c], [3]]", resultList.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenChunked_thenListIsSplit() {
|
||||||
|
val resultList = evenList.chunked(2)
|
||||||
|
verifyList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenUnevenChunked_thenListIsSplit() {
|
||||||
|
val resultList = unevenList.chunked(2)
|
||||||
|
verifyPartialList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenWindowed_thenListIsSplit() {
|
||||||
|
val resultList = evenList.windowed(2, 2)
|
||||||
|
verifyList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenUnevenPartialWindowed_thenListIsSplit() {
|
||||||
|
val resultList = unevenList.windowed(2, 2, partialWindows = true)
|
||||||
|
verifyPartialList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenUnevenWindowed_thenListIsSplit() {
|
||||||
|
val resultList = unevenList.windowed(2, 2, partialWindows = false)
|
||||||
|
verifyList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenGroupByWithAscendingNumbers_thenListIsSplit() {
|
||||||
|
val numberList = listOf(1, 2, 3, 4, 5, 6);
|
||||||
|
val resultList = numberList.groupBy { (it + 1) / 2 }
|
||||||
|
assertEquals("[[1, 2], [3, 4], [5, 6]]", resultList.values.toString())
|
||||||
|
assertEquals("[1, 2, 3]", resultList.keys.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenGroupByWithAscendingNumbersUneven_thenListIsSplit() {
|
||||||
|
val numberList = listOf(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
val resultList = numberList.groupBy { (it + 1) / 2 }.values
|
||||||
|
assertEquals("[[1, 2], [3, 4], [5, 6], [7]]", resultList.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenGroupByWithRandomNumbers_thenListIsSplitInWrongWay() {
|
||||||
|
val numberList = listOf(1, 3, 8, 20, 23, 30);
|
||||||
|
val resultList = numberList.groupBy { (it + 1) / 2 }
|
||||||
|
assertEquals("[[1], [3], [8], [20], [23], [30]]", resultList.values.toString())
|
||||||
|
assertEquals("[1, 2, 4, 10, 12, 15]", resultList.keys.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenWithIndexGroupBy_thenListIsSplit() {
|
||||||
|
val resultList = evenList.withIndex()
|
||||||
|
.groupBy { it.index / 2 }
|
||||||
|
.map { it.value.map { it.value } }
|
||||||
|
verifyList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenWithIndexGroupByUneven_thenListIsSplit() {
|
||||||
|
val resultList = unevenList.withIndex()
|
||||||
|
.groupBy { it.index / 2 }
|
||||||
|
.map { it.value.map { it.value } }
|
||||||
|
verifyPartialList(resultList)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenFoldIndexed_thenListIsSplit() {
|
||||||
|
val resultList = evenList.foldIndexed(ArrayList<ArrayList<Any>>(evenList.size / 2)) { index, acc, item ->
|
||||||
|
if (index % 2 == 0) {
|
||||||
|
acc.add(ArrayList(2))
|
||||||
|
}
|
||||||
|
acc.last().add(item)
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
verifyList(resultList)
|
||||||
|
}
|
||||||
|
}
|
@ -54,3 +54,5 @@
|
|||||||
- [Nested forEach in Kotlin](https://www.baeldung.com/kotlin-nested-foreach)
|
- [Nested forEach in Kotlin](https://www.baeldung.com/kotlin-nested-foreach)
|
||||||
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
||||||
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
|
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
|
||||||
|
- [Inline Functions in Kotlin](https://www.baeldung.com/kotlin-inline-functions)
|
||||||
|
- [Delegation Pattern in Kotlin](https://www.baeldung.com/kotlin-delegation-pattern)
|
||||||
|
@ -5,6 +5,15 @@ class Country(val name : String, val cities : List<City>)
|
|||||||
|
|
||||||
class City(val name : String, val streets : List<String>)
|
class City(val name : String, val streets : List<String>)
|
||||||
|
|
||||||
|
fun City.getStreetsWithCityName() : List<String> {
|
||||||
|
return streets.map { "$name, $it" }.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Country.getCitiesWithCountryName() : List<String> {
|
||||||
|
return cities.flatMap { it.getStreetsWithCityName() }
|
||||||
|
.map { "$name, $it" }
|
||||||
|
}
|
||||||
|
|
||||||
class World {
|
class World {
|
||||||
|
|
||||||
private val streetsOfAmsterdam = listOf("Herengracht", "Prinsengracht")
|
private val streetsOfAmsterdam = listOf("Herengracht", "Prinsengracht")
|
||||||
@ -45,6 +54,19 @@ class World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun allStreetsFlatMap() {
|
||||||
|
|
||||||
|
countries.flatMap { it.cities}
|
||||||
|
.flatMap { it.streets}
|
||||||
|
.forEach { println(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun allFlatMapTable() {
|
||||||
|
|
||||||
|
countries.flatMap { it.getCitiesWithCountryName() }
|
||||||
|
.forEach { println(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(args : Array<String>) {
|
fun main(args : Array<String>) {
|
||||||
@ -56,6 +78,10 @@ fun main(args : Array<String>) {
|
|||||||
world.allNested()
|
world.allNested()
|
||||||
|
|
||||||
world.allTable()
|
world.allTable()
|
||||||
|
|
||||||
|
world.allStreetsFlatMap()
|
||||||
|
|
||||||
|
world.allFlatMapTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user