├── .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 | --------------------------------------------------------------------------------