-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
executable file
·278 lines (266 loc) · 19.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- Generated by Apache Maven Doxia Site Renderer 1.3 at May 19, 2012 -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>op4j: bending the Java spoon - Main</title>
<style type="text/css" media="all">
@import url("./css/maven-base.css");
@import url("./css/maven-theme.css");
@import url("./css/site.css");
</style>
<link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
<meta name="Date-Revision-yyyymmdd" content="20120519" />
<meta http-equiv="Content-Language" content="en" />
</head>
<body class="composite">
<div id="banner">
<a href="./" id="bannerLeft">
<img src="images/op4j_logo.png" alt="op4j: bending the Java spoon" />
</a>
<div class="clear">
<hr/>
</div>
</div>
<div id="breadcrumbs">
<div class="xleft">
<span id="publishDate">Last Published: 19 May 2012</span>
| <span id="projectVersion">Version: 1.2</span>
</div>
<div class="xright"> <a href="index.html" title="Main">Main</a>
|
<a href="download.html" title="Download">Download</a>
|
<a href="https://www.bendingthejavaspoon.com" class="externalLink" title="Example Recipes Blog">Example Recipes Blog</a>
|
<a href="https://github.com/op4j/op4j.github.com/issues" class="externalLink" title="Issue Tracking">Issue Tracking</a>
|
<a href="apidocs/index.html" title="Javadoc">Javadoc</a>
|
<a href="https://github.com/op4j" class="externalLink" title="Github Project Page">Github Project Page</a>
</div>
<div class="clear">
<hr/>
</div>
</div>
<div id="leftColumn">
<div id="navcolumn">
<h5>The op4j Project</h5>
<ul>
<li class="none">
<strong>· Main</strong>
</li>
<li class="none">
<a href="download.html" title="· Download">· Download</a>
</li>
<li class="none">
<a href="maveninfo.html" title="· Maven Info">· Maven Info</a>
</li>
<li class="none">
<a href="dependencies.html" title="· Dependencies">· Dependencies</a>
</li>
<li class="none">
<a href="https://github.com/op4j" class="externalLink" title="· Github Repository">· Github Repository</a>
</li>
<li class="none">
<a href="https://www.bendingthejavaspoon.com" class="externalLink" title="· Example Recipes">· Example Recipes</a>
</li>
<li class="none">
<a href="https://github.com/op4j/op4j.github.com/issues" class="externalLink" title="· Issue Tracking">· Issue Tracking</a>
</li>
<li class="expanded">
<a href="#" title="· Documentation">· Documentation</a>
<ul>
<li class="none">
<a href="basics.html" title="· The Basics">· The Basics</a>
</li>
<li class="expanded">
<a href="#" title="· Working with...">· Working with...</a>
<ul>
<li class="none">
<a href="arrays.html" title="· Arrays">· Arrays</a>
</li>
<li class="none">
<a href="lists.html" title="· Lists">· Lists</a>
</li>
<li class="none">
<a href="maps.html" title="· Maps">· Maps</a>
</li>
<li class="none">
<a href="sets.html" title="· Sets">· Sets</a>
</li>
<li class="none">
<a href="generic.html" title="· Any object (generic)">· Any object (generic)</a>
</li>
</ul>
</li>
<li class="expanded">
<a href="#" title="· Functions">· Functions</a>
<ul>
<li class="none">
<a href="functions.html" title="· About Functions">· About Functions</a>
</li>
<li class="none">
<a href="call.html" title="· Call">· Call</a>
</li>
<li class="none">
<a href="get.html" title="· Get">· Get</a>
</li>
<li class="none">
<a href="fnfunc.html" title="· FnFunc">· FnFunc</a>
</li>
<li class="none">
<a href="fnboolean.html" title="· FnBoolean">· FnBoolean</a>
</li>
<li class="none">
<a href="fncalendar.html" title="· FnCalendar">· FnCalendar</a>
</li>
<li class="none">
<a href="fndate.html" title="· FnDate">· FnDate</a>
</li>
<li class="none">
<a href="fnobject.html" title="· FnObject">· FnObject</a>
</li>
<li class="none">
<a href="fnstring.html" title="· FnString">· FnString</a>
</li>
<li class="expanded">
<a href="#" title="· Numbers">· Numbers</a>
<ul>
<li class="none">
<a href="fnnumber.html" title="· FnNumber">· FnNumber</a>
</li>
<li class="none">
<a href="fnbigdecimal.html" title="· FnBigDecimal">· FnBigDecimal</a>
</li>
<li class="none">
<a href="fnbiginteger.html" title="· FnBigInteger">· FnBigInteger</a>
</li>
<li class="none">
<a href="fninteger.html" title="· FnInteger">· FnInteger</a>
</li>
<li class="none">
<a href="fnlong.html" title="· FnLong">· FnLong</a>
</li>
<li class="none">
<a href="fnfloat.html" title="· FnFloat">· FnFloat</a>
</li>
<li class="none">
<a href="fndouble.html" title="· FnDouble">· FnDouble</a>
</li>
<li class="none">
<a href="fndouble.html" title="· FnShort">· FnShort</a>
</li>
</ul>
</li>
<li class="expanded">
<a href="#" title="· Structures">· Structures</a>
<ul>
<li class="none">
<a href="fnarray.html" title="· FnArray">· FnArray</a>
</li>
<li class="none">
<a href="fnlist.html" title="· FnList">· FnList</a>
</li>
<li class="none">
<a href="fnmap.html" title="· FnMap">· FnMap</a>
</li>
<li class="none">
<a href="fnset.html" title="· FnSet">· FnSet</a>
</li>
<li class="none">
<a href="fntuple.html" title="· FnTuple">· FnTuple</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="none">
<a href="apidocs/op4j/index.html" title="· Javadoc">· Javadoc</a>
</li>
<li class="none">
<a href="faq.html" title="· FAQ">· FAQ</a>
</li>
</ul>
</li>
<li class="none">
<a href="license.html" title="· License">· License</a>
</li>
<li class="none">
<a href="team.html" title="· Team">· Team</a>
</li>
</ul>
<ul>
<li class="collapsed">
<a href="ognl-about.html" title="· op4j-ognl">· op4j-ognl</a>
</li>
<li class="collapsed">
<a href="jodatime-about.html" title="· op4j-jodatime">· op4j-jodatime</a>
</li>
</ul>
<a href="https://maven.apache.org" title="Built with Maven 2" class="poweredBy">
<img class="poweredBy" alt="Built with Maven 2" src="https://maven.apache.org/images/logos/maven-feather.png" />
</a>
</div>
</div>
<div id="bodyColumn">
<div id="contentBox">
<p><b>op4j 1.2 RELEASED!</b> (May 14th, 2012). <b><a href="./download.html">[DOWNLOAD]</a></b> ChangeLogs: <a href="./op4j-ChangeLog.txt">[op4j]</a> <a href="./op4j-ognl-ChangeLog.txt">[op4j-ognl]</a> <a href="./op4j-jodatime-ChangeLog.txt">[op4j-jodatime]</a></p><p>Also see the <b><a class="externalLink" href="https://www.bendingthejavaspoon.com">[EXAMPLE RECIPES BLOG]</a></b></p><div class="section"><h2>op4j: Bending the Java spoon<a name="op4j:_Bending_the_Java_spoon"></a></h2><p><b>op4j</b> (pronounced <i>['op-ah]</i>) <b>is a developer happiness tool</b>. It is a Java library aimed at <b>improving quality, semantics, cleanness and readability of Java code</b>, especially auxiliary code like data conversion, structure iteration, filtering, mapping, etc.</p><p>op4j is a powerful implementation of the <a class="externalLink" href="http://martinfowler.com/bliki/FluentInterface.html">Fluent Interface</a> style of code. It allows you to create <i>chained expressions</i> which apply both predefined or user-defined functions to your objects in a fluid and readable way. This improves the way your code looks and greatly reduces the complexity of executing auxiliary low-level tasks in the highly bureaucratic, statically -and strongly- typed language that Java is. </p><p>But also, op4j is a huge repository of <b>several hundred functions</b> with more than <b>one thousand different parameterizations</b> ready to be used in your expressions. From regular expression matching on Strings to locale-savvy number conversion, to easy Calendar creation. Check the <i>FnX function hub classes</i> online documentation to know more.</p><p>op4j is open source, and it is distributed under the terms of the Apache License 2.0.</p><p>op4j has an <b>EXAMPLE RECIPES BLOG</b> called <a class="externalLink" href="https://www.bendingthejavaspoon.com">Bending the Java spoon</a>, where you can find simple and explanatory examples on how to use the library.</p><p>For knowing more, read the quick example below, have a look at the <b><a href="./basics.html">Basics</a></b> page or choose any link from the menu on the left.</p><div class="section"><h3>A very quick overview example<a name="A_very_quick_overview_example"></a></h3><p>Let's see an example of an op4j <i>operation expression</i>.</p><p>op4j operation expressions usually start with <b>Op.on(...)</b> (read it as <i>"operate on"</i>) specifying the object on which op4j will operate, and end with <b>get()</b>, which effectively executes the defined expression and returns the result. Let's see an example:</p><p>Let's convert a <tt>List<String></tt> into an (ordered) <tt>Set<String></tt>:</p><div class="source"><pre> // Without op4j
Set<String> set = new LinkedHashSet<String>(list);
// With op4j
Set<String> set = Op.on(list).toSet().get();
</pre></div><p>Ok, op4j code here was a little bit more readable than "normal" java code... but what if all those Strings were dates in the <tt>dd/MM/yyyy</tt> format and we wanted to convert them into <tt>java.util.Calendar</tt> objects?</p><p>Let's iterate the newly created set and execute one of op4j's more than 200 predefined functions on each of the set's elements...</p><div class="source"><pre> Set<Calendar> set =
Op.on(list).toSet().forEach().exec(FnString.toCalendar("dd/MM/yyyy")).get();
</pre></div><p>That was cool. But unfortunately, it seems that some of those Strings could be null, and we don't want nulls to be included in the final result, so let's remove them before executing the conversion...</p><div class="source"><pre> Set<Calendar> set =
Op.on(list).toSet().removeAllNull().forEach().exec(FnString.toCalendar("dd/MM/yyyy")).get();
</pre></div><p>And a <tt>forEach().exec()</tt> (= <i>execute on each</i>) operation is what is usually called a <i>"map"</i> operation (in fact <tt>map()</tt> is a <tt>forEach().exec().endFor()</tt>), so why not use that more suitable name: </p><div class="source"><pre> Set<Calendar> set =
Op.on(list).toSet().removeAllNull().map(FnString.toCalendar("dd/MM/yyyy")).get();
</pre></div><p>But we will go a little bit further because we don't want dates in the future, only the past ones, and so we will reposition that <tt>removeAllNull()</tt> operation after the <tt>map</tt> operation (conversion will not affect nulls) and extend it with a boolean condition (a function returning a boolean) in order to remove future dates:</p><div class="source"><pre> Calendar now = Calendar.getInstance();
Set<Calendar> set =
Op.on(list).toSet().map(FnString.toCalendar("dd/MM/yyyy")).removeAllNullOrTrue(FnCalendar.after(now)).get();
</pre></div><p>Wow! this looks great. There is no need to compare with "normal" java code, right?... but let's do it anyway ;-)</p><div class="source"><pre> // ****************************
// WARNING: Non-op4j code!!
// ****************************
Calendar now = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Set<Calendar> set = new LinkedHashSet<Calendar>();
for (String element : list) {
if (element != null) {
try {
date = dateFormat1.parse(element);
} catch (ParseException e) {
throw new SomeException(e);
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(date.getTime());
if (!calendar.after(now)) {
set.add(calendar);
}
}
}
</pre></div><p>Awful!! And this isn't even application logic, it's just auxiliary code for converting and filtering a list of String dates... and it has turned into a lot of complex and hard-to-understand code, probably bigger and uglier than the (much more important) application logic that might surround it.</p><p>Output will be exactly the same for both fragments of code. Given:</p><div class="source"><pre>List<String> list = ["12/10/1492", "6/12/1978", "15/07/2045", null]
</pre></div><p>...both will return:</p><div class="source"><pre>Set<Calendar> set = [Calendar(12 October 1492), Calendar(6 December 1978)]
</pre></div><p><br /><br /><b>Making it last: turning expressions into functions</b> </p><p>And... what if we didn't really want to execute our date handling expression right there, but rather just define it and <i>store</i> it somehow for later use (similar -just similar- to what you'd achieve with a closure)? </p><p>Well, then instead of our <b>Op.on(...)</b> we can create an equivalent <b>Fn.on(...)</b> expression with exactly the same structure, and when executing <b>get()</b> we will obtain an executable <tt>Function<List<String>,Set<Calendar>></tt> object (read it as <i>"Function that receives a List of String and returns a Set of Calendar"</i>):</p><div class="source"><pre> Function<List<String>,Set<Calendar>> dateProcessFunction =
Fn.onListOf(Types.STRING).toSet().map(FnString.toCalendar("dd/MM/yyyy")).removeAllNullOrTrue(FnCalendar.after(now)).get();
</pre></div><p>...and then we will be able to use it in an <tt>exec</tt> operation exactly as any other predefined (or user-defined) function, like: </p><div class="source"><pre> List<List<String>> listOfListOfStrings = ...
List<Set<Calendar>> listOfSetOfCalendars =
Op.on(listOfListOfStrings).forEach().exec(dateProcessFunction).get();
</pre></div><p>... or even directly execute it just like:</p><div class="source"><pre> Set<Calendar> set = dateProcessFunction.execute(list);
</pre></div></div><div class="section"><h3>Learning more...<a name="Learning_more..."></a></h3><p>If you want to know more, you should start with <a href="./basics.html">The Basics</a>.</p></div></div>
</div>
</div>
<div class="clear">
<hr/>
</div>
<div id="footer">
<div class="xright">
Copyright © 2012
<a href="https://www.op4j.org">The OP4J team</a>.
All Rights Reserved.
</div>
<div class="clear">
<hr/>
</div>
</div>
</body>
</html>