11# JKScope
22
3- Java scope functions in the Kotlin style
3+ Java scope functions inspired by Kotlin
44
55[ ![ Maven Central] ( https://maven-badges.herokuapp.com/maven-central/com.plugatar.jkscope/jkscope/badge.svg )] ( https://maven-badges.herokuapp.com/maven-central/com.plugatar.jkscope/jkscope )
66[ ![ Javadoc] ( https://javadoc.io/badge2/com.plugatar.jkscope/jkscope/javadoc.svg )] ( https://javadoc.io/doc/com.plugatar.jkscope/jkscope )
77[ ![ License] ( https://img.shields.io/badge/License-Apache%202.0-blue.svg )] ( https://opensource.org/licenses/Apache-2.0 )
88
99## Table of Contents
1010
11- * [ How to use] ( #How-to-use )
12- * [ Example] ( #Examples )
11+ * [ Motivation] ( #motivation )
12+ * [ How to use] ( #how-to-use )
13+ * [ Docs] ( #docs )
14+ * [ JKScope interface methods] ( #jkscope-interface-methods )
15+ * [ ` let ` and ` also ` ] ( #let-and-also )
16+ * [ ` takeIf ` and ` takeUnless ` ] ( #takeif-and-takeunless )
17+ * [ ` letOut ` ] ( #letout )
18+ * [ ` letOpt ` ] ( #letopt )
19+ * [ JKScope static methods] ( #jkscope-static-methods )
20+ * [ ` run ` , ` runCatching ` and ` runRec ` ] ( #run-runcatching-and-runrec )
21+ * [ ` with ` , ` withInt ` , ` withLong ` and ` withDouble ` ] ( #with-withint-withlong-and-withdouble )
22+ * [ ` let ` variations] ( #let-variations )
23+
24+ ## Motivation
25+
26+ Inspired by the [ Kotlin scope function] ( https://kotlinlang.org/docs/scope-functions.html ) I want to reduce the number of
27+ lines of my Java code and make this code more readable.
28+
29+ This library should have been written for this feature at a minimum 😄
30+
31+ ```
32+ Map<String, Integer> map = let(new HashMap<>(), it -> {
33+ it.put("val1", 1);
34+ it.put("val2", 2);
35+ });
36+ ```
37+
38+ It is also worth noting that all functions allow you not to process checked exceptions.
39+
40+ ```
41+ public static void main(String[] args) {
42+ URI uri = let(() -> new URI("abc"));
43+ }
44+ ```
1345
1446## How to use
1547
16- Requires Java 8+ version.
48+ Java version required: 1.8+. The library has no dependencies. All you need is this (get the latest
49+ version [ here] ( https://github.com/evpl/jkscope/releases ) ):
1750
1851Maven:
1952
@@ -34,107 +67,141 @@ dependencies {
3467}
3568```
3669
37- ## Examples
70+ ## Docs
3871
39- ### Static methods
72+ ### JKScope interface methods
4073
41- ``` java
42- import static com.plugatar.jkscope.JKScope.let ;
43- import static com.plugatar.jkscope.JKScope.run ;
44- import static com.plugatar.jkscope.JKScope.with ;
45- import static com.plugatar.jkscope.JKScope.withNonNull ;
74+ You need to implement ` JKScope ` interface to use these methods.
4675
47- class ExampleTest {
76+ ```
77+ class MyObject implements JKScope<MyObject> { }
78+ ```
4879
49- @Test
50- void letMethod () {
51- let(() - > {
52- System . out. println(" ok" );
53- });
54- }
80+ #### ` let ` and ` also `
5581
56- @Test
57- void runMethod () {
58- int result = run(() - > {
59- System . out. println(" ok" );
60- return 12 ;
61- });
62- }
82+ Both methods are the same. These methods perform given function block on this object and returns this object.
6383
64- @Test
65- void withMethod () {
66- String value1 = " a " ;
67- String value2 = " b " ;
68- String value3 = " c " ;
84+ ```
85+ MyDTO myDTO = new MyDTO().let(it -> {
86+ it.setProperty("value") ;
87+ it.setAnother("another value") ;
88+ }) ;
6989
70- with(value2, it - > {
71- System . out. println(it);
72- });
90+ MyResource myResource = new MyResource().also(it -> it.init());
91+ ```
7392
74- String result = with(value1, value2, (it1, it2) - > it1 + it2);
93+ #### ` takeIf ` and ` takeUnless `
7594
76- with(value1, value2, value3, (it1, it2, it3) - > {
77- System . out. println(it1 + it2 + it3);
78- });
95+ ` takeIf ` method performs given function block on this object and returns ` Opt ` monad of this object if the condition is
96+ met or empty ` Opt ` instance if the condition is not met. ` takeUnless ` method has reverse logic.
7997
80- with(value2). takeNonNull(). takeIf(it - > it. length() > 3 ). let(it - > System . out. println(it));
81- }
98+ ```
99+ new MyObject().takeIf(it -> it.getInt() > 10).takeUnless(it -> it.getInt() > 20).let(it -> System.out.println(it));
100+ ```
101+
102+ #### ` letOut `
82103
83- @Test
84- void withNonNullMethod () {
85- String value1 = " a" ;
86- String value2 = null ;
87- String value3 = " c" ;
104+ ` takeIf ` method performs given function block on this object and returns result.
88105
89- withNonNull(value2, it - > {
90- System . out . println(it );
91- });
106+ ```
107+ Integer value = new MyObject().letOut(it -> it.getInt() );
108+ ```
92109
93- withNonNull(value1, value2, (it1, it2) - > it1 + it2) . let(it - > System . out . println(it));
110+ #### ` letOpt `
94111
95- withNonNull(value1, value2, value3, (it1, it2, it3) - > {
96- System . out. println(it1 + it2 + it3);
97- });
112+ ` takeIf ` method performs given function block on this object and returns ` Opt ` monad of result.
98113
99- withNonNull(value2). takeNonNull(). takeUnless(it - > it. length() < 3 ). let(it - > System . out. println(it));
100- }
101- }
114+ ```
115+ new MyObject().letOpt(it -> it.getInt()).takeIf(it -> it > 10).let(it -> System.out.println(it));
102116```
103117
104- ### Instance methods
118+ ### JKScope static methods
105119
106- ``` java
107- public class MyClass implements JKScope<MyClass > {
120+ You can import the methods you need or import all to use them all.
108121
109- public MyClass () {
110- }
122+ ```
123+ import static com.plugatar.jkscope.JKScope.*;
124+ ```
111125
112- public void method1 () {
113- }
126+ #### ` run ` , ` runCatching ` and ` runRec `
127+
128+ ` run ` just runs given function block, ` runCatching ` runs ignore any Throwable, ` runRec ` runs function block allowing
129+ yourself to be called recursively.
130+
131+ ```
132+ run(() -> {
133+ System.out.println("Hi");
134+ });
114135
115- public String method2 () {
116- return " abc" ;
136+ runCatching(() -> {
137+ System.out.println("Hi");
138+ });
139+
140+ runRec(func -> {
141+ if (new Random().nextInt(0, 100) == 50) {
142+ func.run();
117143 }
118- }
144+ });
145+ ```
146+
147+ #### ` with ` , ` withInt ` , ` withLong ` and ` withDouble `
148+
149+ These methods perform given function block on given values.
150+
151+ ```
152+ with(value, it -> {
153+ System.out.println(value);
154+ });
155+
156+ with(value1, value2, (v1, v2) -> {
157+ System.out.println(v1);
158+ System.out.println(v2);
159+ });
160+ ```
161+
162+ #### ` let ` variations
163+
164+ ` let ` returns ` Opt ` instance of given value, ` letNonNull ` returns ` Opt ` instance of given value of given value or
165+ empty ` Opt ` instance if given value is null.
119166
120- class ExampleTest {
167+ ```
168+ let(value).takeNonNull().takeUnless(it -> it.isEmpty()).takeIf(it -> it.length() < 100).let(it -> System.out.println(it));
121169
122- @Test
123- void instance () {
124- MyClass myClass = new MyClass (). also(it - > it. method1());
170+ letNonNull(value).takeUnless(it -> it.isEmpty()).takeIf(it -> it.length() < 100).let(it -> System.out.println(it));
171+ ```
125172
126- myClass . apply(it - > it . method1()) . apply(it - > it . method2());
173+ ` let ` , ` letInt ` , ` letLong ` and ` letDouble ` returns result of function block.
127174
128- myClass. let(it - > {
129- it. method1();
130- it. method2();
131- });
175+ ```
176+ String value = let(() -> {
177+ //...
178+ return "val";
179+ });
180+ ```
181+
182+ ` let ` , ` letInt ` , ` letLong ` and ` letDouble ` methods can also receive a value, process it using a function block, and
183+ return that value.
184+
185+ ```
186+ String value = let("val", it -> {
187+ System.out.println(it);
188+ });
189+ ```
132190
133- String result = myClass. run(it - > it. method2());
191+ ` letRec ` , ` letIntRec ` , ` letLongRec ` and ` letDoubleRec ` accept initial value and allow you to process it recursively
192+ returning the result.
134193
135- myClass. takeIf(it - > it. method2(). length() > 3 ). let(it - > {
136- System . out. println(" ok" );
137- });
194+ ```
195+ int value = letIntRec(10, (n, func) -> {
196+ if (n < 2) {
197+ return n;
138198 }
139- }
199+ return func.apply(n - 1) + func.apply(n - 2);
200+ });
201+ ```
202+
203+ ` letWith ` methods accept values and returning the result of function block.
204+
205+ ```
206+ int value = letWith("42", it -> Integer.valueOf(it));
140207```
0 commit comments