├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── codeql.yml
│ └── maven.yml
├── .gitignore
├── LICENSE
├── README.adoc
├── days
├── day001
│ ├── pom.xml
│ └── src
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day001
│ │ └── Day001Test.java
├── day002
│ ├── pom.xml
│ └── src
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day002
│ │ └── Day002Test.java
├── day003
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day003
│ │ └── Day003.java
├── day004
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day004
│ │ └── Day004.java
├── day005
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day005
│ │ └── Day005.java
├── day006
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day006
│ │ └── Day006.java
├── day007
│ ├── pom.xml
│ └── src
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day007
│ │ └── Day007Test.java
├── day008
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day008
│ │ └── Day008.java
├── day009
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day009
│ │ └── Day009.java
├── day010
│ ├── pom.xml
│ └── src
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day010
│ │ └── Day010Test.java
├── day011
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day011
│ │ └── Day011.java
├── day012
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day012
│ │ └── Day012.java
├── day013
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day013
│ │ ├── Day013.java
│ │ └── MySingletonClass.java
├── day014
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day014
│ │ └── Day014.java
├── day015
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day015
│ │ ├── Day015.java
│ │ └── package-info.java
├── day016
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day016
│ │ └── Day016.java
├── day017
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day017
│ │ └── Day017.java
├── day018
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day018
│ │ └── Day018.java
├── day019
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day019
│ │ └── Day019.java
├── day020
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day020
│ │ └── Day020.java
├── day021
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day021
│ │ │ └── Day021.java
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day021
│ │ └── Day021Test.java
├── day022
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day022
│ │ └── Day022.java
├── day023
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day023
│ │ │ └── Day023.java
│ │ └── resources
│ │ └── config.properties
├── day024
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day024
│ │ └── Day024.java
├── day025
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day025
│ │ └── Day025.java
├── day026
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day026
│ │ └── Day026.java
├── day027
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day027
│ │ └── Day027.java
├── day028
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day028
│ │ └── Day028.java
├── day029
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day029
│ │ │ └── Day029.java
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day029
│ │ └── Day029Test.java
├── day030
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day030
│ │ └── Day030.java
├── day031
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day031
│ │ └── Day031.java
├── day032
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day032
│ │ └── Day032.java
├── day033
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day033
│ │ └── Day033.java
├── day034
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day034
│ │ └── Day034.java
├── day035
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day035
│ │ └── Day035.java
├── day036
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day036
│ │ └── Day036.java
├── day037
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day037
│ │ └── Day037.java
├── day038
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day038
│ │ ├── Day038.java
│ │ └── Operators.java
├── day039
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day039
│ │ └── Day039.java
├── day040
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day040
│ │ └── Day040.java
├── day041
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day041
│ │ └── Day041.java
├── day043
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day043
│ │ └── Day043.java
├── day044
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day044
│ │ └── Day044.java
├── day045
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day045
│ │ └── Day045.java
├── day046
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day046
│ │ └── Day046.java
├── day047
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day047
│ │ └── Day047.java
├── day048
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day048
│ │ └── Day048.java
├── day049
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day049
│ │ └── Day049.java
├── day050
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day050
│ │ └── Day050.java
├── day051
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day051
│ │ └── Day051.java
├── day052
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day052
│ │ └── Day052.java
├── day053
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day053
│ │ └── Day053.java
├── day054
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day054
│ │ └── Day054.java
├── day055
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day055
│ │ │ └── Day055.java
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day055
│ │ └── Day055Test.java
├── day056
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day056
│ │ └── Day056.java
├── day057
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day057
│ │ └── Day057.java
├── day058
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day058
│ │ └── Day058.java
├── day059
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day059
│ │ └── Day059.java
├── day060
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day060
│ │ └── Day060.java
├── day062
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day062
│ │ └── Day062.java
├── day063
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── Day063.java
├── day064
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day064
│ │ └── Day064.java
├── day065
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day065
│ │ └── Day065.java
├── day066
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day066
│ │ └── Day066.java
├── day067
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day067
│ │ └── Day067.java
├── day068
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day068
│ │ └── Day068.java
├── day069
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day069
│ │ └── Day069.java
├── day070
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day070
│ │ │ └── Day070.java
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day070
│ │ └── Day070Test.java
├── day071
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day071
│ │ │ ├── Application.java
│ │ │ ├── Day071.java
│ │ │ └── calculator
│ │ │ ├── Calculator.java
│ │ │ └── CalculatorImpl.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day072
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day072
│ │ │ ├── Application.java
│ │ │ ├── Day072.java
│ │ │ └── animal
│ │ │ ├── Animal.java
│ │ │ ├── Cat.java
│ │ │ └── Dog.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day073
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day073
│ │ │ ├── Application.java
│ │ │ ├── Day073.java
│ │ │ └── paymentprocessor
│ │ │ ├── Asynchronous.java
│ │ │ ├── AsynchronousPaymentProcessor.java
│ │ │ ├── Payment.java
│ │ │ ├── PaymentProcessor.java
│ │ │ ├── Synchronous.java
│ │ │ └── SynchronousPaymentProcessor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day074
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day074
│ │ └── Day074.java
├── day075
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day075
│ │ │ ├── Application.java
│ │ │ ├── Day075.java
│ │ │ ├── DependencyA.java
│ │ │ ├── DependencyB.java
│ │ │ ├── Payment.java
│ │ │ ├── PaymentProcessor.java
│ │ │ ├── PaymentProcessorFactory.java
│ │ │ └── PaymentProcessorImpl.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day076
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day076
│ │ └── Day076.java
├── day078
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day078
│ │ └── Day078.java
├── day079
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day079
│ │ ├── Day079.java
│ │ └── myservice
│ │ ├── MyService.java
│ │ ├── MyServiceFactory.java
│ │ └── MyServiceImpl.java
├── day080
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day080
│ │ └── Day080.java
├── day081
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day081
│ │ └── Day081.java
├── day082
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day082
│ │ └── Day082.java
├── day083
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day083
│ │ └── Day083.java
├── day084
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day084
│ │ └── Day084.java
├── day085
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day085
│ │ └── Day085.java
├── day086
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day086
│ │ └── Day086.java
├── day087
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day087
│ │ └── Day087.java
├── day088
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day088
│ │ └── Day088.java
├── day089
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day089
│ │ │ ├── Application.java
│ │ │ ├── BeanValidator.java
│ │ │ ├── Day089.java
│ │ │ ├── Maximum.java
│ │ │ ├── MethodValidator.java
│ │ │ └── Person.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day090
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day090
│ │ └── Day090.java
├── day091
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day091
│ │ └── Day091.java
├── day092
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day092
│ │ └── Day092.java
├── day093
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day093
│ │ └── Day093.java
├── day094
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day094
│ │ └── Day094.java
├── day095
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day095
│ │ └── Day095.java
├── day096
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day096
│ │ │ ├── AfterOrderCompletes.java
│ │ │ ├── AfterOrderCompletesObserver.java
│ │ │ ├── Application.java
│ │ │ ├── BeforeOrderCompletes.java
│ │ │ ├── BeforeOrderCompletesObserver.java
│ │ │ ├── Day096.java
│ │ │ ├── Order.java
│ │ │ └── OrderService.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day097
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day097
│ │ └── Day097.java
├── day098
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── thegreatapi
│ │ │ └── ahundreddaysofjava
│ │ │ └── day098
│ │ │ ├── Application.java
│ │ │ ├── Day098.java
│ │ │ ├── Email.java
│ │ │ ├── EmailValidator.java
│ │ │ ├── MyService.java
│ │ │ ├── Validate.java
│ │ │ └── ValidationInterceptor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── beans.xml
├── day099
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day099
│ │ └── Day099.java
├── day100
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── thegreatapi
│ │ └── ahundreddaysofjava
│ │ └── day100
│ │ ├── Day100.java
│ │ ├── ExecutionPlan.java
│ │ └── MyService.java
└── pom.xml
└── pom.xml
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: hbelmiro
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "maven"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 | ignore:
8 | - dependency-name: "org.apache.maven.plugins:maven-compiler-plugin"
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: "weekly"
13 |
--------------------------------------------------------------------------------
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
3 |
4 | # This workflow uses actions that are not certified by GitHub.
5 | # They are provided by a third-party and are governed by
6 | # separate terms of service, privacy policy, and support
7 | # documentation.
8 |
9 | name: Java CI with Maven
10 |
11 | on:
12 | push:
13 | branches: [ "main" ]
14 | pull_request:
15 | branches: [ "main" ]
16 |
17 | jobs:
18 | build:
19 |
20 | runs-on: ubuntu-latest
21 |
22 | steps:
23 | - uses: actions/checkout@v4
24 | - name: Set up JDK 22
25 | uses: actions/setup-java@v4
26 | with:
27 | java-version: '22'
28 | distribution: 'temurin'
29 | cache: maven
30 | - name: Build with Maven
31 | run: mvn -B verify --file pom.xml
32 |
33 | dependabot:
34 | permissions: write-all
35 | name: 'Dependabot'
36 | needs: [ build ]
37 | runs-on: ubuntu-latest
38 | if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}}
39 | steps:
40 | - name: Enable auto-merge for Dependabot PRs
41 | run: gh pr merge --auto --merge "$PR_URL"
42 | env:
43 | PR_URL: ${{github.event.pull_request.html_url}}
44 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # intellij
2 | /.idea
3 | *.iml
4 | /*.ipr
5 | /*.iws
6 | **/out/
7 | **/target/
8 |
--------------------------------------------------------------------------------
/days/day001/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 |
11 | day001
12 | day001
13 |
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 | org.junit.jupiter
21 | junit-jupiter-api
22 | test
23 |
24 |
25 | org.assertj
26 | assertj-core
27 | test
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | maven-clean-plugin
36 | 3.5.0
37 |
38 |
39 | maven-resources-plugin
40 | 3.3.1
41 |
42 |
43 | maven-compiler-plugin
44 | 3.8.0
45 |
46 |
47 | maven-surefire-plugin
48 | 3.5.3
49 |
50 |
51 | maven-jar-plugin
52 | 3.4.2
53 |
54 |
55 | maven-install-plugin
56 | 3.1.4
57 |
58 |
59 | maven-deploy-plugin
60 | 3.1.4
61 |
62 |
63 | maven-site-plugin
64 | 3.21.0
65 |
66 |
67 | maven-project-info-reports-plugin
68 | 3.9.0
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/days/day001/src/test/java/com/thegreatapi/ahundreddaysofjava/day001/Day001Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day001;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.security.SecureRandom;
6 |
7 | import static org.assertj.core.api.Assertions.assertThat;
8 |
9 | class Day001Test {
10 |
11 | public static final SecureRandom SECURE_RANDOM = new SecureRandom();
12 |
13 | private static int generateRandomNumberBetween(int minimum, int maximum) {
14 | return SECURE_RANDOM.nextInt(maximum - minimum) + minimum;
15 | }
16 |
17 | @Test
18 | void randomNumberBetween() {
19 | var minimum = 100;
20 | var maximum = 1000;
21 |
22 | int randomNumber = generateRandomNumberBetween(minimum, maximum);
23 |
24 | assertThat(randomNumber).isBetween(minimum, maximum);
25 | }
26 | }
--------------------------------------------------------------------------------
/days/day002/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day002
13 |
14 |
15 |
16 | org.junit.jupiter
17 | junit-jupiter
18 | test
19 |
20 |
21 | org.assertj
22 | assertj-core
23 | test
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/days/day002/src/test/java/com/thegreatapi/ahundreddaysofjava/day002/Day002Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day002;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.time.LocalDateTime;
6 | import java.time.format.DateTimeFormatter;
7 |
8 | import static org.assertj.core.api.Assertions.assertThat;
9 |
10 | class Day002Test {
11 |
12 | @Test
13 | void formatDate() {
14 | DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
15 |
16 | LocalDateTime currentDateTime = LocalDateTime.of(2020, 1, 31, 20, 35, 45);
17 |
18 | assertThat(currentDateTime.format(FORMATTER))
19 | .isEqualTo("31/01/2020 20:35:45");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/days/day003/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day003
13 |
14 |
--------------------------------------------------------------------------------
/days/day003/src/main/java/com/thegreatapi/ahundreddaysofjava/day003/Day003.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day003;
2 |
3 | import java.time.LocalTime;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.ScheduledExecutorService;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | public class Day003 {
9 |
10 | private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
11 |
12 | public static void main(String[] args) throws InterruptedException {
13 | var day003 = new Day003();
14 | day003.printCurrentTimeEvery2Seconds();
15 | Thread.sleep(15_000);
16 | day003.stopPrinting();
17 | }
18 |
19 | public void printCurrentTimeEvery2Seconds() {
20 | Runnable task = () -> System.out.println(LocalTime.now());
21 | scheduledExecutorService.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);
22 | }
23 |
24 | public void stopPrinting() {
25 | scheduledExecutorService.shutdown();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/days/day004/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day004
13 |
14 |
--------------------------------------------------------------------------------
/days/day004/src/main/java/com/thegreatapi/ahundreddaysofjava/day004/Day004.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day004;
2 |
3 | import java.time.LocalDate;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.Objects;
7 |
8 | public class Day004 {
9 |
10 | public static void main(String[] args) {
11 | List beatles = new ArrayList<>();
12 | beatles.add(new Person("1", "John Lennon", LocalDate.of(1940, 10, 9)));
13 | beatles.add(new Person("2", "Paul McCartney", LocalDate.of(1942, 6, 18)));
14 | beatles.add(new Person("3", "George Harrison", LocalDate.of(1943, 2, 25)));
15 | beatles.add(new Person("4", "Ringo Starr", LocalDate.of(1940, 7, 7)));
16 |
17 | removeItemUsingEquals(beatles);
18 |
19 | removeItemUsingAnSpecificFilter(beatles);
20 |
21 | System.out.println(beatles);
22 | }
23 |
24 | private static void removeItemUsingAnSpecificFilter(List beatles) {
25 | beatles.removeIf(person -> "George Harrison".equals(person.getName()));
26 | }
27 |
28 | private static void removeItemUsingEquals(List beatles) {
29 | var lennon = new Person("1", "John Lennon", LocalDate.of(1940, 10, 9));
30 | beatles.remove(lennon);
31 | }
32 |
33 | static class Person {
34 |
35 | private final String id;
36 |
37 | private final String name;
38 |
39 | private final LocalDate dateOfBirth;
40 |
41 | Person(String id, String name, LocalDate dateOfBirth) {
42 | this.id = id;
43 | this.name = name;
44 | this.dateOfBirth = dateOfBirth;
45 | }
46 |
47 | public String getId() {
48 | return id;
49 | }
50 |
51 | public String getName() {
52 | return name;
53 | }
54 |
55 | public LocalDate getDateOfBirth() {
56 | return dateOfBirth;
57 | }
58 |
59 | @Override
60 | public boolean equals(Object o) {
61 | if (this == o) {
62 | return true;
63 | }
64 | if (o == null || getClass() != o.getClass()) {
65 | return false;
66 | }
67 | var person = (Person) o;
68 | return Objects.equals(id, person.id) && Objects.equals(name, person.name) && Objects.equals(dateOfBirth, person.dateOfBirth);
69 | }
70 |
71 | @Override
72 | public int hashCode() {
73 | return Objects.hash(id, name, dateOfBirth);
74 | }
75 |
76 | @Override
77 | public String toString() {
78 | return "Person{" +
79 | "name='" + name + '\'' +
80 | '}';
81 | }
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/days/day005/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day005
13 |
14 |
--------------------------------------------------------------------------------
/days/day005/src/main/java/com/thegreatapi/ahundreddaysofjava/day005/Day005.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day005;
2 |
3 | import java.util.List;
4 | import java.util.stream.Collectors;
5 | import java.util.stream.Stream;
6 |
7 | public class Day005 {
8 |
9 | private static final String GUITAR = "Guitar";
10 | private static final String DRUMS = "Drums";
11 | private static final String BASS = "Bass";
12 | private static final String VOCALS = "Vocals";
13 | private static final String KEYBOARDS = "Keyboards";
14 |
15 | public static void main(String[] args) {
16 | List pinkFloyd = List.of(
17 | new BandMember("David Gilmour", GUITAR),
18 | new BandMember("Roger Waters", BASS),
19 | new BandMember("Richard Wright", KEYBOARDS),
20 | new BandMember("Nick Mason", DRUMS)
21 | );
22 |
23 | List ironMaiden = List.of(
24 | new BandMember("Bruce Dickinson", VOCALS),
25 | new BandMember("Steve Harris", BASS),
26 | new BandMember("Adrian Smith", GUITAR),
27 | new BandMember("Dave Murray", GUITAR),
28 | new BandMember("Nicko McBrain", DRUMS)
29 | );
30 |
31 | List blackSabbath = List.of(
32 | new BandMember("Ozzy Osbourne", VOCALS),
33 | new BandMember("Geezer Butler", BASS),
34 | new BandMember("Toni Iommi", GUITAR),
35 | new BandMember("Bill Ward", DRUMS)
36 | );
37 |
38 | Stream musicians = Stream.concat(Stream.concat(pinkFloyd.stream(), ironMaiden.stream()), blackSabbath.stream());
39 |
40 | List guitarPlayers = musicians.filter(bandMember -> GUITAR.equals(bandMember.instrument))
41 | .map(BandMember::name)
42 | .collect(Collectors.toList());
43 |
44 | System.out.println(guitarPlayers);
45 | }
46 |
47 | static record BandMember(String name, String instrument) {
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/days/day006/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day006
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day006/src/main/java/com/thegreatapi/ahundreddaysofjava/day006/Day006.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day006;
2 |
3 | import java.util.concurrent.CompletableFuture;
4 | import java.util.concurrent.ForkJoinPool;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | import static java.util.concurrent.TimeUnit.SECONDS;
9 |
10 | public class Day006 {
11 |
12 | private static final Logger LOGGER = Logger.getLogger(Day006.class.getName());
13 |
14 | public static void main(String[] args) {
15 | CompletableFuture.runAsync(Day006::task);
16 |
17 | LOGGER.info("Message from the main thread. Note that this message is logged before the async task ends.");
18 |
19 | LOGGER.info("Waiting for the async task to end.");
20 | boolean isQuiecent = ForkJoinPool.commonPool().awaitQuiescence(5, SECONDS);
21 | if (isQuiecent) {
22 | LOGGER.info("Async task ended.");
23 | } else {
24 | LOGGER.log(Level.SEVERE, "The async task is taking too long to finish. This program will end anyway.");
25 | }
26 | }
27 |
28 | private static void task() {
29 | LOGGER.info("Async task starting. This message is logged by the async task thread");
30 | try {
31 | Thread.sleep(1000);
32 | LOGGER.info("Async task is ending. This message is logged by the async task thread");
33 | } catch (InterruptedException e) {
34 | Thread.currentThread().interrupt();
35 | LOGGER.log(Level.SEVERE, "The async task thread was interrupted.", e);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/days/day007/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day007
13 |
14 |
15 | org.junit.jupiter
16 | junit-jupiter-api
17 | test
18 |
19 |
20 | org.assertj
21 | assertj-core
22 | test
23 |
24 |
25 |
--------------------------------------------------------------------------------
/days/day007/src/test/java/com/thegreatapi/ahundreddaysofjava/day007/Day007Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day007;
2 |
3 | import java.text.MessageFormat;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import org.junit.jupiter.api.Test;
6 |
7 | class Day007Test {
8 |
9 | @Test
10 | void shouldFormatMessageCorrectly() {
11 | // Arrange
12 | String param1 = "Hello";
13 | String param2 = "World";
14 | String param3 = "Java";
15 |
16 | // Act
17 | String actualMessage = MessageFormat.format(
18 | "This message contains 3 parameters. The #1 is ''{0}'', "
19 | + "the #2 is ''{1}'', and the #3 is ''{2}''.",
20 | param1, param2, param3);
21 |
22 | // Assert
23 | String expectedMessage = "This message contains 3 parameters. The #1 is"
24 | + " 'Hello', the #2 is 'World', and the #3 is 'Java'.";
25 | assertThat(actualMessage).isEqualTo(expectedMessage);
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/days/day008/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day008
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day008/src/main/java/com/thegreatapi/ahundreddaysofjava/day008/Day008.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day008;
2 |
3 | import java.security.SecureRandom;
4 | import java.text.MessageFormat;
5 | import java.util.concurrent.ExecutorService;
6 | import java.util.concurrent.Executors;
7 | import java.util.logging.Logger;
8 |
9 | public class Day008 {
10 |
11 | private static final Logger LOGGER = Logger.getLogger(Day008.class.getName());
12 |
13 | private static final SecureRandom RANDOM = new SecureRandom();
14 |
15 | public static void main(String[] args) {
16 | LOGGER.info("Creating a thread pool with 5 threads");
17 | ExecutorService executor = Executors.newFixedThreadPool(5);
18 |
19 | /*
20 | * Will submit 15 tasks. Note that there's only 5 threads to run all of them in our thread pool.
21 | * So the first 5 tasks will run simultaneously and 10 tasks will wait in the queue until a thread is available.
22 | */
23 | LOGGER.info("Starting tasks submissions.");
24 | try {
25 | for (var i = 1; i <= 15; i++) {
26 | int taskId = i;
27 | LOGGER.info(() -> MessageFormat.format("Will submit task {0}.", taskId));
28 | executor.submit(() -> task(taskId));
29 | }
30 | } finally {
31 | executor.shutdown();
32 | }
33 | }
34 |
35 | private static void task(int taskId) {
36 | LOGGER.info(() -> MessageFormat.format("Running task {0}.", taskId));
37 | simulateLongProcessing();
38 | LOGGER.info(() -> MessageFormat.format("Task {0} has finished.", taskId));
39 | }
40 |
41 | private static void simulateLongProcessing() {
42 | try {
43 | Thread.sleep((RANDOM.nextInt(3) + 10) * 1000L);
44 | } catch (InterruptedException e) {
45 | Thread.currentThread().interrupt();
46 | throw new RuntimeException(MessageFormat.format("Thread {0} was interrupted.", Thread.currentThread().getName()), e);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/days/day009/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day009
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day009/src/main/java/com/thegreatapi/ahundreddaysofjava/day009/Day009.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day009;
2 |
3 | public class Day009 {
4 |
5 | public static void main(String[] args) {
6 | for (Gender gender : Gender.values()) {
7 | System.out.printf("The value of %s is %s%n", gender, gender.getValue());
8 | }
9 | }
10 |
11 | public enum Gender {
12 | FEMALE('f'),
13 | MALE('m');
14 |
15 | private final char value;
16 |
17 | Gender(char value) {
18 | this.value = value;
19 | }
20 |
21 | public char getValue() {
22 | return value;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/days/day010/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day010
13 |
14 |
15 |
16 | org.junit.jupiter
17 | junit-jupiter-api
18 | test
19 |
20 |
21 | org.assertj
22 | assertj-core
23 | test
24 |
25 |
26 | com.google.jimfs
27 | jimfs
28 | test
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/days/day010/src/test/java/com/thegreatapi/ahundreddaysofjava/day010/Day010Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day010;
2 |
3 | import com.google.common.jimfs.Configuration;
4 | import com.google.common.jimfs.Jimfs;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import java.io.IOException;
8 | import java.nio.file.*;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 | import static org.assertj.core.api.Assertions.assertThatCode;
12 |
13 | class Day010Test {
14 |
15 | @Test
16 | void fileDoesNotExist() {
17 | FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix());
18 | Path directory = fileSystem.getPath("/directory");
19 | Path file = directory.resolve(fileSystem.getPath("myfile.txt"));
20 |
21 | assertThatCode(() -> Files.write(file, "thegreatapi.com".getBytes(), StandardOpenOption.WRITE))
22 | .isInstanceOf(NoSuchFileException.class);
23 | }
24 |
25 | @Test
26 | void fileExists() throws IOException {
27 | FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix());
28 | Path directory = fileSystem.getPath("/directory");
29 | Path file = directory.resolve(fileSystem.getPath("myfile.txt"));
30 |
31 | Files.createDirectory(directory);
32 | Files.createFile(file);
33 |
34 | assertThatCode(() -> Files.write(file, "thegreatapi.com".getBytes(), StandardOpenOption.WRITE))
35 | .doesNotThrowAnyException();
36 |
37 | assertThat(Files.readString(file))
38 | .isEqualTo("thegreatapi.com");
39 | }
40 | }
--------------------------------------------------------------------------------
/days/day011/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day011
13 |
14 |
15 |
16 |
17 | com.google.jimfs
18 | jimfs
19 | test
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/days/day011/src/main/java/com/thegreatapi/ahundreddaysofjava/day011/Day011.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day011;
2 |
3 | import java.util.Collections;
4 | import java.util.LinkedHashMap;
5 | import java.util.Map;
6 |
7 | public class Day011 {
8 |
9 | public static void main(String[] args) {
10 | Map unsortedMap = Map.of(
11 | "three", 3,
12 | "one", 1,
13 | "four", 4,
14 | "five", 5,
15 | "two", 2
16 | );
17 |
18 | Map sortedMap = sortByValue(unsortedMap);
19 |
20 | System.out.println(sortedMap);
21 | }
22 |
23 | private static Map sortByValue(Map unsortedMap) {
24 | Map sortedMap = new LinkedHashMap<>();
25 |
26 | unsortedMap.entrySet().stream()
27 | .sorted(Map.Entry.comparingByValue())
28 | .forEach(entry -> sortedMap.put(entry.getKey(), entry.getValue()));
29 |
30 | return Collections.unmodifiableMap(sortedMap);
31 | }
32 | }
--------------------------------------------------------------------------------
/days/day012/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day012
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day012/src/main/java/com/thegreatapi/ahundreddaysofjava/day012/Day012.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day012;
2 |
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.ExecutionException;
5 | import java.util.concurrent.Executors;
6 | import java.util.concurrent.Future;
7 | import java.util.logging.Logger;
8 |
9 | public class Day012 {
10 |
11 | private static final Logger LOGGER = Logger.getLogger(Day012.class.getName());
12 |
13 | public static void main(String[] args) throws InterruptedException {
14 | var executorService = Executors.newSingleThreadExecutor();
15 |
16 | try {
17 | Callable callable = Day012::doALongCalculation;
18 | Future future = executorService.submit(callable);
19 |
20 | doOtherThingWhileCalculating();
21 |
22 | LOGGER.info("Will get the calculated value. Note that the value will be got immediately");
23 | LOGGER.info("Calculated value: " + future.get());
24 | } catch (ExecutionException e) {
25 | e.printStackTrace();
26 | } finally {
27 | executorService.shutdown();
28 | }
29 | }
30 |
31 | private static int doALongCalculation() throws InterruptedException {
32 | Thread.sleep(5000L);
33 | return 42;
34 | }
35 |
36 | private static void doOtherThingWhileCalculating() throws InterruptedException {
37 | Thread.sleep(7000L);
38 | }
39 | }
--------------------------------------------------------------------------------
/days/day013/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day013
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day013/src/main/java/com/thegreatapi/ahundreddaysofjava/day013/Day013.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day013;
2 |
3 | import java.util.logging.Logger;
4 |
5 | public class Day013 {
6 |
7 | private static final Logger LOGGER = Logger.getLogger(Day013.class.getName());
8 |
9 | public static void main(String[] args) throws InterruptedException {
10 | LOGGER.info("Application started. Will wait 3 seconds.");
11 | Thread.sleep(3000);
12 |
13 | LOGGER.info("Will print the singleton class name.");
14 | LOGGER.info(MySingletonClass.class.getName());
15 |
16 | LOGGER.info("Will wait 3 seconds.");
17 | Thread.sleep(3000);
18 |
19 | LOGGER.info("Will get an instance of the singleton class.");
20 | MySingletonClass object = MySingletonClass.getInstance();
21 | LOGGER.info("Instance's creation DateTime: " + object.getCreationDateTime());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/days/day013/src/main/java/com/thegreatapi/ahundreddaysofjava/day013/MySingletonClass.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day013;
2 |
3 | import java.time.LocalDateTime;
4 |
5 | public final class MySingletonClass {
6 |
7 | private final LocalDateTime creationDateTime;
8 |
9 | private MySingletonClass(LocalDateTime creationDateTime) {
10 | this.creationDateTime = creationDateTime;
11 | }
12 |
13 | public LocalDateTime getCreationDateTime() {
14 | return creationDateTime;
15 | }
16 |
17 | public static MySingletonClass getInstance() {
18 | return InstanceHolder.INSTANCE;
19 | }
20 |
21 | private static final class InstanceHolder {
22 | static final MySingletonClass INSTANCE = new MySingletonClass(LocalDateTime.now());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/days/day014/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day014
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day014/src/main/java/com/thegreatapi/ahundreddaysofjava/day014/Day014.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day014;
2 |
3 | import java.math.BigDecimal;
4 |
5 | public class Day014 {
6 |
7 | public static void main(String[] args) {
8 | // Prints 1.229999999999999982236431605997495353221893310546875
9 | System.out.println(new BigDecimal(1.23));
10 |
11 | // Prints 1.23
12 | System.out.println(new BigDecimal("1.23"));
13 |
14 | // Prints 1.23
15 | System.out.println(BigDecimal.valueOf(1.23));
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day015/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day015
13 |
14 |
15 |
16 | com.google.code.findbugs
17 | jsr305
18 |
19 |
20 |
--------------------------------------------------------------------------------
/days/day015/src/main/java/com/thegreatapi/ahundreddaysofjava/day015/Day015.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day015;
2 |
3 | import javax.annotation.Nullable;
4 | import java.util.Collections;
5 | import java.util.List;
6 | import java.util.Objects;
7 |
8 | public class Day015 {
9 |
10 | public static void main(String[] args) {
11 | Person john = Person.builder()
12 | .name("John")
13 | .children(List.of(
14 | Person.builder()
15 | .name("Amanda")
16 | .petName("Toto")
17 | .build()
18 | ))
19 | .build();
20 |
21 | System.out.println(john);
22 | }
23 |
24 | public static class Person {
25 |
26 | private final String name;
27 |
28 | private final List children;
29 |
30 | @Nullable
31 | private final String petName;
32 |
33 | private Person(Builder builder) {
34 | name = Objects.requireNonNull(builder.name);
35 | children = builder.children != null ? builder.children : List.of();
36 | petName = builder.petName;
37 | }
38 |
39 | public String getName() {
40 | return name;
41 | }
42 |
43 | public List getChildren() {
44 | return children;
45 | }
46 |
47 | @Nullable
48 | public String getPetName() {
49 | return petName;
50 | }
51 |
52 | public static Builder builder() {
53 | return new Builder();
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return "Person{" +
59 | "name='" + name + '\'' +
60 | ", children=" + children +
61 | ", petName='" + petName + '\'' +
62 | '}';
63 | }
64 | }
65 |
66 | public static final class Builder {
67 |
68 | private String name;
69 |
70 | private List children;
71 |
72 | @Nullable
73 | private String petName;
74 |
75 | private Builder() {
76 | }
77 |
78 | public Builder name(String name) {
79 | this.name = name;
80 | return this;
81 | }
82 |
83 | public Builder children(List children) {
84 | this.children = Collections.unmodifiableList(children);
85 | return this;
86 | }
87 |
88 | public Builder petName(String petName) {
89 | this.petName = petName;
90 | return this;
91 | }
92 |
93 | public Person build() {
94 | return new Person(this);
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/days/day015/src/main/java/com/thegreatapi/ahundreddaysofjava/day015/package-info.java:
--------------------------------------------------------------------------------
1 | @ParametersAreNonnullByDefault
2 | package com.thegreatapi.ahundreddaysofjava.day015;
3 |
4 | import javax.annotation.ParametersAreNonnullByDefault;
--------------------------------------------------------------------------------
/days/day016/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day016
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day016/src/main/java/com/thegreatapi/ahundreddaysofjava/day016/Day016.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day016;
2 |
3 | public class Day016 {
4 |
5 | public static void main(String[] args) {
6 | System.out.println(createSql("id", "name", "coutry", "gender"));
7 | }
8 |
9 | private static String createSql(String... columns) {
10 | return new StringBuilder("SELECT ")
11 | .append(String.join(", ", columns))
12 | .append(" FROM PEOPLE")
13 | .toString();
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day017/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day017
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day017/src/main/java/com/thegreatapi/ahundreddaysofjava/day017/Day017.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day017;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | public class Day017 {
6 |
7 | private static final Pattern REGEX = Pattern.compile(", ");
8 |
9 | public static void main(String[] args) {
10 | System.out.println("Simple split: ");
11 | for (String column : simpleSplit()) {
12 | System.out.println(column);
13 | }
14 |
15 | System.out.println("Performant split: ");
16 | for (String column : performantSplit()) {
17 | System.out.println(column);
18 | }
19 | }
20 |
21 | private static String[] simpleSplit() {
22 | return "id, name, country, gender".split(", ");
23 | }
24 |
25 | // If you will split frequently, prefer this implementation.
26 | private static String[] performantSplit() {
27 | return REGEX.split("id, name, country, gender");
28 | }
29 | }
--------------------------------------------------------------------------------
/days/day018/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day018
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day018/src/main/java/com/thegreatapi/ahundreddaysofjava/day018/Day018.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day018;
2 |
3 | import java.util.Collection;
4 | import java.util.List;
5 | import java.util.NoSuchElementException;
6 |
7 | public class Day018 {
8 |
9 | public static void main(String[] args) {
10 | System.out.println(max(List.of(6, 3, 1, 8, 3, 9, 2, 7)));
11 | }
12 |
13 | private static Integer max(Collection collection) {
14 | return collection.stream()
15 | .max(Integer::compareTo)
16 | .orElseThrow(NoSuchElementException::new);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/days/day019/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day019
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day019/src/main/java/com/thegreatapi/ahundreddaysofjava/day019/Day019.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day019;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.Map;
5 |
6 | public class Day019 {
7 |
8 | public static void main(String[] args) {
9 | Map map = new LinkedHashMap<>();
10 |
11 | map.put(5, "five");
12 | map.put(4, "four");
13 | map.put(3, "three");
14 | map.put(2, "two");
15 | map.put(1, "one");
16 |
17 | map.forEach((key, value) -> System.out.println(key + ": " + value));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/days/day020/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day020
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day020/src/main/java/com/thegreatapi/ahundreddaysofjava/day020/Day020.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day020;
2 |
3 | public class Day020 {
4 |
5 | public static void main(String[] args) {
6 | var original = "moc.ipataergeht";
7 | var reversed = new StringBuilder(original).reverse().toString();
8 | System.out.println(reversed);
9 | }
10 | }
--------------------------------------------------------------------------------
/days/day021/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day021
13 |
14 |
15 |
16 | org.junit.jupiter
17 | junit-jupiter-api
18 | test
19 |
20 |
21 | com.github.tomakehurst
22 | wiremock-jre8
23 | test
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/days/day021/src/main/java/com/thegreatapi/ahundreddaysofjava/day021/Day021.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day021;
2 |
3 | public class Day021 {
4 |
5 | }
--------------------------------------------------------------------------------
/days/day021/src/test/java/com/thegreatapi/ahundreddaysofjava/day021/Day021Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day021;
2 |
3 | import com.github.tomakehurst.wiremock.WireMockServer;
4 | import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
5 | import org.junit.jupiter.api.AfterEach;
6 | import org.junit.jupiter.api.BeforeEach;
7 | import org.junit.jupiter.api.Test;
8 |
9 | import java.net.URI;
10 | import java.net.http.HttpClient;
11 | import java.net.http.HttpRequest;
12 | import java.net.http.HttpResponse;
13 |
14 | import static com.github.tomakehurst.wiremock.client.WireMock.get;
15 | import static com.github.tomakehurst.wiremock.client.WireMock.ok;
16 | import static org.junit.jupiter.api.Assertions.assertEquals;
17 |
18 | class Day021Test {
19 |
20 | private WireMockServer server;
21 |
22 | @BeforeEach
23 | void setUp() {
24 | server = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort());
25 | server.start();
26 | }
27 |
28 | @Test
29 | void test() throws Exception {
30 | mockWebServer();
31 |
32 | HttpClient client = HttpClient.newHttpClient();
33 | HttpRequest request = HttpRequest.newBuilder()
34 | .uri(URI.create("http://localhost:" + server.port() + "/my/resource"))
35 | .build();
36 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
37 |
38 | assertEquals("TheGreatAPI.com", response.body());
39 | }
40 |
41 | private void mockWebServer() {
42 | server.stubFor(get("/my/resource")
43 | .willReturn(ok()
44 | .withBody("TheGreatAPI.com")));
45 | }
46 |
47 | @AfterEach
48 | void tearDown() {
49 | server.shutdownServer();
50 | }
51 | }
--------------------------------------------------------------------------------
/days/day022/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day022
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day022/src/main/java/com/thegreatapi/ahundreddaysofjava/day022/Day022.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day022;
2 |
3 | import java.util.List;
4 |
5 | public class Day022 {
6 |
7 | public static void main(String[] args) {
8 | List orders = readOrders();
9 |
10 | String bands = orders.stream()
11 | .map(Order::customer)
12 | .map(Customer::band)
13 | .reduce((band1, band2) -> String.join(";", band1, band2))
14 | .orElse("None");
15 |
16 | System.out.println(bands);
17 | /* Prints:
18 | Pink Floyd;Black Sabbath;Ozzy Osbourne
19 | */
20 | }
21 |
22 | private static List readOrders() {
23 | var gilmour = new Customer("David Gilmour", "Pink Floyd");
24 | var iommi = new Customer("Toni Iommi", "Black Sabbath");
25 | var rhoads = new Customer("Randy Rhoads", "Ozzy Osbourne");
26 |
27 | var strato = new Product("Fender", "Stratocaster");
28 | var sg = new Product("Gibson", "SG");
29 | var lesPaul = new Product("Gibson", "Les Paul");
30 | var rr = new Product("Jackson", "RR");
31 |
32 | return List.of(
33 | new Order(gilmour, List.of(strato)),
34 | new Order(iommi, List.of(sg)),
35 | new Order(rhoads, List.of(lesPaul, rr))
36 | );
37 | }
38 |
39 | static record Customer(String name, String band) {
40 | }
41 |
42 | static record Product(String brand, String modelName) {
43 | }
44 |
45 | static record Order(Customer customer, List products) {
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/days/day023/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day023
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day023/src/main/java/com/thegreatapi/ahundreddaysofjava/day023/Day023.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day023;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 |
6 | public class Day023 {
7 |
8 | public static void main(String[] args) throws IOException {
9 | var properties = new Properties();
10 | try (var reader = Day023.class.getClassLoader().getResourceAsStream("config.properties")) {
11 | properties.load(reader);
12 | }
13 | System.out.println(properties);
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day023/src/main/resources/config.properties:
--------------------------------------------------------------------------------
1 | pool-size=42
2 | active=true
--------------------------------------------------------------------------------
/days/day024/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day024
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day024/src/main/java/com/thegreatapi/ahundreddaysofjava/day024/Day024.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day024;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 |
7 | import static java.util.concurrent.TimeUnit.SECONDS;
8 |
9 | public class Day024 {
10 |
11 | public static void main(String[] args) throws IOException, InterruptedException {
12 | var process = new ProcessBuilder("ls").start();
13 | try (var stdOutReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
14 | var stdErrReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
15 | if (process.waitFor(5, SECONDS)) {
16 | int exitValue = process.exitValue();
17 | if (exitValue == 0) {
18 | stdOutReader.lines().forEach(System.out::println);
19 | } else {
20 | stdErrReader.lines().forEach(System.err::println);
21 | }
22 | } else {
23 | throw new RuntimeException("Timeout");
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/days/day025/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day025
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day025/src/main/java/com/thegreatapi/ahundreddaysofjava/day025/Day025.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day025;
2 |
3 | public class Day025 {
4 |
5 | public static void main(String[] args) {
6 | Number n = 6;
7 |
8 | // Instead of doing:
9 | if (n instanceof Integer) {
10 | Integer i = (Integer) n;
11 | print(i);
12 | }
13 |
14 | // Just do:
15 | if (n instanceof Integer i) {
16 | print(i);
17 | }
18 | }
19 |
20 | private static void print(Integer i) {
21 | System.out.println(i);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/days/day026/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day026
13 |
14 |
15 |
16 | com.google.code.findbugs
17 | jsr305
18 |
19 |
20 |
--------------------------------------------------------------------------------
/days/day026/src/main/java/com/thegreatapi/ahundreddaysofjava/day026/Day026.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day026;
2 |
3 | import javax.annotation.Nonnull;
4 | import javax.annotation.Nullable;
5 | import java.util.Optional;
6 |
7 | public class Day026 {
8 |
9 | public static void main(String[] args) {
10 | // Instead of doing:
11 | String nullableValue = getNullableValue();
12 | if (nullableValue != null) {
13 | System.out.println(nullableValue.length());
14 | } else {
15 | System.out.println(0);
16 | }
17 |
18 | // Just do:
19 | System.out.println(getOptionalValue().map(String::length).orElse(0));
20 | }
21 |
22 | @Nonnull
23 | private static Optional getOptionalValue() {
24 | return Optional.empty();
25 | }
26 |
27 | @Nullable
28 | private static String getNullableValue() {
29 | return null;
30 | }
31 | }
--------------------------------------------------------------------------------
/days/day027/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day027
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day027/src/main/java/com/thegreatapi/ahundreddaysofjava/day027/Day027.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day027;
2 |
3 | import java.util.List;
4 |
5 | import static java.util.stream.Collectors.joining;
6 |
7 | public final class Day027 {
8 |
9 | public static void main(String[] args) {
10 | List players = createList();
11 |
12 | String message = players.stream()
13 | .map(Player::toString)
14 | .collect(joining(System.lineSeparator()));
15 |
16 | System.out.println(message);
17 | }
18 |
19 | private static List createList() {
20 | var messi = new Player("Lionel Messi", "PSG", "Argentina", 42);
21 | var cr7 = new Player("Cristiano Ronaldo", "Manchester United", "Portugal", 50);
22 | var lukaku = new Player("Romelu Lukaku", "Chelsea", "Belgium", 41);
23 |
24 | return List.of(messi, cr7, lukaku);
25 | }
26 |
27 | private record Player(String name, String club, String coutry, int numberOfGoals) {
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/days/day028/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day028
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day028/src/main/java/com/thegreatapi/ahundreddaysofjava/day028/Day028.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day028;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | import static java.util.Comparator.comparing;
7 |
8 | public final class Day028 {
9 |
10 | public static void main(String[] args) {
11 | var messi = new Player("Lionel Messi", "PSG", "Argentina", 42);
12 | var cr7 = new Player("Cristiano Ronaldo", "Manchester United", "Portugal", 50);
13 | var lukaku = new Player("Romelu Lukaku", "Chelsea", "Belgium", 41);
14 |
15 | List players = Arrays.asList(messi, cr7, lukaku);
16 |
17 | players.sort(comparing(Player::numberOfGoals).reversed());
18 |
19 | System.out.println("Top Scorers:");
20 | players.forEach(System.out::println);
21 | }
22 |
23 | private record Player(String name, String club, String country, int numberOfGoals) {
24 | }
25 | }
--------------------------------------------------------------------------------
/days/day029/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day029
13 |
14 |
15 |
16 | org.junit.jupiter
17 | junit-jupiter-api
18 | test
19 |
20 |
21 | org.awaitility
22 | awaitility
23 | test
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/days/day029/src/main/java/com/thegreatapi/ahundreddaysofjava/day029/Day029.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day029;
2 |
3 | import java.util.Collections;
4 | import java.util.Map;
5 | import java.util.concurrent.ConcurrentHashMap;
6 | import java.util.stream.IntStream;
7 |
8 | public class Day029 {
9 |
10 | private final Map primes = new ConcurrentHashMap<>();
11 |
12 | public void startComputingPrimes() {
13 | var count = 0;
14 | for (var i = 2; i <= Integer.MAX_VALUE; i++) {
15 | if (isPrime(i)) {
16 | primes.put(++count, i);
17 | }
18 | }
19 | }
20 |
21 | private static boolean isPrime(int number) {
22 | return IntStream.rangeClosed(2, (int) Math.sqrt(number))
23 | .allMatch(n -> number % n != 0);
24 | }
25 |
26 | public Map getAlreadyComputedPrimes() {
27 | return Collections.unmodifiableMap(primes);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/days/day029/src/test/java/com/thegreatapi/ahundreddaysofjava/day029/Day029Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day029;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.util.concurrent.CompletableFuture;
6 |
7 | import static org.awaitility.Awaitility.await;
8 | import static org.junit.jupiter.api.Assertions.assertEquals;
9 |
10 | class Day029Test {
11 |
12 | @Test
13 | void test() {
14 | Day029 day029 = new Day029();
15 |
16 | CompletableFuture.runAsync(day029::startComputingPrimes);
17 |
18 | // Await until the already computed primes contain the key 100_000
19 | await().until(() -> day029.getAlreadyComputedPrimes().containsKey(100_000));
20 |
21 | assertEquals(1299709, day029.getAlreadyComputedPrimes().get(100_000));
22 | }
23 | }
--------------------------------------------------------------------------------
/days/day030/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day030
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day030/src/main/java/com/thegreatapi/ahundreddaysofjava/day030/Day030.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day030;
2 |
3 | public class Day030 {
4 |
5 | public static void main(String[] args) {
6 |
7 | // Requires JDK 15 or JDK 13 with Preview Features enabled
8 |
9 | var myString = """
10 | This is a
11 | text block of
12 | multiple lines.
13 | """;
14 |
15 | System.out.println(myString);
16 |
17 | var myIndentedString = """
18 | And this is
19 | a text block with
20 | indentation:
21 | public String getMessage() {
22 | if (LocalTime.now().isAfter(LocalTime.of(12, 0))) {
23 | return "Good afternoon";
24 | } else {
25 | return "Good morning";
26 | }
27 | }
28 | """;
29 |
30 | System.out.println(myIndentedString);
31 | }
32 | }
--------------------------------------------------------------------------------
/days/day031/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day031
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day031/src/main/java/com/thegreatapi/ahundreddaysofjava/day031/Day031.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day031;
2 |
3 | import java.util.List;
4 | import java.util.stream.Collectors;
5 | import java.util.stream.Stream;
6 |
7 | public class Day031 {
8 |
9 | public static void main(String[] args) {
10 | // Instead of doing:
11 | List list = Stream.of("the", "great", "api", ".com")
12 | .collect(Collectors.toList());
13 |
14 | // Just do:
15 | List listJdk16 = Stream.of("the", "great", "api", ".com")
16 | .toList();
17 | }
18 | }
--------------------------------------------------------------------------------
/days/day032/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day032
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day032/src/main/java/com/thegreatapi/ahundreddaysofjava/day032/Day032.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day032;
2 |
3 | import java.security.SecureRandom;
4 |
5 | public class Day032 {
6 |
7 | public static void main(String[] args) {
8 | String result = map(randomNumber());
9 | System.out.println(result);
10 | }
11 |
12 | private static String map(int number) {
13 | // Requires JDK 12
14 | return switch (number) {
15 | case 1 -> "one";
16 | case 2 -> "two";
17 | case 3 -> "three";
18 | default -> "unknown";
19 | };
20 | }
21 |
22 | private static int randomNumber() {
23 | return new SecureRandom().nextInt(4);
24 | }
25 | }
--------------------------------------------------------------------------------
/days/day033/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day033
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day033/src/main/java/com/thegreatapi/ahundreddaysofjava/day033/Day033.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day033;
2 |
3 | import java.time.LocalTime;
4 | import java.util.Optional;
5 |
6 | public class Day033 {
7 |
8 | public static void main(String[] args) {
9 | Optional optionalValue = getOptionalValue();
10 |
11 | // Stop using Optional#get.
12 | // It will be deprecated soon, as you can see in https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8160606
13 | System.out.println(optionalValue.get());
14 |
15 | // Start using Optional#orElseThrow instead of Optional#get
16 | System.out.println(getOptionalValue().orElseThrow());
17 | }
18 |
19 | private static Optional getOptionalValue() {
20 | return Optional.of(LocalTime.now());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/days/day034/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day034
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day034/src/main/java/com/thegreatapi/ahundreddaysofjava/day034/Day034.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day034;
2 |
3 | import java.io.File;
4 |
5 | public class Day034 {
6 |
7 | public static final String JAVA_SUFFIX = File.separator + "java";
8 |
9 | public static void main(String[] args) {
10 | ProcessHandle.allProcesses()
11 | .filter(Day034::isJavaProcess)
12 | .map(ProcessHandle::info)
13 | .forEach(System.out::println);
14 | }
15 |
16 | private static boolean isJavaProcess(ProcessHandle processHandle) {
17 | return processHandle.info()
18 | .command()
19 | .map(command -> command.endsWith(JAVA_SUFFIX))
20 | .orElse(false);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/days/day035/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day035
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day035/src/main/java/com/thegreatapi/ahundreddaysofjava/day035/Day035.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day035;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.FileReader;
5 | import java.io.IOException;
6 |
7 | public class Day035 {
8 |
9 | public static void main(String[] args) throws IOException {
10 | String path = args[0];
11 |
12 | // Instead of doing:
13 | var bufferedReader = new BufferedReader(new FileReader(path));
14 | try {
15 | String line = bufferedReader.readLine();
16 | System.out.println(line);
17 | } finally {
18 | bufferedReader.close();
19 | }
20 |
21 | // Just do:
22 | try (var autoClosedBufferedReader = new BufferedReader(new FileReader(path))) {
23 | String line = autoClosedBufferedReader.readLine();
24 | System.out.println(line);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/days/day036/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day036
13 |
14 |
15 |
16 | com.google.code.findbugs
17 | jsr305
18 |
19 |
20 |
--------------------------------------------------------------------------------
/days/day036/src/main/java/com/thegreatapi/ahundreddaysofjava/day036/Day036.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day036;
2 |
3 | import javax.annotation.Nonnull;
4 |
5 | public final class Day036 {
6 |
7 | private Day036() {
8 | }
9 |
10 | public static void main(String[] args) {
11 | printLenght(null);
12 | }
13 |
14 | public static void printLenght(@Nonnull String s) {
15 | System.out.println(s.length());
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day037/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day037
13 |
14 |
15 |
16 | com.google.code.findbugs
17 | jsr305
18 |
19 |
20 |
--------------------------------------------------------------------------------
/days/day037/src/main/java/com/thegreatapi/ahundreddaysofjava/day037/Day037.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day037;
2 |
3 | import javax.annotation.Nullable;
4 | import java.util.Objects;
5 |
6 | public class Day037 {
7 |
8 | public static void main(String[] args) {
9 | String s = Objects.requireNonNullElse(doStuff(), "not found");
10 |
11 | // Will print 'not found'
12 | System.out.println(s);
13 | }
14 |
15 | @Nullable
16 | private static String doStuff() {
17 | return null;
18 | }
19 | }
--------------------------------------------------------------------------------
/days/day038/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day038
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day038/src/main/java/com/thegreatapi/ahundreddaysofjava/day038/Day038.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day038;
2 |
3 | import java.util.concurrent.CompletableFuture;
4 | import java.util.concurrent.ExecutionException;
5 |
6 | import static java.util.concurrent.TimeUnit.SECONDS;
7 |
8 | public class Day038 {
9 |
10 | public static void main(String[] args) throws InterruptedException, ExecutionException {
11 | String webSite = CompletableFuture.supplyAsync(Day038::getWebSite)
12 | .completeOnTimeout("https://twitter.com/helber_belmiro", 5, SECONDS)
13 | .get();
14 |
15 | System.out.println(webSite);
16 | }
17 |
18 | private static String getWebSite() {
19 | try {
20 | Thread.sleep(10_000);
21 | return "thegreatapi.com";
22 | } catch (InterruptedException e) {
23 | Thread.currentThread().interrupt();
24 | throw new RuntimeException(e);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/days/day038/src/main/java/com/thegreatapi/ahundreddaysofjava/day038/Operators.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day038;
2 |
3 | public class Operators {
4 |
5 | // i++ you read: use and then increment
6 | // ++i you read: increment and then use
7 |
8 | static int result;
9 | static int i;
10 |
11 | public static void main(String[] args) {
12 | System.out.println("Use and increment.");
13 | useAndIncrement();
14 |
15 | System.out.println("Increment and use.");
16 | incrementAndUse();
17 | }
18 |
19 | static void useAndIncrement() {
20 | resetVariables();
21 |
22 | // Use and then increment.
23 | result = i++;
24 |
25 | System.out.println(result); // Prints: 0
26 | System.out.println(i); // Prints: 1
27 |
28 | resetVariables();
29 |
30 | // This is the same as:
31 |
32 | // Use
33 | result = i;
34 |
35 | // And then increment
36 | i = i + 1;
37 |
38 | System.out.println(result); // Prints: 0
39 | System.out.println(i); // Prints: 1
40 | }
41 |
42 | private static void incrementAndUse() {
43 | resetVariables();
44 |
45 | // Increment and then use.
46 | result = ++i;
47 |
48 | System.out.println(result); // Prints: 1
49 | System.out.println(i); // Prints: 1
50 |
51 | resetVariables();
52 |
53 | // This is the same as:
54 |
55 | // Increment
56 | i = i + 1;
57 |
58 | // And then use
59 | result = i;
60 |
61 | System.out.println(result); // Prints: 1
62 | System.out.println(i); // Prints: 1
63 | }
64 |
65 | static void resetVariables() {
66 | result = 0;
67 | i = 0;
68 | }
69 | }
--------------------------------------------------------------------------------
/days/day039/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day039
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day039/src/main/java/com/thegreatapi/ahundreddaysofjava/day039/Day039.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day039;
2 |
3 | public class Day039 {
4 |
5 | public static void main(String[] args) {
6 | int i = 4;
7 | int j = 21;
8 |
9 | int k = ++i * 7 + 2 - j--;
10 |
11 | System.out.println(i);
12 | System.out.println(j);
13 | System.out.println(k);
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day040/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day040
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day040/src/main/java/com/thegreatapi/ahundreddaysofjava/day040/Day040.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day040;
2 |
3 | import java.util.function.Predicate;
4 | import java.util.stream.Stream;
5 |
6 | import static java.util.function.Predicate.not;
7 |
8 | public class Day040 {
9 |
10 | public static void main(String[] args) {
11 | // Instead of doing:
12 | printAllThat(word -> !word.isEmpty());
13 |
14 | // Just do:
15 | printAllThat(not(String::isEmpty));
16 | }
17 |
18 | private static void printAllThat(Predicate filter) {
19 | Stream.of("avocado", "chair", "", "dog", "car")
20 | .filter(filter)
21 | .forEach(System.out::println);
22 | }
23 | }
--------------------------------------------------------------------------------
/days/day041/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day041
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day041/src/main/java/com/thegreatapi/ahundreddaysofjava/day041/Day041.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day041;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | public class Day041 {
8 |
9 | public static void main(String[] args) {
10 | List originalList = new ArrayList<>();
11 | originalList.add("one");
12 | originalList.add("two");
13 | originalList.add("three");
14 |
15 | List copy = Collections.unmodifiableList(originalList);
16 |
17 | originalList.remove("two");
18 |
19 | System.out.println(String.join(" ", copy));
20 | }
21 | }
--------------------------------------------------------------------------------
/days/day043/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day043
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day043/src/main/java/com/thegreatapi/ahundreddaysofjava/day043/Day043.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day043;
2 |
3 | public class Day043 {
4 |
5 | public static void main(String[] args) {
6 | var methodCode = """
7 | private static void task() {
8 | LOGGER.info("Async task starting. This message is logged by the async task thread");
9 | try {
10 | Thread.sleep(1000);
11 | LOGGER.info("Async task is ending. This message is logged by the async task thread");
12 | } catch (InterruptedException e) {
13 | Thread.currentThread().interrupt();
14 | LOGGER.log(Level.SEVERE, "The async task thread was interrupted.", e);
15 | }
16 | }
17 | """;
18 |
19 | var classCode = """
20 | public class MyClass {
21 | %s
22 | }
23 | """;
24 |
25 | // Requires JDK 12
26 | String fullCode = classCode.formatted(methodCode.indent(4));
27 |
28 | System.out.println(fullCode);
29 | }
30 | }
--------------------------------------------------------------------------------
/days/day044/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day044
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day044/src/main/java/com/thegreatapi/ahundreddaysofjava/day044/Day044.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day044;
2 |
3 | public class Day044 {
4 |
5 | public static final String NAME = "Helber Belmiro";
6 |
7 | public static void main(String[] args) {
8 | String formattedString;
9 |
10 | // Instead of doing:
11 | formattedString = String.format("My name is %s", NAME);
12 |
13 | // Just do: (Requires JDK 15)
14 | formattedString = "My name is %s".formatted(NAME);
15 |
16 | System.out.println(formattedString);
17 | }
18 | }
--------------------------------------------------------------------------------
/days/day045/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day045
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day045/src/main/java/com/thegreatapi/ahundreddaysofjava/day045/Day045.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day045;
2 |
3 | import java.time.LocalDate;
4 | import java.util.Arrays;
5 | import java.util.Comparator;
6 | import java.util.List;
7 |
8 | public class Day045 {
9 |
10 | public static void main(String[] args) {
11 | List queen = getMusicians();
12 |
13 | // Instead of doing:
14 | queen.sort(new Comparator() {
15 | @Override
16 | public int compare(Musician m1, Musician m2) {
17 | return m1.dateOfBirth.compareTo(m2.dateOfBirth);
18 | }
19 | });
20 |
21 | System.out.println(queen);
22 |
23 | // Just do:
24 | queen.sort(Comparator.comparing(Musician::dateOfBirth));
25 |
26 | System.out.println(queen);
27 | }
28 |
29 | private static List getMusicians() {
30 | Musician roger = new Musician("Roger Taylor", LocalDate.of(1949, 7, 26));
31 | Musician john = new Musician("John Deacon", LocalDate.of(1951, 8, 19));
32 | Musician brian = new Musician("Brian May", LocalDate.of(1947, 7, 19));
33 | Musician freddie = new Musician("Freddie Mercury", LocalDate.of(1946, 9, 5));
34 |
35 | return Arrays.asList(roger, john, brian, freddie);
36 | }
37 |
38 | record Musician(String name, LocalDate dateOfBirth) {
39 | }
40 | }
--------------------------------------------------------------------------------
/days/day046/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day046
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day046/src/main/java/com/thegreatapi/ahundreddaysofjava/day046/Day046.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day046;
2 |
3 | import java.time.LocalDate;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 | import java.util.List;
7 | import java.util.stream.Collectors;
8 |
9 | public class Day046 {
10 |
11 | public static void main(String[] args) {
12 | List queen = getMusicians();
13 | List years;
14 |
15 | // Instead of doing:
16 | years = new ArrayList<>();
17 | for (Musician musician : queen) {
18 | years.add(musician.dateOfBirth.getYear());
19 | }
20 |
21 | System.out.println(years);
22 |
23 | // Just do:
24 | years = queen.stream()
25 | .map(musician -> musician.dateOfBirth.getYear())
26 | .collect(Collectors.toList());
27 |
28 | System.out.println(years);
29 | }
30 |
31 | private static List getMusicians() {
32 | Musician roger = new Musician("Roger Taylor", LocalDate.of(1949, 7, 26));
33 | Musician john = new Musician("John Deacon", LocalDate.of(1951, 8, 19));
34 | Musician brian = new Musician("Brian May", LocalDate.of(1947, 7, 19));
35 | Musician freddie = new Musician("Freddie Mercury", LocalDate.of(1946, 9, 5));
36 |
37 | return Arrays.asList(roger, john, brian, freddie);
38 | }
39 |
40 | record Musician(String name, LocalDate dateOfBirth) {
41 | }
42 | }
--------------------------------------------------------------------------------
/days/day047/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day047
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day047/src/main/java/com/thegreatapi/ahundreddaysofjava/day047/Day047.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day047;
2 |
3 | public class Day047 {
4 |
5 | @FunctionalInterface
6 | interface Converter {
7 | // Because of the @FunctionalInterface annotation, only one method is allowed in this interface
8 |
9 | String convert(Integer number);
10 | }
11 |
12 | public static void main(String[] args) {
13 | for (var i = 1; i <= 4; i++) {
14 | System.out.println(i + " in english: " + englishConverter().convert(i));
15 | System.out.println(i + " in portuguese: " + portugueseConverter().convert(i));
16 | System.out.println(i + " in german: " + germanConverter().convert(i));
17 | }
18 | }
19 |
20 | private static Converter germanConverter() {
21 | return number -> {
22 | switch (number) {
23 | case 1:
24 | return "eins";
25 | case 2:
26 | return "zwei";
27 | case 3:
28 | return "drei";
29 | case 4:
30 | return "vier";
31 | default:
32 | throw new UnsupportedOperationException();
33 | }
34 | };
35 | }
36 |
37 | private static Converter portugueseConverter() {
38 | return number -> {
39 | switch (number) {
40 | case 1:
41 | return "um";
42 | case 2:
43 | return "dois";
44 | case 3:
45 | return "três";
46 | case 4:
47 | return "quatro";
48 | default:
49 | throw new UnsupportedOperationException();
50 | }
51 | };
52 | }
53 |
54 | private static Converter englishConverter() {
55 | return number -> {
56 | switch (number) {
57 | case 1:
58 | return "one";
59 | case 2:
60 | return "two";
61 | case 3:
62 | return "three";
63 | case 4:
64 | return "four";
65 | default:
66 | throw new UnsupportedOperationException();
67 | }
68 | };
69 | }
70 | }
--------------------------------------------------------------------------------
/days/day048/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day048
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day049/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day049
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day049/src/main/java/com/thegreatapi/ahundreddaysofjava/day049/Day049.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day049;
2 |
3 | import java.util.Map;
4 | import java.util.function.Function;
5 | import java.util.stream.Collectors;
6 |
7 | public class Day049 {
8 |
9 | public static void main(String[] args) {
10 | Map portugueseNumbers = translateToPortuguese(englishNumbers());
11 | System.out.println(portugueseNumbers);
12 | }
13 |
14 | private static Map translateToPortuguese(Map numbers) {
15 | /*
16 | Instead of doing:
17 | Function keyMapper = number -> number;
18 | */
19 |
20 | // Just do:
21 | Function keyMapper = Function.identity();
22 |
23 | Function valueMapper = number -> switch (number) {
24 | case 1 -> "um";
25 | case 2 -> "dois";
26 | case 3 -> "três";
27 | case 4 -> "quatro";
28 | default -> throw new UnsupportedOperationException("Cannot translate %d".formatted(number));
29 | };
30 |
31 | return numbers.keySet()
32 | .stream()
33 | .collect(Collectors.toMap(keyMapper, valueMapper));
34 | }
35 |
36 | private static Map englishNumbers() {
37 | return Map.of(
38 | 1, "one",
39 | 2, "two",
40 | 3, "three",
41 | 4, "four"
42 | );
43 | }
44 | }
--------------------------------------------------------------------------------
/days/day050/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day050
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day050/src/main/java/com/thegreatapi/ahundreddaysofjava/day050/Day050.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day050;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.stream.IntStream;
6 |
7 | public class Day050 {
8 |
9 | public static void main(String[] args) {
10 | System.out.println(createPool(10));
11 | System.out.println(enhancedCreatePool(10));
12 | }
13 |
14 | // Instead of:
15 | private static List createPool(int poolSize) {
16 | List pool = new ArrayList<>(poolSize);
17 | for (var i = 0; i < poolSize; i++) {
18 | pool.add(new PooledObject(String.valueOf(i)));
19 | }
20 | return pool;
21 | }
22 |
23 | // Just do:
24 | private static List enhancedCreatePool(int poolSize) {
25 | return IntStream.range(0, poolSize)
26 | .mapToObj(i -> new PooledObject(String.valueOf(i)))
27 | .toList();
28 | }
29 |
30 | private record PooledObject(String id) {
31 | }
32 | }
--------------------------------------------------------------------------------
/days/day051/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day051
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day051/src/main/java/com/thegreatapi/ahundreddaysofjava/day051/Day051.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day051;
2 |
3 | import java.util.function.UnaryOperator;
4 |
5 | public class Day051 {
6 |
7 | public static void main(String[] args) {
8 | // Instead of doing:
9 | // Function multiplyBy2 = i -> i * 2;
10 |
11 | // Just do:
12 | UnaryOperator multiplyBy2 = i -> i * 2;
13 |
14 | System.out.println(multiplyBy2.apply(3));
15 | }
16 | }
--------------------------------------------------------------------------------
/days/day052/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day052
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day052/src/main/java/com/thegreatapi/ahundreddaysofjava/day052/Day052.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day052;
2 |
3 | import java.io.IOException;
4 | import java.io.UncheckedIOException;
5 | import java.nio.file.Files;
6 | import java.nio.file.Path;
7 |
8 | public class Day052 {
9 |
10 | public static void main(String[] args) {
11 | System.out.println(readFile());
12 | }
13 |
14 | public static String readFile() {
15 | try {
16 | return Files.readString(Path.of("/test.txt"));
17 | } catch (IOException e) {
18 | throw new UncheckedIOException(e);
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/days/day053/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day053
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day053/src/main/java/com/thegreatapi/ahundreddaysofjava/day053/Day053.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day053;
2 |
3 | import java.util.logging.Logger;
4 |
5 | public class Day053 {
6 |
7 | private static final Logger LOGGER = Logger.getLogger(Day053.class.getName());
8 |
9 | public static void main(String[] args) {
10 | // Instead of always running the expensive method
11 | // LOGGER.info(veryExpensiveStringCreation());
12 |
13 | // Pass the method reference so that it is called only when and if necessary
14 | LOGGER.info(Day053::veryExpensiveStringCreation);
15 | }
16 |
17 | private static String veryExpensiveStringCreation() {
18 | try {
19 | Thread.sleep(10_000);
20 | } catch (InterruptedException e) {
21 | //TODO: handle properly
22 | }
23 | return "thegreatapi.com";
24 | }
25 | }
--------------------------------------------------------------------------------
/days/day054/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day054
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day054/src/main/java/com/thegreatapi/ahundreddaysofjava/day054/Day054.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day054;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class Day054 {
7 |
8 | public static void main(String[] args) {
9 | Map map = new HashMap<>();
10 | map.put(1, "one");
11 | map.put(2, "two");
12 |
13 | // Instead of doing:
14 | // String three = map.get(3);
15 | // if (three == null) {
16 | // three = "three";
17 | // map.put(3, three);
18 | // }
19 |
20 | // Just do:
21 | String three = map.computeIfAbsent(3, k -> "three");
22 |
23 | System.out.println(three);
24 | System.out.println(map);
25 | }
26 | }
--------------------------------------------------------------------------------
/days/day055/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day055
13 |
14 |
15 |
16 | org.junit.jupiter
17 | junit-jupiter-api
18 | test
19 |
20 |
21 | org.assertj
22 | assertj-core
23 | test
24 |
25 |
26 |
--------------------------------------------------------------------------------
/days/day055/src/main/java/com/thegreatapi/ahundreddaysofjava/day055/Day055.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day055;
2 |
3 | public record Day055(String fieldA, Integer fieldB) {
4 | }
--------------------------------------------------------------------------------
/days/day055/src/test/java/com/thegreatapi/ahundreddaysofjava/day055/Day055Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day055;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.assertj.core.api.Assertions.assertThat;
6 | import static org.junit.jupiter.api.Assertions.assertEquals;
7 |
8 | class Day055Test {
9 |
10 | @Test
11 | void testEquals() {
12 | Day055 obj1 = new Day055("thegreatapi.com", 42);
13 | Day055 obj2 = new Day055("thegreatapi.com", 42);
14 |
15 | // Intead of using JUnit assertions, like this:
16 | assertEquals(obj1.hashCode(), obj2.hashCode());
17 |
18 | // Use AssertJ, like this:
19 | assertThat(obj1).hasSameHashCodeAs(obj2);
20 | }
21 | }
--------------------------------------------------------------------------------
/days/day056/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day056
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day056/src/main/java/com/thegreatapi/ahundreddaysofjava/day056/Day056.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day056;
2 |
3 | public final class Day056 {
4 |
5 | private static final String RESET_COLOR = "\u001B[0m";
6 |
7 | public static void main(String[] args) {
8 | var color = Color.valueOf(args[0]);
9 | System.out.println(color.getAnsiColor() + "thegreatapi.com" + RESET_COLOR);
10 | }
11 |
12 | @SuppressWarnings("unused")
13 | public enum Color {
14 | BLACK("\u001B[30m"),
15 | BLUE("\u001B[34m"),
16 | RED("\u001B[31m"),
17 | YELLOW("\u001B[33m"),
18 | WHITE("\u001B[37m");
19 |
20 | private final String ansiColor;
21 |
22 | Color(String ansiColor) {
23 | this.ansiColor = ansiColor;
24 | }
25 |
26 | public final String getAnsiColor() {
27 | return ansiColor;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/days/day057/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day057
13 |
14 |
15 |
16 | info.picocli
17 | picocli
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/days/day057/src/main/java/com/thegreatapi/ahundreddaysofjava/day057/Day057.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day057;
2 |
3 | import picocli.CommandLine;
4 |
5 | import java.nio.file.Files;
6 | import java.nio.file.Path;
7 | import java.util.concurrent.Callable;
8 |
9 | @CommandLine.Command(
10 | mixinStandardHelpOptions = true,
11 | description = "Prints the contents of the specified file in the specified color")
12 | public class Day057 implements Callable {
13 |
14 | private static final String RESET_COLOR = "\u001B[0m";
15 |
16 | @CommandLine.Option(names = {"-c", "--collor"}, description = "BLACK, BLUE, RED, YELLOW or WHITE")
17 | private Color color;
18 |
19 | @CommandLine.Parameters(index = "0", description = "The file whose checksum to calculate.")
20 | private Path path;
21 |
22 | @Override
23 | public Integer call() throws Exception {
24 | print(Files.readString(path));
25 | return 0;
26 | }
27 |
28 | private void print(String text) {
29 | System.out.println(color.getAnsiColor() + text + RESET_COLOR);
30 | }
31 |
32 | public static void main(String... args) {
33 | int exitCode = new CommandLine(new Day057()).execute(args);
34 | System.exit(exitCode);
35 | }
36 |
37 | @SuppressWarnings("unused")
38 | enum Color {
39 | BLACK("\u001B[30m"),
40 | BLUE("\u001B[34m"),
41 | RED("\u001B[31m"),
42 | YELLOW("\u001B[33m"),
43 | WHITE("\u001B[37m");
44 |
45 | private final String ansiColor;
46 |
47 | Color(String ansiColor) {
48 | this.ansiColor = ansiColor;
49 | }
50 |
51 | public final String getAnsiColor() {
52 | return ansiColor;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/days/day058/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day058
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day058/src/main/java/com/thegreatapi/ahundreddaysofjava/day058/Day058.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day058;
2 |
3 | import java.util.List;
4 |
5 | public class Day058 {
6 |
7 | static class Bad {
8 |
9 | /**
10 | * Never write code that depends on {@link Object#toString()} format.
11 | * The format can change in the future and break your code.
12 | * In this particular case, we don't even know the {@link List} implementation that we're receiving,
13 | * and we don't have any guarantee that the return of {@link List#toString()} would be in the expected format.
14 | */
15 | public String convertToString(List list) {
16 | return list.toString().replace("[", "").replace("]", "");
17 | }
18 | }
19 |
20 | static class Good {
21 |
22 | public String convertToString(List list) {
23 | return String.join(", ", list);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/days/day059/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day059
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day059/src/main/java/com/thegreatapi/ahundreddaysofjava/day059/Day059.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day059;
2 |
3 | import java.util.List;
4 | import java.util.function.Predicate;
5 | import java.util.stream.Collectors;
6 | import java.util.stream.IntStream;
7 |
8 | public class Day059 {
9 |
10 | public static void main(String[] args) {
11 | /*
12 | A Predicate is the same as Function.
13 | It consumes a T and returns a Boolean.
14 | */
15 | Predicate isEven = intValue -> intValue % 2 == 0;
16 |
17 | List numbers = getNumbers();
18 | numbers.stream()
19 | .filter(isEven)
20 | .forEach(System.out::println);
21 | }
22 |
23 | private static List getNumbers() {
24 | return IntStream.rangeClosed(1, 100).boxed().collect(Collectors.toList());
25 | }
26 | }
--------------------------------------------------------------------------------
/days/day060/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day060
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day060/src/main/java/com/thegreatapi/ahundreddaysofjava/day060/Day060.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day060;
2 |
3 | import java.util.List;
4 | import java.util.function.Predicate;
5 | import java.util.stream.Collectors;
6 | import java.util.stream.IntStream;
7 |
8 | import static java.util.function.Predicate.not;
9 |
10 | public class Day060 {
11 |
12 | public static void main(String[] args) {
13 | Predicate isEven = intValue -> intValue % 2 == 0;
14 | Predicate isPositive = intValue -> intValue > 0;
15 |
16 | List numbers = getNumbers();
17 |
18 | // Prints negative odd numbers and positive even numbers.
19 | numbers.stream()
20 | .filter(isEven.and(isPositive).or(not(isEven).and(not(isPositive))))
21 | .forEach(System.out::println);
22 | }
23 |
24 | private static List getNumbers() {
25 | return IntStream.rangeClosed(-20, 20).boxed().collect(Collectors.toList());
26 | }
27 | }
--------------------------------------------------------------------------------
/days/day062/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day062
13 |
14 |
15 |
16 | jakarta.json.bind
17 | jakarta.json.bind-api
18 |
19 |
20 |
21 | org.eclipse
22 | yasson
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/days/day062/src/main/java/com/thegreatapi/ahundreddaysofjava/day062/Day062.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day062;
2 |
3 | import jakarta.json.bind.Jsonb;
4 | import jakarta.json.bind.JsonbBuilder;
5 |
6 | import java.util.List;
7 |
8 | public class Day062 {
9 |
10 | public static void main(String[] args) throws Exception {
11 | Musician steveHarris = new Musician("Steve Harris", "Bass", "England", "Iron Maiden");
12 | Musician michaelSchenker = new Musician("Michael Schenker", "Guitar", "Germany", "UFO");
13 | Musician daveLombardo = new Musician("Dave Lombardo", "Drums", "Cuba", "Slayer");
14 |
15 | List musicians = List.of(steveHarris, michaelSchenker, daveLombardo);
16 |
17 | try (Jsonb jsonb = JsonbBuilder.create()) {
18 | String json = jsonb.toJson(musicians);
19 | System.out.println(json);
20 |
21 | String jsonJohnLord = "{\"bandName\":\"Deep Purple\",\"country\":\"England\",\"instrument\":\"Keyboards\",\"name\":\"John Lord\"}";
22 |
23 | Musician johnLord = jsonb.fromJson(jsonJohnLord, Musician.class);
24 |
25 | System.out.println(johnLord);
26 | }
27 | }
28 |
29 | public static class Musician {
30 | private String name;
31 | private String instrument;
32 | private String country;
33 | private String bandName;
34 |
35 | public Musician() {
36 | }
37 |
38 | public Musician(String name, String instrument, String country, String bandName) {
39 | this.name = name;
40 | this.instrument = instrument;
41 | this.country = country;
42 | this.bandName = bandName;
43 | }
44 |
45 | @SuppressWarnings("unused")
46 | public String getName() {
47 | return name;
48 | }
49 |
50 | @SuppressWarnings("unused")
51 | public String getInstrument() {
52 | return instrument;
53 | }
54 |
55 | @SuppressWarnings("unused")
56 | public String getCountry() {
57 | return country;
58 | }
59 |
60 | @SuppressWarnings("unused")
61 | public String getBandName() {
62 | return bandName;
63 | }
64 |
65 | public void setName(String name) {
66 | this.name = name;
67 | }
68 |
69 | public void setInstrument(String instrument) {
70 | this.instrument = instrument;
71 | }
72 |
73 | public void setCountry(String country) {
74 | this.country = country;
75 | }
76 |
77 | public void setBandName(String bandName) {
78 | this.bandName = bandName;
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | return "Musician{" +
84 | "name='" + name + '\'' +
85 | ", instrument='" + instrument + '\'' +
86 | ", country='" + country + '\'' +
87 | ", bandName='" + bandName + '\'' +
88 | '}';
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/days/day063/src/main/java/com/thegreatapi/ahundreddaysofjava/Day063.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava;
2 |
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.Produces;
6 | import jakarta.ws.rs.core.MediaType;
7 | import org.eclipse.microprofile.faulttolerance.Fallback;
8 |
9 | import java.time.Instant;
10 |
11 | @Path("/hello")
12 | public class Day063 {
13 |
14 | @GET
15 | @Fallback(fallbackMethod = "fallbackHello")
16 | @Produces(MediaType.TEXT_PLAIN)
17 | public String hello() {
18 | if (Instant.now().toEpochMilli() % 2 == 0) {
19 | return "Hello from the main method";
20 | } else {
21 | throw new RuntimeException();
22 | }
23 | }
24 |
25 | public String fallbackHello() {
26 | return "Hello from the fallback method";
27 | }
28 | }
--------------------------------------------------------------------------------
/days/day064/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day064
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day064/src/main/java/com/thegreatapi/ahundreddaysofjava/day064/Day064.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day064;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.function.Predicate;
6 |
7 | import static java.util.stream.Collectors.partitioningBy;
8 |
9 | public class Day064 {
10 |
11 | public static void main(String[] args) {
12 | Predicate isEuropeanBand = band -> List.of(Europe.values()).contains(band.country);
13 |
14 | Map> europeanBandsAndOthers = getBands().stream()
15 | .collect(partitioningBy(isEuropeanBand));
16 |
17 | List europeanBands = europeanBandsAndOthers.get(true);
18 | List otherBands = europeanBandsAndOthers.get(false);
19 |
20 | System.out.println("Bands from Europe: " + europeanBands);
21 | System.out.println("Other bands: " + otherBands);
22 | }
23 |
24 | private static List getBands() {
25 | return List.of(
26 | new Band("Sepultura", America.BRAZIL),
27 | new Band("Gojira", Europe.FRANCE),
28 | new Band("Rush", America.CANADA),
29 | new Band("AC/DC", Oceania.NEW_ZEALAND),
30 | new Band("Iron Maiden", Europe.ENGLAND),
31 | new Band("Scorpions", Europe.GERMANY),
32 | new Band("Kiss", America.USA),
33 | new Band("Mastodon", America.USA)
34 | );
35 | }
36 |
37 | static record Band(String name, Country country) {
38 | }
39 |
40 | interface Country {
41 | }
42 |
43 | enum Europe implements Country {
44 | ENGLAND,
45 | GERMANY,
46 | FRANCE
47 | }
48 |
49 | enum America implements Country {
50 | BRAZIL,
51 | ARGENTINA,
52 | USA,
53 | CANADA
54 | }
55 |
56 | enum Oceania implements Country {
57 | AUSTRALIA,
58 | NEW_ZEALAND
59 | }
60 | }
--------------------------------------------------------------------------------
/days/day065/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day065
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day065/src/main/java/com/thegreatapi/ahundreddaysofjava/day065/Day065.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day065;
2 |
3 | import java.util.HashMap;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | public class Day065 {
8 |
9 | public static void main(String[] args) {
10 | // Instead of doing:
11 | Map> map1 = new HashMap>();
12 |
13 | // Just do:
14 | Map> map2 = new HashMap<>();
15 | }
16 | }
--------------------------------------------------------------------------------
/days/day066/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day066
13 |
14 |
--------------------------------------------------------------------------------
/days/day066/src/main/java/com/thegreatapi/ahundreddaysofjava/day066/Day066.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day066;
2 |
3 | import java.time.LocalDate;
4 |
5 | public class Day066 {
6 |
7 | /* Instead of doing:
8 |
9 | @AllArgsConstructor
10 | @ToString
11 | @EqualsAndHashCode
12 | class PersonLombok {
13 | @Getter
14 | private final String name;
15 | @Getter
16 | private final LocalDate dateOfBirth;
17 | @Getter
18 | private final String country;
19 | }
20 |
21 | Just do: (requires JDK 16)
22 | */
23 |
24 | record PersonPureJava(String name, LocalDate dateOfBirth, String country) {
25 | }
26 | }
--------------------------------------------------------------------------------
/days/day067/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day067
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day067/src/main/java/com/thegreatapi/ahundreddaysofjava/day067/Day067.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day067;
2 |
3 | import java.util.EnumMap;
4 | import java.util.Map;
5 |
6 | public class Day067 {
7 |
8 | public static void main(String[] args) {
9 | /*
10 | Use EnumMap when the key of your Map is an enum.
11 | EnumMap is more efficient than HashMap.
12 | */
13 | Map portugueseColors = new EnumMap<>(Color.class);
14 | portugueseColors.put(Color.RED, "Vermelho");
15 | portugueseColors.put(Color.YELLOW, "Amarelo");
16 | portugueseColors.put(Color.BLUE, "Azul");
17 | }
18 |
19 | enum Color {
20 | RED,
21 | YELLOW,
22 | BLUE
23 | }
24 | }
--------------------------------------------------------------------------------
/days/day068/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day068
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day068/src/main/java/com/thegreatapi/ahundreddaysofjava/day068/Day068.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day068;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;
8 |
9 | public class Day068 {
10 |
11 | public static void main(String[] args) {
12 | var interestingClasses = List.of(Integer.class, Number.class, String.class);
13 |
14 | // Instead of doing:
15 | List interestingClassNames = interestingClasses.stream()
16 | .map(Class::getName)
17 | .toList();
18 |
19 | Optional> class1 = Arrays.stream(Thread.currentThread().getStackTrace())
20 | .map(StackTraceElement::getClassName)
21 | .filter(interestingClassNames::contains)
22 | .findFirst()
23 | .map(className -> {
24 | try {
25 | return Class.forName(className);
26 | } catch (ClassNotFoundException e) {
27 | throw new RuntimeException(e);
28 | }
29 | });
30 |
31 | // Just do:
32 | Optional> class2 = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).walk(
33 | stackFrameStream -> stackFrameStream.>map(StackWalker.StackFrame::getDeclaringClass)
34 | .filter(interestingClasses::contains)
35 | .findFirst()
36 | );
37 | }
38 | }
--------------------------------------------------------------------------------
/days/day069/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day069
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day069/src/main/java/com/thegreatapi/ahundreddaysofjava/day069/Day069.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day069;
2 |
3 | import java.security.SecureRandom;
4 | import java.util.stream.Stream;
5 |
6 | public class Day069 {
7 |
8 | private static final SecureRandom SECURE_RANDOM = new SecureRandom();
9 |
10 | public static void main(String[] args) {
11 | Stream.generate(() -> SECURE_RANDOM.nextInt(99) + 1)
12 | .forEach(System.out::println);
13 | }
14 | }
--------------------------------------------------------------------------------
/days/day070/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day070
13 |
14 |
15 | org.junit.jupiter
16 | junit-jupiter-params
17 | test
18 |
19 |
20 | org.assertj
21 | assertj-core
22 | test
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/days/day070/src/main/java/com/thegreatapi/ahundreddaysofjava/day070/Day070.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day070;
2 |
3 | import java.time.LocalDate;
4 | import java.time.Period;
5 | import java.time.temporal.ChronoUnit;
6 |
7 | public class Day070 {
8 |
9 | record Person(String name, LocalDate dateOfBirth) {
10 |
11 | public boolean isYearsHigherThan(int years) {
12 | return Period.between(dateOfBirth, LocalDate.now()).get(ChronoUnit.YEARS) >= years;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day070/src/test/java/com/thegreatapi/ahundreddaysofjava/day070/Day070Test.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day070;
2 |
3 | import org.junit.jupiter.params.ParameterizedTest;
4 | import org.junit.jupiter.params.provider.Arguments;
5 | import org.junit.jupiter.params.provider.MethodSource;
6 |
7 | import java.time.LocalDate;
8 | import java.util.stream.Stream;
9 |
10 | import static com.thegreatapi.ahundreddaysofjava.day070.Day070.Person;
11 | import static org.assertj.core.api.Assertions.assertThat;
12 |
13 | class Day070Test {
14 |
15 | private static Stream isYearsHigherThanSource() {
16 | Person peter = new Person("Peter", LocalDate.of(1950, 1, 1));
17 | Person john = new Person("John", LocalDate.of(2015, 1, 1));
18 | Person mary = new Person("Mary", LocalDate.of(2003, 1, 1));
19 |
20 | return Stream.of(
21 | Arguments.of(peter, 18, true),
22 | Arguments.of(john, 18, false),
23 | Arguments.of(mary, 18, true)
24 | );
25 | }
26 |
27 | @ParameterizedTest
28 | @MethodSource("isYearsHigherThanSource")
29 | void isYearsHigherThan(Person person, int years, boolean expectedResult) {
30 | assertThat(person.isYearsHigherThan(years))
31 | .isEqualTo(expectedResult);
32 | }
33 | }
--------------------------------------------------------------------------------
/days/day071/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day071
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day071/src/main/java/com/thegreatapi/ahundreddaysofjava/day071/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day071;
2 |
3 | import com.thegreatapi.ahundreddaysofjava.day071.calculator.Calculator;
4 | import jakarta.enterprise.context.ApplicationScoped;
5 | import jakarta.inject.Inject;
6 |
7 | @ApplicationScoped
8 | class Application {
9 |
10 | private final Calculator calculator;
11 |
12 | @Inject
13 | private Application(Calculator calculator) {
14 | this.calculator = calculator;
15 | }
16 |
17 | public void run() {
18 | System.out.println(calculator.sum(2, 3));
19 | }
20 | }
--------------------------------------------------------------------------------
/days/day071/src/main/java/com/thegreatapi/ahundreddaysofjava/day071/Day071.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day071;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day071 {
7 |
8 | public static void main(String[] args) {
9 | Weld weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day071/src/main/java/com/thegreatapi/ahundreddaysofjava/day071/calculator/Calculator.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day071.calculator;
2 |
3 | public interface Calculator {
4 |
5 | int sum(int a, int b);
6 | }
7 |
--------------------------------------------------------------------------------
/days/day071/src/main/java/com/thegreatapi/ahundreddaysofjava/day071/calculator/CalculatorImpl.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day071.calculator;
2 |
3 | class CalculatorImpl implements Calculator {
4 |
5 | private CalculatorImpl() {
6 | }
7 |
8 | @Override
9 | public int sum(int a, int b) {
10 | return a + b;
11 | }
12 | }
--------------------------------------------------------------------------------
/days/day071/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day072/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day072
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day072/src/main/java/com/thegreatapi/ahundreddaysofjava/day072/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day072;
2 |
3 | import com.thegreatapi.ahundreddaysofjava.day072.animal.Animal;
4 | import jakarta.enterprise.context.ApplicationScoped;
5 | import jakarta.inject.Inject;
6 | import jakarta.inject.Named;
7 |
8 | @ApplicationScoped
9 | class Application {
10 |
11 | private final Animal dog;
12 | private final Animal cat;
13 |
14 | @Inject
15 | private Application(@Named("Dog") Animal dog, @Named("Cat") Animal cat) {
16 | this.dog = dog;
17 | this.cat = cat;
18 | }
19 |
20 | public void run() {
21 | System.out.println("The dog says: " + dog.speak());
22 | System.out.println("The cat says: " + cat.speak());
23 | }
24 | }
--------------------------------------------------------------------------------
/days/day072/src/main/java/com/thegreatapi/ahundreddaysofjava/day072/Day072.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day072;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day072 {
7 |
8 | public static void main(String[] args) {
9 | Weld weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day072/src/main/java/com/thegreatapi/ahundreddaysofjava/day072/animal/Animal.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day072.animal;
2 |
3 | public interface Animal {
4 |
5 | String speak();
6 | }
7 |
--------------------------------------------------------------------------------
/days/day072/src/main/java/com/thegreatapi/ahundreddaysofjava/day072/animal/Cat.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day072.animal;
2 |
3 | import jakarta.inject.Named;
4 |
5 | @Named("Cat")
6 | class Cat implements Animal {
7 |
8 | private Cat(){
9 | }
10 |
11 | @Override
12 | public String speak() {
13 | return "meow";
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day072/src/main/java/com/thegreatapi/ahundreddaysofjava/day072/animal/Dog.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day072.animal;
2 |
3 | import jakarta.inject.Named;
4 |
5 | @Named("Dog")
6 | class Dog implements Animal {
7 |
8 | private Dog() {
9 | }
10 |
11 | @Override
12 | public String speak() {
13 | return "woof";
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day072/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day073/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day073
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073;
2 |
3 | import com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor.Asynchronous;
4 | import com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor.Payment;
5 | import com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor.PaymentProcessor;
6 | import jakarta.inject.Inject;
7 |
8 | import java.math.BigDecimal;
9 |
10 | class Application {
11 |
12 | private final PaymentProcessor paymentProcessor;
13 |
14 | @Inject
15 | private Application(@Asynchronous PaymentProcessor paymentProcessor) {
16 | this.paymentProcessor = paymentProcessor;
17 | }
18 |
19 | public void run() {
20 | paymentProcessor.process(new Payment("1234", BigDecimal.TEN));
21 | }
22 | }
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/Day073.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day073 {
7 |
8 | public static void main(String[] args) {
9 | Weld weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/paymentprocessor/Asynchronous.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor;
2 |
3 | import jakarta.inject.Qualifier;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.ElementType.*;
9 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
10 |
11 | @Qualifier
12 | @Retention(RUNTIME)
13 | @Target({METHOD, FIELD, PARAMETER, TYPE})
14 | public @interface Asynchronous {
15 | }
16 |
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/paymentprocessor/AsynchronousPaymentProcessor.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor;
2 |
3 | @Asynchronous
4 | class AsynchronousPaymentProcessor implements PaymentProcessor {
5 |
6 | @Override
7 | public void process(Payment payment) {
8 | System.out.println("Processing payment " + payment + " asynchronously");
9 | }
10 | }
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/paymentprocessor/Payment.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor;
2 |
3 | import java.math.BigDecimal;
4 |
5 | public final record Payment(String id, BigDecimal value) {
6 | }
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/paymentprocessor/PaymentProcessor.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor;
2 |
3 | public interface PaymentProcessor {
4 |
5 | void process(Payment payment);
6 | }
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/paymentprocessor/Synchronous.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor;
2 |
3 | import jakarta.inject.Qualifier;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.ElementType.*;
9 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
10 |
11 | @Qualifier
12 | @Retention(RUNTIME)
13 | @Target({METHOD, FIELD, PARAMETER, TYPE})
14 | public @interface Synchronous {
15 | }
16 |
--------------------------------------------------------------------------------
/days/day073/src/main/java/com/thegreatapi/ahundreddaysofjava/day073/paymentprocessor/SynchronousPaymentProcessor.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day073.paymentprocessor;
2 |
3 | @Synchronous
4 | class SynchronousPaymentProcessor implements PaymentProcessor {
5 |
6 | @Override
7 | public void process(Payment payment) {
8 | System.out.println("Processing payment " + payment + " synchronously");
9 | }
10 | }
--------------------------------------------------------------------------------
/days/day073/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day074/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day074
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day074/src/main/java/com/thegreatapi/ahundreddaysofjava/day074/Day074.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day074;
2 |
3 | import java.util.function.Consumer;
4 |
5 | public class Day074 {
6 |
7 | public static void main(String[] args) {
8 | Person daveMustaine = new Person("Dave Mustaine", "Megadeth");
9 |
10 | // A consumer is a Function that uses an argument and returns nothing. Like Function.
11 | Consumer personConsumer = person -> System.out.printf(
12 | "%s from %s sings: %s%n", daveMustaine.name, daveMustaine.bandName, "\"Holy waaaars\""
13 | );
14 |
15 | daveMustaine.sing(personConsumer);
16 | }
17 |
18 | private static record Person(String name, String bandName) {
19 |
20 | void sing(Consumer consumer) {
21 | consumer.accept(this);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/days/day075/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day075
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | import jakarta.inject.Inject;
4 |
5 | class Application {
6 |
7 | private final PaymentProcessor paymentProcessor;
8 |
9 | @Inject
10 | private Application(PaymentProcessor paymentProcessor) {
11 | this.paymentProcessor = paymentProcessor;
12 | }
13 |
14 | public void run() {
15 | paymentProcessor.process(new Payment());
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/Day075.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day075 {
7 |
8 | public static void main(String[] args) {
9 | Weld weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/DependencyA.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | class DependencyA {
4 |
5 | void process() {
6 | System.out.println("Dependency A is processing...");
7 | }
8 | }
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/DependencyB.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | public class DependencyB {
4 |
5 | void process() {
6 | System.out.println("Dependency B is processing...");
7 | }
8 | }
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/Payment.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | public record Payment() {
4 | }
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/PaymentProcessor.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | public interface PaymentProcessor {
4 |
5 | void process(Payment payment);
6 | }
7 |
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/PaymentProcessorFactory.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | import jakarta.enterprise.inject.Produces;
4 |
5 | final class PaymentProcessorFactory {
6 |
7 | private PaymentProcessorFactory() {
8 | }
9 |
10 | @Produces
11 | static PaymentProcessor createPaymentProcessor() {
12 | return new PaymentProcessorImpl(new DependencyA(), new DependencyB());
13 | }
14 | }
--------------------------------------------------------------------------------
/days/day075/src/main/java/com/thegreatapi/ahundreddaysofjava/day075/PaymentProcessorImpl.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day075;
2 |
3 | class PaymentProcessorImpl implements PaymentProcessor {
4 |
5 | private final DependencyA dependencyA;
6 |
7 | private final DependencyB dependencyB;
8 |
9 | PaymentProcessorImpl(DependencyA dependencyA, DependencyB dependencyB) {
10 | this.dependencyA = dependencyA;
11 | this.dependencyB = dependencyB;
12 | }
13 |
14 | @Override
15 | public void process(Payment payment) {
16 | dependencyA.process();
17 | dependencyB.process();
18 |
19 | System.out.println("Finishing payment...");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/days/day075/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day076/src/main/java/com/thegreatapi/ahundreddaysofjava/day076/Day076.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day076;
2 |
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.Produces;
6 | import jakarta.ws.rs.core.MediaType;
7 | import java.time.LocalDate;
8 | import java.util.List;
9 |
10 | @Path("/person")
11 | public class Day076 {
12 |
13 | // To start the server, run:
14 | // mvn compile quarkus:dev
15 |
16 | @GET
17 | @Produces(MediaType.APPLICATION_JSON)
18 | public List getPeople() {
19 | return List.of(
20 | new Person("1", "Ozzy Osbourne", LocalDate.of(1948, 12, 3)),
21 | new Person("2", "Tony Iommi", LocalDate.of(1948, 2, 19)),
22 | new Person("3", "Geezer Butler", LocalDate.of(1948, 7, 19)),
23 | new Person("4", "Bill Ward", LocalDate.of(1948, 5, 5))
24 | );
25 | }
26 |
27 | public static class Person {
28 | private final String id;
29 | private final String name;
30 | private final LocalDate dateOfBirth;
31 |
32 | public Person(String id, String name, LocalDate dateOfBirth) {
33 | this.id = id;
34 | this.name = name;
35 | this.dateOfBirth = dateOfBirth;
36 | }
37 |
38 | public String getId() {
39 | return id;
40 | }
41 |
42 | public String getName() {
43 | return name;
44 | }
45 |
46 | public LocalDate getDateOfBirth() {
47 | return dateOfBirth;
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/days/day078/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day078
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day078/src/main/java/com/thegreatapi/ahundreddaysofjava/day078/Day078.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day078;
2 |
3 | import java.util.List;
4 | import java.util.function.Function;
5 |
6 | public class Day078 {
7 |
8 | public static void main(String[] args) {
9 | int input1 = 42;
10 | String output1 = map(input1, obj -> "The value is " + obj);
11 | System.out.println(output1);
12 |
13 | String[] input2 = {"a", "b", "c"};
14 | List output2 = map(input2, List::of);
15 | System.out.println(output2);
16 | }
17 |
18 | private static R map(T input, Function function) {
19 | return function.apply(input);
20 | }
21 | }
--------------------------------------------------------------------------------
/days/day079/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day079
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day079/src/main/java/com/thegreatapi/ahundreddaysofjava/day079/Day079.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day079;
2 |
3 | import com.thegreatapi.ahundreddaysofjava.day079.myservice.MyService;
4 | import com.thegreatapi.ahundreddaysofjava.day079.myservice.MyServiceFactory;
5 |
6 | public class Day079 {
7 |
8 | public static void main(String[] args) {
9 | // This class has access to MyService and MyServiceFactory, but not MyServiceImpl
10 | MyService myService = MyServiceFactory.createMyService();
11 | myService.run();
12 | }
13 | }
--------------------------------------------------------------------------------
/days/day079/src/main/java/com/thegreatapi/ahundreddaysofjava/day079/myservice/MyService.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day079.myservice;
2 |
3 | public interface MyService {
4 |
5 | void run();
6 | }
--------------------------------------------------------------------------------
/days/day079/src/main/java/com/thegreatapi/ahundreddaysofjava/day079/myservice/MyServiceFactory.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day079.myservice;
2 |
3 | public final class MyServiceFactory {
4 |
5 | private MyServiceFactory() {
6 | }
7 |
8 | public static MyService createMyService() {
9 | return new MyServiceImpl();
10 | }
11 | }
--------------------------------------------------------------------------------
/days/day079/src/main/java/com/thegreatapi/ahundreddaysofjava/day079/myservice/MyServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day079.myservice;
2 |
3 | class MyServiceImpl implements MyService {
4 |
5 | @Override
6 | public void run() {
7 | System.out.println("Running my service...");
8 | }
9 | }
--------------------------------------------------------------------------------
/days/day080/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day080
13 |
14 |
--------------------------------------------------------------------------------
/days/day080/src/main/java/com/thegreatapi/ahundreddaysofjava/day080/Day080.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day080;
2 |
3 | public class Day080 {
4 |
5 | private sealed interface Animal permits Dog, Cat {
6 | void speak();
7 | }
8 |
9 | private static non-sealed class Dog implements Animal {
10 |
11 | @Override
12 | public void speak() {
13 | System.out.println("Woof");
14 | }
15 | }
16 |
17 | private static final class Cat implements Animal {
18 |
19 | @Override
20 | public void speak() {
21 | System.out.println("Meow");
22 | }
23 | }
24 |
25 | // Bird is not allowed in the sealed hierarchy
26 | // private static class Bird implements Animal {
27 | //
28 | // @Override
29 | // public void speak() {
30 | // System.out.println("Pew");
31 | // }
32 | // }
33 | }
--------------------------------------------------------------------------------
/days/day081/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day081
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day081/src/main/java/com/thegreatapi/ahundreddaysofjava/day081/Day081.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day081;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 |
6 | public class Day081 {
7 |
8 | public static void main(String[] args) {
9 | List list = List.of(6, 3, 1, 2, 4, 2, 5, 8, 4, 5, 3);
10 | int frequency = Collections.frequency(list, 4);
11 | System.out.println(frequency);
12 | }
13 | }
--------------------------------------------------------------------------------
/days/day082/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day082
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day082/src/main/java/com/thegreatapi/ahundreddaysofjava/day082/Day082.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day082;
2 |
3 | public class Day082 {
4 |
5 | public static void main(String[] args) {
6 | int a = 2;
7 | int b = Integer.MAX_VALUE;
8 |
9 | long uncastedLong = a * b;
10 | System.out.println(uncastedLong); // Prints: -2
11 |
12 | long castedLong = (long) a * b;
13 | System.out.println(castedLong); // Prints: 4294967294
14 | }
15 | }
--------------------------------------------------------------------------------
/days/day083/src/main/java/com/thegreatapi/ahundreddaysofjava/day083/Day083.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day083;
2 |
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.Produces;
6 | import jakarta.ws.rs.core.MediaType;
7 | import org.eclipse.microprofile.faulttolerance.Timeout;
8 |
9 | import java.time.temporal.ChronoUnit;
10 |
11 | @Path("/hello")
12 | public class Day083 {
13 |
14 | @GET
15 | @Timeout(value = 1, unit = ChronoUnit.SECONDS)
16 | @Produces(MediaType.TEXT_PLAIN)
17 | public String hello() throws InterruptedException {
18 | Thread.sleep(1500);
19 | return "";
20 | }
21 | }
--------------------------------------------------------------------------------
/days/day084/src/main/java/com/thegreatapi/ahundreddaysofjava/day084/Day084.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day084;
2 |
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.Produces;
6 | import jakarta.ws.rs.core.MediaType;
7 | import org.eclipse.microprofile.faulttolerance.Retry;
8 |
9 | import java.time.temporal.ChronoUnit;
10 |
11 | @Path("/hello")
12 | public class Day084 {
13 |
14 | private static int numberOfAttempts;
15 |
16 | @GET
17 | @Retry(maxRetries = 3, delay = 2, delayUnit = ChronoUnit.SECONDS)
18 | @Produces(MediaType.TEXT_PLAIN)
19 | public String hello() {
20 | numberOfAttempts++;
21 |
22 | if (numberOfAttempts < 3) {
23 | throw new RuntimeException("Emulates an error");
24 | } else {
25 | return "Hello after " + numberOfAttempts + " attempts";
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/days/day085/src/main/java/com/thegreatapi/ahundreddaysofjava/day085/Day085.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day085;
2 |
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.Produces;
6 | import jakarta.ws.rs.core.MediaType;
7 | import org.eclipse.microprofile.faulttolerance.Retry;
8 |
9 | import java.security.SecureRandom;
10 | import java.time.temporal.ChronoUnit;
11 |
12 | @Path("/hello")
13 | public class Day085 {
14 |
15 | private static final SecureRandom RANDOM = new SecureRandom();
16 |
17 | private static int numberOfAttempts;
18 |
19 | @GET
20 | @Retry(retryOn = MyCustomException.class, maxRetries = 3, delay = 2, delayUnit = ChronoUnit.SECONDS)
21 | @Produces(MediaType.TEXT_PLAIN)
22 | public String hello() {
23 | numberOfAttempts++;
24 |
25 | if (numberOfAttempts < 3) {
26 | if (RANDOM.nextBoolean()) {
27 | // Will throw MyCustomException and will retry
28 | throw new MyCustomException();
29 | } else {
30 | // Will throw RuntimeException and won't retry
31 | throw new RuntimeException();
32 | }
33 | } else {
34 | return "Hello after " + numberOfAttempts + " attempts";
35 | }
36 | }
37 |
38 | static class MyCustomException extends RuntimeException {
39 | private static final long serialVersionUID = 6631584573985699096L;
40 | }
41 | }
--------------------------------------------------------------------------------
/days/day086/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day086
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day086/src/main/java/com/thegreatapi/ahundreddaysofjava/day086/Day086.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day086;
2 |
3 | public class Day086 {
4 |
5 | public static void main(String[] args) {
6 | var toUpperStrategy = new ToUpperStrategy(IdentityStrategy.getInstance());
7 | var addPrefixStrategy = new AddPrefixStrategy(toUpperStrategy);
8 | var trimStrategy = new TrimStrategy(addPrefixStrategy);
9 |
10 | String result = trimStrategy.apply(" thegreatapi.com ");
11 | System.out.println(result); // Prints: ~> THEGREATAPI.COM
12 | }
13 |
14 | @FunctionalInterface
15 | interface Strategy {
16 | String apply(String s);
17 | }
18 |
19 | abstract static class AbstractStrategy implements Strategy {
20 | private final Strategy delegate;
21 |
22 | protected AbstractStrategy(Strategy delegate) {
23 | this.delegate = delegate;
24 | }
25 |
26 | @Override
27 | public String apply(String s) {
28 | return delegate.apply(doApply(s));
29 | }
30 |
31 | protected abstract String doApply(String s);
32 | }
33 |
34 | static class ToUpperStrategy extends AbstractStrategy {
35 |
36 | ToUpperStrategy(Strategy delegate) {
37 | super(delegate);
38 | }
39 |
40 | @Override
41 | protected String doApply(String s) {
42 | return s.toUpperCase();
43 | }
44 | }
45 |
46 | static class TrimStrategy extends AbstractStrategy {
47 |
48 | protected TrimStrategy(Strategy delegate) {
49 | super(delegate);
50 | }
51 |
52 | @Override
53 | protected String doApply(String s) {
54 | return s.trim();
55 | }
56 | }
57 |
58 | static class AddPrefixStrategy extends AbstractStrategy {
59 |
60 | protected AddPrefixStrategy(Strategy delegate) {
61 | super(delegate);
62 | }
63 |
64 | @Override
65 | protected String doApply(String s) {
66 | return "~> " + s;
67 | }
68 | }
69 |
70 | static class IdentityStrategy implements Strategy {
71 |
72 | private static final IdentityStrategy INSTANCE = new IdentityStrategy();
73 |
74 | private IdentityStrategy() {
75 | }
76 |
77 | static IdentityStrategy getInstance() {
78 | return INSTANCE;
79 | }
80 |
81 | @Override
82 | public String apply(String s) {
83 | return s;
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/days/day087/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day087
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day087/src/main/java/com/thegreatapi/ahundreddaysofjava/day087/Day087.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day087;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | public class Day087 {
9 |
10 | public static void main(String[] args) {
11 | var myAnnotatedObject = new AnnotatedClass();
12 | var myNonAnnotatedObject = new NonAnnotatedClass();
13 |
14 | System.out.println(isAnnotated(myAnnotatedObject)); // Prints: true
15 | System.out.println(isAnnotated(myNonAnnotatedObject)); // Prints: false
16 | }
17 |
18 | private static boolean isAnnotated(Object object) {
19 | return object.getClass().isAnnotationPresent(MyAnnotation.class);
20 | }
21 |
22 | @MyAnnotation
23 | static class AnnotatedClass {
24 | }
25 |
26 | static class NonAnnotatedClass {
27 | }
28 |
29 | @Retention(RetentionPolicy.RUNTIME)
30 | @Target(ElementType.TYPE)
31 | @interface MyAnnotation {
32 | }
33 | }
--------------------------------------------------------------------------------
/days/day088/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day088
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day088/src/main/java/com/thegreatapi/ahundreddaysofjava/day088/Day088.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day088;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | public class Day088 {
9 |
10 | public static void main(String[] args) throws NoSuchFieldException {
11 | var myObject = new MyClass(2021, 8);
12 |
13 | System.out.println(isAnnotated(myObject, "year")); // Prints: true
14 | System.out.println(isAnnotated(myObject, "month")); // Prints: true
15 | }
16 |
17 | private static boolean isAnnotated(Object object, String fieldName) throws NoSuchFieldException {
18 | return object.getClass().getDeclaredField(fieldName).isAnnotationPresent(MyAnnotation.class);
19 | }
20 |
21 | static class MyClass {
22 |
23 | @MyAnnotation
24 | private final int year;
25 |
26 | private final int month;
27 |
28 | MyClass(int year, int month) {
29 | this.year = year;
30 | this.month = month;
31 | }
32 |
33 | public int getYear() {
34 | return year;
35 | }
36 |
37 | public int getMonth() {
38 | return month;
39 | }
40 | }
41 |
42 | @Retention(RetentionPolicy.RUNTIME)
43 | @Target(ElementType.FIELD)
44 | @interface MyAnnotation {
45 | }
46 | }
--------------------------------------------------------------------------------
/days/day089/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day089
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day089/src/main/java/com/thegreatapi/ahundreddaysofjava/day089/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day089;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 | import jakarta.inject.Inject;
5 |
6 | @ApplicationScoped
7 | class Application {
8 |
9 | private final BeanValidator beanValidator;
10 |
11 | @Inject
12 | Application(BeanValidator beanValidator) {
13 | this.beanValidator = beanValidator;
14 | }
15 |
16 | public void run() {
17 | var p = new Person("Freddie", 58);
18 | beanValidator.validate(p);
19 | }
20 | }
--------------------------------------------------------------------------------
/days/day089/src/main/java/com/thegreatapi/ahundreddaysofjava/day089/BeanValidator.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day089;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 | import jakarta.inject.Inject;
5 |
6 | import java.util.Arrays;
7 |
8 | @ApplicationScoped
9 | class BeanValidator {
10 |
11 | private final MethodValidator methodValidator;
12 |
13 | @Inject
14 | BeanValidator(MethodValidator methodValidator) {
15 | this.methodValidator = methodValidator;
16 | }
17 |
18 | void validate(Object o) {
19 | Arrays.stream(o.getClass().getDeclaredMethods())
20 | .filter(method -> method.isAnnotationPresent(Maximum.class))
21 | .forEach(method -> methodValidator.validate(method, o));
22 | }
23 | }
--------------------------------------------------------------------------------
/days/day089/src/main/java/com/thegreatapi/ahundreddaysofjava/day089/Day089.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day089;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day089 {
7 |
8 | public static void main(String[] args) {
9 | var weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 |
18 |
19 | }
--------------------------------------------------------------------------------
/days/day089/src/main/java/com/thegreatapi/ahundreddaysofjava/day089/Maximum.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day089;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.METHOD)
10 | @interface Maximum {
11 | int value();
12 | }
--------------------------------------------------------------------------------
/days/day089/src/main/java/com/thegreatapi/ahundreddaysofjava/day089/MethodValidator.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day089;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 |
5 | import java.lang.reflect.Method;
6 |
7 | @ApplicationScoped
8 | class MethodValidator {
9 |
10 | void validate(Method method, Object object) {
11 | Object value;
12 | try {
13 | value = method.invoke(object);
14 | } catch (ReflectiveOperationException e) {
15 | throw new RuntimeException(e);
16 | }
17 |
18 | int maximum = method.getAnnotation(Maximum.class).value();
19 |
20 | if (value instanceof Integer number && number > maximum) {
21 | throw new RuntimeException("Invalid object. Method " + method.getName() +
22 | " can't return a value greater than " + maximum);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/days/day089/src/main/java/com/thegreatapi/ahundreddaysofjava/day089/Person.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day089;
2 |
3 | class Person {
4 |
5 | private final String name;
6 |
7 | private final int age;
8 |
9 | Person(String name, int age) {
10 | this.name = name;
11 | this.age = age;
12 | }
13 |
14 | public String getName() {
15 | return name;
16 | }
17 |
18 | @Maximum(17)
19 | public int getAge() {
20 | return age;
21 | }
22 | }
--------------------------------------------------------------------------------
/days/day089/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day090/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day090
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day090/src/main/java/com/thegreatapi/ahundreddaysofjava/day090/Day090.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day090;
2 |
3 | import java.util.StringJoiner;
4 |
5 | public class Day090 {
6 |
7 | public static void main(String[] args) {
8 | var stringJoiner = new StringJoiner(";");
9 |
10 | stringJoiner.add("this");
11 | stringJoiner.add("is");
12 | stringJoiner.add("a");
13 | stringJoiner.add("StringJoiner");
14 |
15 | stringJoiner.add("and")
16 | .add("it")
17 | .add("has")
18 | .add("a")
19 | .add("fluent")
20 | .add("api");
21 |
22 | // Prints: this;is;a;StringJoiner;and;it;has;a;fluent;api
23 | System.out.println(stringJoiner);
24 | }
25 | }
--------------------------------------------------------------------------------
/days/day091/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day091
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day091/src/main/java/com/thegreatapi/ahundreddaysofjava/day091/Day091.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day091;
2 |
3 | import java.util.List;
4 |
5 | public class Day091 {
6 |
7 | public static void main(String[] args) {
8 | List originalList = List.of(3, 1, 5, 2, 4, 1, 5, 3, 5, 2, 6);
9 | List distinctElementsList = originalList.stream().distinct().toList();
10 |
11 | System.out.println(distinctElementsList);
12 | }
13 | }
--------------------------------------------------------------------------------
/days/day092/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day092
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day092/src/main/java/com/thegreatapi/ahundreddaysofjava/day092/Day092.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day092;
2 |
3 | import java.util.List;
4 |
5 | public class Day092 {
6 |
7 | public static void main(String[] args) {
8 | List integers = List.of(1, 2, 3, 4, 5);
9 |
10 | Integer sum = integers.stream().mapToInt(Integer::intValue).sum();
11 |
12 | System.out.println(sum);
13 | }
14 | }
--------------------------------------------------------------------------------
/days/day093/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day093
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day093/src/main/java/com/thegreatapi/ahundreddaysofjava/day093/Day093.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day093;
2 |
3 | import java.time.Instant;
4 | import java.time.temporal.ChronoField;
5 | import java.util.List;
6 |
7 | public class Day093 {
8 |
9 | public static void main(String[] args) {
10 | List myList = getList();
11 |
12 | // If myList is null, a NullPointerException will be thrown
13 | for (String s : myList) {
14 | System.out.println(s);
15 | }
16 | }
17 |
18 | private static List getList() {
19 | if (someCondition()) {
20 | return List.of("a", "b", "c");
21 | } else {
22 | // Instead of returning null
23 | // return null;
24 |
25 | // Return an empty list, so the caller don't need to check if the returned list is not null
26 | return List.of();
27 | }
28 | }
29 |
30 | private static boolean someCondition() {
31 | return Instant.now().get(ChronoField.MILLI_OF_SECOND) % 2 == 0;
32 | }
33 | }
--------------------------------------------------------------------------------
/days/day094/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day094
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day094/src/main/java/com/thegreatapi/ahundreddaysofjava/day094/Day094.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day094;
2 |
3 | import java.util.List;
4 | import java.util.concurrent.Flow;
5 | import java.util.concurrent.SubmissionPublisher;
6 |
7 | public class Day094 {
8 |
9 | public static void main(String[] args) {
10 | List judasPriestMembers = List.of(
11 | "Rob Halford",
12 | "K.K. Downing",
13 | "Glenn Tipton",
14 | "Ian Hill",
15 | "Scott Travis"
16 | );
17 |
18 | var subscriber = new MySubscriber();
19 |
20 | try (var publisher = new SubmissionPublisher()) {
21 | publisher.subscribe(subscriber);
22 | judasPriestMembers.forEach(publisher::submit);
23 | }
24 | }
25 |
26 | static class MySubscriber implements Flow.Subscriber {
27 |
28 | private Flow.Subscription subscription;
29 |
30 | @Override
31 | public void onSubscribe(Flow.Subscription subscription) {
32 | System.out.println("Started subscription");
33 | this.subscription = subscription;
34 | subscription.request(1);
35 | }
36 |
37 | @Override
38 | public void onNext(String item) {
39 | System.out.println(item);
40 | subscription.request(1);
41 | }
42 |
43 | @Override
44 | public void onError(Throwable throwable) {
45 | System.err.println("Error: " + throwable);
46 | }
47 |
48 | @Override
49 | public void onComplete() {
50 | System.out.println("Subscription complete");
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/days/day095/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day095
13 |
14 |
15 |
16 |
17 | net.datafaker
18 | datafaker
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day095/src/main/java/com/thegreatapi/ahundreddaysofjava/day095/Day095.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day095;
2 |
3 |
4 | import net.datafaker.Faker;
5 |
6 | import java.util.Date;
7 | import java.util.List;
8 | import java.util.stream.IntStream;
9 |
10 | public class Day095 {
11 |
12 | private static final Faker FAKER = new Faker();
13 |
14 | public static void main(String[] args) {
15 | List people = IntStream.rangeClosed(1, 10)
16 | .mapToObj(i -> createPerson())
17 | .toList();
18 |
19 | people.forEach(System.out::println);
20 |
21 | // Person[firstName=Randall, lastName=Oberbrunner, dateOfBirth=Tue Oct 02 06:16:54 BRT 1962]
22 | // Person[firstName=Thanh, lastName=Lemke, dateOfBirth=Fri Feb 28 10:54:57 BRST 1964]
23 | // Person[firstName=Walker, lastName=Waters, dateOfBirth=Fri Feb 21 16:55:01 BRT 1992]
24 | // Person[firstName=Colin, lastName=Koelpin, dateOfBirth=Wed Jul 28 15:03:17 BRT 1982]
25 | // Person[firstName=Velia, lastName=Corwin, dateOfBirth=Thu Nov 07 06:41:49 BRT 1974]
26 | // Person[firstName=Dwayne, lastName=Wilkinson, dateOfBirth=Mon Apr 24 16:38:56 BRT 1972]
27 | // Person[firstName=Lynn, lastName=Oberbrunner, dateOfBirth=Tue Mar 11 09:29:37 BRT 2003]
28 | // Person[firstName=Cristie, lastName=Yundt, dateOfBirth=Thu Sep 04 05:28:06 BRT 1980]
29 | // Person[firstName=Brynn, lastName=Tremblay, dateOfBirth=Thu Nov 03 10:28:57 BRST 1988]
30 | // Person[firstName=Ahmad, lastName=Homenick, dateOfBirth=Tue Apr 19 15:46:28 BRT 1977]
31 |
32 | // or another way to do the same
33 | people = FAKER.collection().suppliers(Day095::createPerson).len(10).generate();
34 | people.forEach(System.out::println);
35 | }
36 |
37 | private static Person createPerson() {
38 | return new Person(
39 | FAKER.name().firstName(),
40 | FAKER.name().lastName(),
41 | FAKER.date().birthday()
42 | );
43 | }
44 |
45 | static record Person(String firstName, String lastName, Date dateOfBirth) {
46 | }
47 | }
--------------------------------------------------------------------------------
/days/day096/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day096
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/AfterOrderCompletes.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import jakarta.inject.Qualifier;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.ElementType.FIELD;
9 | import static java.lang.annotation.ElementType.METHOD;
10 | import static java.lang.annotation.ElementType.PARAMETER;
11 | import static java.lang.annotation.ElementType.TYPE;
12 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
13 |
14 | @Qualifier
15 | @Retention(RUNTIME)
16 | @Target({METHOD, FIELD, PARAMETER, TYPE})
17 | public @interface AfterOrderCompletes {
18 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/AfterOrderCompletesObserver.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 | import jakarta.enterprise.event.Observes;
5 |
6 | @ApplicationScoped
7 | public class AfterOrderCompletesObserver {
8 |
9 | public void observeAfterOrderCompletesMessage(@Observes @AfterOrderCompletes Order order){
10 | System.out.printf("Order %s was completed.%n", order);
11 | }
12 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import jakarta.inject.Inject;
4 |
5 | import java.math.BigDecimal;
6 | import java.util.List;
7 |
8 | public class Application {
9 |
10 | private final OrderService orderService;
11 |
12 | @Inject
13 | public Application(OrderService orderService) {
14 | this.orderService = orderService;
15 | }
16 |
17 | public void run() {
18 | var order = new Order("Helber", List.of("Pencil", "Book", "Rubber"), new BigDecimal("95.49"));
19 | orderService.complete(order);
20 | }
21 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/BeforeOrderCompletes.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import jakarta.inject.Qualifier;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.ElementType.FIELD;
9 | import static java.lang.annotation.ElementType.METHOD;
10 | import static java.lang.annotation.ElementType.PARAMETER;
11 | import static java.lang.annotation.ElementType.TYPE;
12 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
13 |
14 | @Qualifier
15 | @Retention(RUNTIME)
16 | @Target({METHOD, FIELD, PARAMETER, TYPE})
17 | public @interface BeforeOrderCompletes {
18 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/BeforeOrderCompletesObserver.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 | import jakarta.enterprise.event.Observes;
5 |
6 | @ApplicationScoped
7 | public class BeforeOrderCompletesObserver {
8 |
9 | public void observeBeforeOrderCompletesMessage(@Observes @BeforeOrderCompletes Order order){
10 | System.out.printf("Order %s will complete.%n", order);
11 | }
12 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/Day096.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day096 {
7 |
8 | public static void main(String[] args) {
9 | var weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/Order.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.List;
5 |
6 | public record Order(String customer, List products, BigDecimal totalValue) {
7 | }
--------------------------------------------------------------------------------
/days/day096/src/main/java/com/thegreatapi/ahundreddaysofjava/day096/OrderService.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day096;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 | import jakarta.enterprise.event.Event;
5 | import jakarta.inject.Inject;
6 |
7 | @ApplicationScoped
8 | class OrderService {
9 |
10 | @Inject
11 | @BeforeOrderCompletes
12 | private Event beforeOrderCompleteEvent;
13 |
14 | @Inject
15 | @AfterOrderCompletes
16 | private Event afterOrderCompleteEvent;
17 |
18 | public void complete(Order order) {
19 | beforeOrderCompleteEvent.fire(order);
20 | doComplete(order);
21 | afterOrderCompleteEvent.fire(order);
22 | }
23 |
24 | private static void doComplete(Order order) {
25 | System.out.printf("Completing order %s.%n", order);
26 | }
27 | }
--------------------------------------------------------------------------------
/days/day096/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day097/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day097
13 |
14 |
15 |
16 |
17 | org.javamoney
18 | moneta
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/days/day097/src/main/java/com/thegreatapi/ahundreddaysofjava/day097/Day097.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day097;
2 |
3 | import org.javamoney.moneta.Money;
4 |
5 | import javax.money.CurrencyUnit;
6 | import javax.money.Monetary;
7 |
8 | public class Day097 {
9 |
10 | public static void main(String[] args) {
11 | CurrencyUnit usd = Monetary.getCurrency("USD");
12 |
13 | var oneDollar = Money.of(1, usd);
14 | var fiftyCent = Money.of(0.5, usd);
15 |
16 | // Prints: USD 1.5
17 | System.out.println(oneDollar.add(fiftyCent));
18 | }
19 | }
--------------------------------------------------------------------------------
/days/day098/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day098
13 |
14 |
15 |
16 |
17 | org.jboss.weld.se
18 | weld-se-shaded
19 |
20 |
21 |
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/Application.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import jakarta.inject.Inject;
4 |
5 | public class Application {
6 |
7 | private final MyService myService;
8 |
9 | @Inject
10 | public Application(MyService myService) {
11 | this.myService = myService;
12 | }
13 |
14 | public void run() {
15 | // Will throw: Exception in thread "main" java.lang.RuntimeException: The email helber @ not valid email is not valid.
16 | System.out.println(myService.hello("helber @ not valid email"));
17 | }
18 | }
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/Day098.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import org.jboss.weld.environment.se.Weld;
4 | import org.jboss.weld.environment.se.WeldContainer;
5 |
6 | public class Day098 {
7 |
8 | public static void main(String[] args) {
9 | var weld = new Weld();
10 | WeldContainer container = weld.initialize();
11 | Application application = container.select(Application.class).getHandler().get();
12 |
13 | application.run();
14 |
15 | container.shutdown();
16 | }
17 | }
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/Email.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import java.lang.annotation.Retention;
4 | import java.lang.annotation.Target;
5 |
6 | import static java.lang.annotation.ElementType.PARAMETER;
7 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
8 |
9 | @Target(PARAMETER)
10 | @Retention(RUNTIME)
11 | public @interface Email {
12 | }
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/EmailValidator.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 |
5 | import java.util.regex.Pattern;
6 |
7 | @ApplicationScoped
8 | public class EmailValidator {
9 |
10 | private static final Pattern VALID_EMAIL_ADDRESS_REGEX =
11 | Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE);
12 |
13 | public void validate(String email) {
14 | var matcher = VALID_EMAIL_ADDRESS_REGEX.matcher(email);
15 | if (!matcher.find()) {
16 | throw new RuntimeException("The email " + email + " is not valid.");
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/MyService.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 |
5 | @ApplicationScoped
6 | @Validate
7 | public class MyService {
8 |
9 | public String hello(@Email String email) {
10 | return "Hello " + email;
11 | }
12 | }
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/Validate.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import jakarta.interceptor.InterceptorBinding;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.Target;
7 |
8 | import static java.lang.annotation.ElementType.METHOD;
9 | import static java.lang.annotation.ElementType.TYPE;
10 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
11 |
12 | @InterceptorBinding
13 | @Target({TYPE, METHOD})
14 | @Retention(RUNTIME)
15 | public @interface Validate {
16 | }
--------------------------------------------------------------------------------
/days/day098/src/main/java/com/thegreatapi/ahundreddaysofjava/day098/ValidationInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day098;
2 |
3 | import jakarta.annotation.Priority;
4 | import jakarta.inject.Inject;
5 | import jakarta.interceptor.AroundInvoke;
6 | import jakarta.interceptor.Interceptor;
7 | import jakarta.interceptor.InvocationContext;
8 |
9 | @Interceptor
10 | @Validate
11 | @Priority(1)
12 | public class ValidationInterceptor {
13 |
14 | private final EmailValidator emailValidator;
15 |
16 | @Inject
17 | public ValidationInterceptor(EmailValidator emailValidator) {
18 | this.emailValidator = emailValidator;
19 | }
20 |
21 | @AroundInvoke
22 | public Object intercept(InvocationContext invocationContext) throws Exception {
23 | for (var i = 0; i < invocationContext.getParameters().length; i++) {
24 | if (invocationContext.getMethod().getParameters()[i].isAnnotationPresent(Email.class)
25 | && invocationContext.getParameters()[i] instanceof String email) {
26 | emailValidator.validate(email);
27 | }
28 | }
29 |
30 | return invocationContext.proceed();
31 | }
32 | }
--------------------------------------------------------------------------------
/days/day098/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/days/day099/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day099
13 |
14 |
15 |
--------------------------------------------------------------------------------
/days/day099/src/main/java/com/thegreatapi/ahundreddaysofjava/day099/Day099.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day099;
2 |
3 | public class Day099 {
4 |
5 | public static void main(String[] args) {
6 | /*
7 | In Java, primitive variables (those of types int, byte, short, long, float, double, boolean, or char)
8 | store values, and object variables (all the others, like String, Integer, Person, MyCustomClass...)
9 | store pointers to the memory address where the object is stored.
10 | */
11 |
12 | // The variable 'i' stores the value 42
13 | int i = 42;
14 |
15 | // The variable 'ronnieJamesDio' stores the memory address whre the object 'new Person("Ronnie James Dio")'
16 | // is stored. It's a pointer
17 | Person ronnieJamesDio = new Person("Ronnie James Dio");
18 |
19 | doStuff(i); // Pass a copy of 'i' to 'doStuff'
20 | System.out.println(i); // Prints: 42
21 |
22 | doStuff(ronnieJamesDio); // Pass a copy of the memory address stored by 'ronnieJamesDio' to 'doStuff'
23 | System.out.println(ronnieJamesDio); // Prints: Person{name='Ronnie James Dio'}
24 |
25 | doStuffWithTheObject(ronnieJamesDio); // Pass a copy of the memory address stored by 'ronnieJamesDio' to 'doStuffWithTheObject'
26 | System.out.println(ronnieJamesDio); // Prints: Person{name='Cozy Powell'}
27 | }
28 |
29 | private static void doStuff(int n) {
30 | // 'n' is a copy of 'i'
31 |
32 | // This changes the value stored by 'n'
33 | n = 100;
34 | }
35 |
36 | private static void doStuff(Person p) {
37 | // p stores a copy of the memory address stored by the variable 'ronnieJamesDio' (a pointer).
38 |
39 | // when we assign a new object, actually we're assigning the memory address where this new object is stored.
40 | // We're assigning a new pointer.
41 | p = new Person("Cozy Powell");
42 | }
43 |
44 | private static void doStuffWithTheObject(Person p) {
45 | // p stores a copy of the memory address stored by the variable 'ronnieJamesDio' (a pointer).
46 |
47 | // We're modifying the attribute of the object stored in the memory address to where the variable p points
48 | p.name = "Cozy Powell";
49 | }
50 |
51 | private static class Person {
52 | private String name;
53 |
54 | Person(String name) {
55 | this.name = name;
56 | }
57 |
58 | @Override
59 | public String toString() {
60 | return "Person{" +
61 | "name='" + name + '\'' +
62 | '}';
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/days/day100/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | days
7 | com.thegreatapi.100daysofjava
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | day100
13 |
14 |
15 |
16 |
17 | org.openjdk.jmh
18 | jmh-core
19 |
20 |
21 | org.openjdk.jmh
22 | jmh-generator-annprocess
23 |
24 |
25 | com.google.code.findbugs
26 | jsr305
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/days/day100/src/main/java/com/thegreatapi/ahundreddaysofjava/day100/Day100.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day100;
2 |
3 | import org.openjdk.jmh.annotations.Benchmark;
4 |
5 | public class Day100 {
6 |
7 | @Benchmark
8 | public void benchmarkNullable(ExecutionPlan plan) {
9 | for (var i = 0; i < ExecutionPlan.ITERACTIONS; i++) {
10 | String value = plan.getMyService().getNullable(i);
11 | if (value != null) {
12 | System.out.println(i + ": " + value);
13 | }
14 | }
15 | }
16 |
17 | @Benchmark
18 | public void benchmarkOptional(ExecutionPlan plan) {
19 | for (var i = 0; i < ExecutionPlan.ITERACTIONS; i++) {
20 | var finalI = i;
21 | plan.getMyService().getWithOptional(i).ifPresent(value -> System.out.println(finalI + ": " + value));
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/days/day100/src/main/java/com/thegreatapi/ahundreddaysofjava/day100/ExecutionPlan.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day100;
2 |
3 | import org.openjdk.jmh.annotations.Level;
4 | import org.openjdk.jmh.annotations.Scope;
5 | import org.openjdk.jmh.annotations.Setup;
6 | import org.openjdk.jmh.annotations.State;
7 |
8 | import java.util.Collections;
9 | import java.util.Map;
10 | import java.util.TreeMap;
11 |
12 | @State(Scope.Benchmark)
13 | public class ExecutionPlan {
14 |
15 | public static final int ITERACTIONS = 10_000;
16 |
17 | private MyService myService;
18 |
19 | @Setup(Level.Iteration)
20 | public void setUp() {
21 | myService = new MyService(createMap());
22 | }
23 |
24 | public MyService getMyService() {
25 | return myService;
26 | }
27 |
28 | private static Map createMap() {
29 | Map map = new TreeMap<>();
30 | for (var i = 0; i < ITERACTIONS; i++) {
31 | map.put(i, i % 2 == 0 ? "yes" : null);
32 | }
33 | return Collections.unmodifiableMap(map);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/days/day100/src/main/java/com/thegreatapi/ahundreddaysofjava/day100/MyService.java:
--------------------------------------------------------------------------------
1 | package com.thegreatapi.ahundreddaysofjava.day100;
2 |
3 | import javax.annotation.Nonnull;
4 | import javax.annotation.Nullable;
5 | import java.util.Map;
6 | import java.util.Optional;
7 |
8 | public class MyService {
9 |
10 | private final Map map;
11 |
12 | public MyService(Map map) {
13 | this.map = map;
14 | }
15 |
16 | @Nonnull
17 | public Optional getWithOptional(Integer index) {
18 | return Optional.ofNullable(map.get(index));
19 | }
20 |
21 | @Nullable
22 | public String getNullable(Integer index) {
23 | return map.get(index);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------