-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
531 lines (316 loc) · 237 KB
/
atom.xml
File metadata and controls
531 lines (316 loc) · 237 KB
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>irusist - 坚持是一种美德</title>
<link href="/atom.xml" rel="self"/>
<link href="http://irusist.github.io/"/>
<updated>2017-11-06T15:29:11.000Z</updated>
<id>http://irusist.github.io/</id>
<author>
<name>irusist</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>Github语言排行[人工置顶]</title>
<link href="http://irusist.github.io/2100/01/01/Github%E8%AF%AD%E8%A8%80%E6%8E%92%E8%A1%8C/"/>
<id>http://irusist.github.io/2100/01/01/Github语言排行/</id>
<published>2099-12-31T16:00:01.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>以下内容是通过github api动态生成的, 生成时间: 2016年01月02日22时05分56秒</p><a id="more"></a><h2 id="Go语言排行"><a href="#Go语言排行" class="headerlink" title="Go语言排行"></a>Go语言排行</h2><ul><li>docker: <a href="https://github.com/docker/docker" target="_blank" rel="noopener">Docker - the open-source application container engine</a>, stars: 27443</li><li>go: <a href="https://github.com/golang/go" target="_blank" rel="noopener">The Go programming language</a>, stars: 13394</li><li>kubernetes: <a href="https://github.com/kubernetes/kubernetes" target="_blank" rel="noopener">Container Cluster Manager from Google</a>, stars: 11933</li><li>syncthing: <a href="https://github.com/syncthing/syncthing" target="_blank" rel="noopener">Open Source Continuous File Synchronization</a>, stars: 10791</li><li>awesome-go: <a href="https://github.com/avelino/awesome-go" target="_blank" rel="noopener">A curated list of awesome Go frameworks, libraries and software</a>, stars: 10420</li><li>gogs: <a href="https://github.com/gogits/gogs" target="_blank" rel="noopener">Gogs (Go Git Service) is a painless self-hosted Git service.</a>, stars: 10332</li><li>lantern: <a href="https://github.com/getlantern/lantern" target="_blank" rel="noopener">:zap: Open Internet for everyone. Lantern is a free desktop application that delivers fast, reliable and secure access to the open Internet for users in censored regions. It uses a variety of techniques to stay unblocked, including P2P and domain fronting. Lantern relies on users in uncensored regions acting as access points to the open Internet.</a>, stars: 9147</li><li>build-web-application-with-golang: <a href="https://github.com/astaxie/build-web-application-with-golang" target="_blank" rel="noopener">A golang ebook intro how to build a web with golang</a>, stars: 8843</li><li>etcd: <a href="https://github.com/coreos/etcd" target="_blank" rel="noopener">Distributed reliable key-value store for the most critical data of a distributed system</a>, stars: 8347</li><li>martini: <a href="https://github.com/go-martini/martini" target="_blank" rel="noopener">Classy web framework for Go</a>, stars: 8078</li><li>hub: <a href="https://github.com/github/hub" target="_blank" rel="noopener">hub helps you win at git.</a>, stars: 7805</li><li>hugo: <a href="https://github.com/spf13/hugo" target="_blank" rel="noopener">A Fast and Flexible Static Site Generator built with love by spf13 in GoLang</a>, stars: 7717</li><li>influxdb: <a href="https://github.com/influxdb/influxdb" target="_blank" rel="noopener">Scalable datastore for metrics, events, and real-time analytics</a>, stars: 7074</li><li>cayley: <a href="https://github.com/google/cayley" target="_blank" rel="noopener">An open-source graph database</a>, stars: 6721</li><li>websocketd: <a href="https://github.com/joewalnes/websocketd" target="_blank" rel="noopener">Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets. </a>, stars: 6703</li><li>ngrok: <a href="https://github.com/inconshreveable/ngrok" target="_blank" rel="noopener">Introspected tunnels to localhost</a>, stars: 6289</li><li>revel: <a href="https://github.com/revel/revel" target="_blank" rel="noopener">A high productivity, full-stack web framework for the Go language.</a>, stars: 6188</li><li>nsq: <a href="https://github.com/nsqio/nsq" target="_blank" rel="noopener">A realtime distributed messaging platform</a>, stars: 6015</li><li>gotty: <a href="https://github.com/yudai/gotty" target="_blank" rel="noopener">Share your terminal as a web application</a>, stars: 6004</li><li>cockroach: <a href="https://github.com/cockroachdb/cockroach" target="_blank" rel="noopener">A Scalable, Survivable, Strongly-Consistent SQL Database</a>, stars: 5971</li><li>drone: <a href="https://github.com/drone/drone" target="_blank" rel="noopener">Drone is a Continuous Integration platform built on Docker, written in Go</a>, stars: 5948</li><li>beego: <a href="https://github.com/astaxie/beego" target="_blank" rel="noopener">beego is an open-source, high-performance web framework for the Go programming language.</a>, stars: 5842</li><li>consul: <a href="https://github.com/hashicorp/consul" target="_blank" rel="noopener">Consul is a tool for service discovery, monitoring and configuration.</a>, stars: 5300</li><li>gin: <a href="https://github.com/gin-gonic/gin" target="_blank" rel="noopener">Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance – up to 40 times faster. If you need smashing performance, get yourself some Gin.</a>, stars: 5079</li><li>rkt: <a href="https://github.com/coreos/rkt" target="_blank" rel="noopener">rkt is an App Container runtime for Linux</a>, stars: 4976</li><li>packer: <a href="https://github.com/mitchellh/packer" target="_blank" rel="noopener">Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.</a>, stars: 4846</li><li>gor: <a href="https://github.com/buger/gor" target="_blank" rel="noopener">Gor is an open-source tool for capturing and replaying live HTTP traffic into a test environment in order to continuously test your system with real data. It can be used to increase confidence in code deployments, configuration changes and infrastructure changes.</a>, stars: 4464</li><li>termui: <a href="https://github.com/gizak/termui" target="_blank" rel="noopener">Golang terminal dashboard</a>, stars: 4204</li><li>flynn: <a href="https://github.com/flynn/flynn" target="_blank" rel="noopener">A next generation open source platform as a service (PaaS)</a>, stars: 4143</li><li>groupcache: <a href="https://github.com/golang/groupcache" target="_blank" rel="noopener">groupcache is a caching and cache-filling library, intended as a replacement for memcached in many cases.</a>, stars: 4105</li></ul><h2 id="JavaScript语言排行"><a href="#JavaScript语言排行" class="headerlink" title="JavaScript语言排行"></a>JavaScript语言排行</h2><ul><li>FreeCodeCamp: <a href="https://github.com/FreeCodeCamp/FreeCodeCamp" target="_blank" rel="noopener">The http://FreeCodeCamp.com open source codebase and curriculum. Learn to code and help nonprofits.</a>, stars: 51482</li><li>angular.js: <a href="https://github.com/angular/angular.js" target="_blank" rel="noopener">HTML enhanced for web apps</a>, stars: 45619</li><li>d3: <a href="https://github.com/mbostock/d3" target="_blank" rel="noopener">A JavaScript visualization library for HTML and SVG.</a>, stars: 45030</li><li>jquery: <a href="https://github.com/jquery/jquery" target="_blank" rel="noopener">jQuery JavaScript Library</a>, stars: 37372</li><li>react: <a href="https://github.com/facebook/react" target="_blank" rel="noopener">A declarative, efficient, and flexible JavaScript library for building user interfaces.</a>, stars: 33959</li><li>html5-boilerplate: <a href="https://github.com/h5bp/html5-boilerplate" target="_blank" rel="noopener">A professional front-end template for building fast, robust, and adaptable web apps or sites.</a>, stars: 32280</li><li>meteor: <a href="https://github.com/meteor/meteor" target="_blank" rel="noopener">Meteor, the JavaScript App Platform</a>, stars: 31002</li><li>javascript: <a href="https://github.com/airbnb/javascript" target="_blank" rel="noopener">JavaScript Style Guide</a>, stars: 28096</li><li>impress.js: <a href="https://github.com/impress/impress.js" target="_blank" rel="noopener">It’s a presentation framework based on the power of CSS3 transforms and transitions in modern browsers and inspired by the idea behind prezi.com.</a>, stars: 26178</li><li>reveal.js: <a href="https://github.com/hakimel/reveal.js" target="_blank" rel="noopener">The HTML Presentation Framework</a>, stars: 25512</li><li>react-native: <a href="https://github.com/facebook/react-native" target="_blank" rel="noopener">A framework for building native apps with React.</a>, stars: 24841</li><li>You-Dont-Know-JS: <a href="https://github.com/getify/You-Dont-Know-JS" target="_blank" rel="noopener">A book series on JavaScript. @YDKJS on twitter.</a>, stars: 24667</li><li>brackets: <a href="https://github.com/adobe/brackets" target="_blank" rel="noopener">An open source code editor for the web, written in JavaScript, HTML and CSS.</a>, stars: 24293</li><li>moment: <a href="https://github.com/moment/moment" target="_blank" rel="noopener">Parse, validate, manipulate, and display dates in javascript.</a>, stars: 24026</li><li>backbone: <a href="https://github.com/jashkenas/backbone" target="_blank" rel="noopener">Give your JS App some Backbone with Models, Views, Collections, and Events</a>, stars: 23799</li><li>three.js: <a href="https://github.com/mrdoob/three.js" target="_blank" rel="noopener">JavaScript 3D library.</a>, stars: 22678</li><li>jQuery-File-Upload: <a href="https://github.com/blueimp/jQuery-File-Upload" target="_blank" rel="noopener">File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.</a>, stars: 22331</li><li>express: <a href="https://github.com/strongloop/express" target="_blank" rel="noopener">Fast, unopinionated, minimalist web framework for node.</a>, stars: 22311</li><li>Semantic-UI: <a href="https://github.com/Semantic-Org/Semantic-UI" target="_blank" rel="noopener">Semantic is a UI component framework based around useful principles from natural language.</a>, stars: 22222</li><li>foundation-sites: <a href="https://github.com/zurb/foundation-sites" target="_blank" rel="noopener">The most advanced responsive front-end framework in the world. Quickly create prototypes and production code for sites that work on any kind of device.</a>, stars: 22149</li><li>socket.io: <a href="https://github.com/socketio/socket.io" target="_blank" rel="noopener">Realtime application framework (Node.JS server)</a>, stars: 21919</li><li>ionic: <a href="https://github.com/driftyco/ionic" target="_blank" rel="noopener">Advanced HTML5 mobile development framework and SDK. Build incredible mobile apps with web technologies you already know and love. Best friends with AngularJS.</a>, stars: 21289</li><li>resume.github.com: <a href="https://github.com/resume/resume.github.com" target="_blank" rel="noopener">Resumes generated using the GitHub informations</a>, stars: 20310</li><li>hacker-scripts: <a href="https://github.com/NARKOZ/hacker-scripts" target="_blank" rel="noopener">Based on a true story</a>, stars: 19866</li><li>node: <a href="https://github.com/nodejs/node" target="_blank" rel="noopener">Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:</a>, stars: 18774</li><li>gulp: <a href="https://github.com/gulpjs/gulp" target="_blank" rel="noopener">The streaming build system</a>, stars: 18427</li><li>Ghost: <a href="https://github.com/TryGhost/Ghost" target="_blank" rel="noopener">Just a blogging platform</a>, stars: 18023</li><li>Chart.js: <a href="https://github.com/nnnick/Chart.js" target="_blank" rel="noopener">Simple HTML5 Charts using the <canvas> tag</canvas></a>, stars: 17621</li><li>Modernizr: <a href="https://github.com/Modernizr/Modernizr" target="_blank" rel="noopener">Modernizr is a JavaScript library that detects HTML5 and CSS3 features in the user’s browser.</a>, stars: 16991</li><li>underscore: <a href="https://github.com/jashkenas/underscore" target="_blank" rel="noopener">JavaScript’s utility _ belt</a>, stars: 16882</li></ul><h2 id="Scala语言排行"><a href="#Scala语言排行" class="headerlink" title="Scala语言排行"></a>Scala语言排行</h2><ul><li>PredictionIO: <a href="https://github.com/PredictionIO/PredictionIO" target="_blank" rel="noopener">PredictionIO, a machine learning server for developers and ML engineers. Built on Apache Spark, HBase and Spray.</a>, stars: 8292</li><li>playframework: <a href="https://github.com/playframework/playframework" target="_blank" rel="noopener">Play Framework</a>, stars: 7239</li><li>spark: <a href="https://github.com/apache/spark" target="_blank" rel="noopener">Mirror of Apache Spark</a>, stars: 6771</li><li>scala: <a href="https://github.com/scala/scala" target="_blank" rel="noopener">The Scala programming language</a>, stars: 5377</li><li>gitbucket: <a href="https://github.com/gitbucket/gitbucket" target="_blank" rel="noopener">A GitHub clone powered by Scala which has easy installation and high extensibility</a>, stars: 5027</li><li>akka: <a href="https://github.com/akka/akka" target="_blank" rel="noopener">Akka Project</a>, stars: 4902</li><li>ArnoldC: <a href="https://github.com/lhartikk/ArnoldC" target="_blank" rel="noopener">Arnold Schwarzenegger based programming language</a>, stars: 4245</li><li>finagle: <a href="https://github.com/twitter/finagle" target="_blank" rel="noopener">A fault tolerant, protocol-agnostic RPC system</a>, stars: 4135</li><li>zipkin: <a href="https://github.com/openzipkin/zipkin" target="_blank" rel="noopener">Zipkin is a distributed tracing system</a>, stars: 2941</li><li>kestrel: <a href="https://github.com/twitter-archive/kestrel" target="_blank" rel="noopener">simple, distributed message queue system (inactive)</a>, stars: 2721</li><li>flockdb: <a href="https://github.com/twitter/flockdb" target="_blank" rel="noopener">A distributed, fault-tolerant graph database</a>, stars: 2709</li><li>sbt: <a href="https://github.com/sbt/sbt" target="_blank" rel="noopener">sbt, a build tool for Scala</a>, stars: 2454</li><li>snowplow: <a href="https://github.com/snowplow/snowplow" target="_blank" rel="noopener">Enterprise-strength web, mobile and event analytics, powered by Hadoop, Kinesis, Redshift and Elasticsearch</a>, stars: 2416</li><li>diffy: <a href="https://github.com/twitter/diffy" target="_blank" rel="noopener">Find potential bugs in your services with Diffy</a>, stars: 2399</li><li>scalding: <a href="https://github.com/twitter/scalding" target="_blank" rel="noopener">A Scala API for Cascading</a>, stars: 2381</li><li>snowflake: <a href="https://github.com/twitter/snowflake" target="_blank" rel="noopener">Snowflake is a network service for generating unique ID numbers at high scale with some simple guarantees.</a>, stars: 2294</li><li>scalaz: <a href="https://github.com/scalaz/scalaz" target="_blank" rel="noopener">An extension to the core Scala library for functional programming.</a>, stars: 2275</li><li>gatling: <a href="https://github.com/gatling/gatling" target="_blank" rel="noopener">Async Scala-Akka-Netty based Load Test Tool</a>, stars: 2195</li><li>spray: <a href="https://github.com/spray/spray" target="_blank" rel="noopener">A suite of scala libraries for building and consuming RESTful web services on top of Akka: lightweight, asynchronous, non-blocking, actor-based, testable</a>, stars: 2183</li><li>marathon: <a href="https://github.com/mesosphere/marathon" target="_blank" rel="noopener">Deploy and manage containers (including Docker) on top of Apache Mesos at scale.</a>, stars: 2114</li><li>scala-js: <a href="https://github.com/scala-js/scala-js" target="_blank" rel="noopener">Scala.js, the Scala to JavaScript compiler</a>, stars: 2055</li><li>gizzard: <a href="https://github.com/twitter/gizzard" target="_blank" rel="noopener">A flexible sharding framework for creating eventually-consistent distributed datastores</a>, stars: 2026</li><li>fpinscala: <a href="https://github.com/fpinscala/fpinscala" target="_blank" rel="noopener">Code, exercises, answers, and hints to go along with the book “Functional Programming in Scala”</a>, stars: 1931</li><li>scaloid: <a href="https://github.com/pocorall/scaloid" target="_blank" rel="noopener">Scaloid makes your Android code easy to understand and maintain.</a>, stars: 1847</li><li>scalatra: <a href="https://github.com/scalatra/scalatra" target="_blank" rel="noopener">Tiny Scala high-performance, async web framework, inspired by Sinatra</a>, stars: 1827</li><li>textteaser: <a href="https://github.com/MojoJolo/textteaser" target="_blank" rel="noopener">TextTeaser is an automatic summarization algorithm.</a>, stars: 1780</li><li>kafka-manager: <a href="https://github.com/yahoo/kafka-manager" target="_blank" rel="noopener">A tool for managing Apache Kafka.</a>, stars: 1714</li><li>bfg-repo-cleaner: <a href="https://github.com/rtyley/bfg-repo-cleaner" target="_blank" rel="noopener">Removes large or troublesome blobs like git-filter-branch does, but faster. And written in Scala</a>, stars: 1681</li><li>lila: <a href="https://github.com/ornicar/lila" target="_blank" rel="noopener">The forever free, adless and open source chess server.</a>, stars: 1666</li><li>summingbird: <a href="https://github.com/twitter/summingbird" target="_blank" rel="noopener">Streaming MapReduce with Scalding and Storm</a>, stars: 1660</li></ul><h2 id="Java语言排行"><a href="#Java语言排行" class="headerlink" title="Java语言排行"></a>Java语言排行</h2><ul><li>elasticsearch: <a href="https://github.com/elastic/elasticsearch" target="_blank" rel="noopener">Open Source, Distributed, RESTful Search Engine</a>, stars: 14203</li><li>Android-Universal-Image-Loader: <a href="https://github.com/nostra13/Android-Universal-Image-Loader" target="_blank" rel="noopener">Powerful and flexible library for loading, caching and displaying images on Android.</a>, stars: 11399</li><li>RxJava: <a href="https://github.com/ReactiveX/RxJava" target="_blank" rel="noopener">RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.</a>, stars: 9770</li><li>iosched: <a href="https://github.com/google/iosched" target="_blank" rel="noopener">The Google I/O 2015 Android App</a>, stars: 9570</li><li>java-design-patterns: <a href="https://github.com/iluwatar/java-design-patterns" target="_blank" rel="noopener">Design patterns implemented in Java</a>, stars: 9412</li><li>retrofit: <a href="https://github.com/square/retrofit" target="_blank" rel="noopener">Type-safe HTTP client for Android and Java by Square, Inc.</a>, stars: 8976</li><li>SlidingMenu: <a href="https://github.com/jfeinstein10/SlidingMenu" target="_blank" rel="noopener">An Android library that allows you to easily create applications with slide-in menus. You may use it in your Android apps provided that you cite this project and include the license in your app. Thanks!</a>, stars: 8759</li><li>storm: <a href="https://github.com/nathanmarz/storm" target="_blank" rel="noopener">Distributed and fault-tolerant realtime computation: stream processing, continuous computation, distributed RPC, and more</a>, stars: 8746</li><li>picasso: <a href="https://github.com/square/picasso" target="_blank" rel="noopener">A powerful image downloading and caching library for Android</a>, stars: 8383</li><li>okhttp: <a href="https://github.com/square/okhttp" target="_blank" rel="noopener">An HTTP+SPDY client for Android and Java applications.</a>, stars: 8089</li><li>android-async-http: <a href="https://github.com/loopj/android-async-http" target="_blank" rel="noopener">An Asynchronous HTTP Library for Android</a>, stars: 8006</li><li>libgdx: <a href="https://github.com/libgdx/libgdx" target="_blank" rel="noopener">Desktop/Android/HTML5/iOS Java game development framework</a>, stars: 7668</li><li>EventBus: <a href="https://github.com/greenrobot/EventBus" target="_blank" rel="noopener">Android optimized event bus that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.</a>, stars: 7569</li><li>android-best-practices: <a href="https://github.com/futurice/android-best-practices" target="_blank" rel="noopener">Do’s and Don’ts for Android development, by Futurice developers</a>, stars: 7556</li><li>spring-framework: <a href="https://github.com/spring-projects/spring-framework" target="_blank" rel="noopener">The Spring Framework</a>, stars: 7418</li><li>fresco: <a href="https://github.com/facebook/fresco" target="_blank" rel="noopener">An Android library for managing images and the memory they use.</a>, stars: 7393</li><li>zxing: <a href="https://github.com/zxing/zxing" target="_blank" rel="noopener">Official ZXing (“Zebra Crossing”) project home</a>, stars: 7237</li><li>ActionBarSherlock: <a href="https://github.com/JakeWharton/ActionBarSherlock" target="_blank" rel="noopener">[DEPRECATED] Action bar implementation which uses the native action bar on Android 4.0+ and a custom implementation on pre-4.0 through a single API and theme.</a>, stars: 7160</li><li>leakcanary: <a href="https://github.com/square/leakcanary" target="_blank" rel="noopener">A memory leak detection library for Android and Java.</a>, stars: 6806</li><li>guava: <a href="https://github.com/google/guava" target="_blank" rel="noopener">Google Core Libraries for Java 6+</a>, stars: 6799</li><li>butterknife: <a href="https://github.com/JakeWharton/butterknife" target="_blank" rel="noopener">View “injection” library for Android.</a>, stars: 6729</li><li>androidannotations: <a href="https://github.com/excilys/androidannotations" target="_blank" rel="noopener">Fast Android Development. Easy maintainance.</a>, stars: 6714</li><li>MPAndroidChart: <a href="https://github.com/PhilJay/MPAndroidChart" target="_blank" rel="noopener">A powerful Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, dragging and animations.</a>, stars: 6668</li><li>ViewPagerIndicator: <a href="https://github.com/JakeWharton/ViewPagerIndicator" target="_blank" rel="noopener">Paging indicator widgets compatible with the ViewPager from the Android Support Library and ActionBarSherlock.</a>, stars: 6667</li><li>HomeMirror: <a href="https://github.com/HannahMitt/HomeMirror" target="_blank" rel="noopener">Android application powering the mirror in my house</a>, stars: 6286</li><li>Android-PullToRefresh: <a href="https://github.com/chrisbanes/Android-PullToRefresh" target="_blank" rel="noopener">DEPRECATED</a>, stars: 6151</li><li>glide: <a href="https://github.com/bumptech/glide" target="_blank" rel="noopener">An image loading and caching library for Android focused on smooth scrolling</a>, stars: 6115</li><li>netty: <a href="https://github.com/netty/netty" target="_blank" rel="noopener">Netty project - an event-driven asynchronous network application framework</a>, stars: 5865</li><li>MaterialDesignLibrary: <a href="https://github.com/navasmdc/MaterialDesignLibrary" target="_blank" rel="noopener">This is a library with components of Android L to you use in android 2.2</a>, stars: 5848</li><li>PhotoView: <a href="https://github.com/chrisbanes/PhotoView" target="_blank" rel="noopener">Implementation of ImageView for Android that supports zooming, by various touch gestures.</a>, stars: 5077</li></ul><h2 id="C语言排行"><a href="#C语言排行" class="headerlink" title="C语言排行"></a>C语言排行</h2><ul><li>linux: <a href="https://github.com/torvalds/linux" target="_blank" rel="noopener">Linux kernel source tree</a>, stars: 28635</li><li>redis: <a href="https://github.com/antirez/redis" target="_blank" rel="noopener">Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes, HyperLogLogs, Bitmaps.</a>, stars: 16124</li><li>git: <a href="https://github.com/git/git" target="_blank" rel="noopener">Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.</a>, stars: 11343</li><li>How-to-Make-a-Computer-Operating-System: <a href="https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System" target="_blank" rel="noopener">How to Make a Computer Operating System in C++</a>, stars: 9704</li><li>emscripten: <a href="https://github.com/kripken/emscripten" target="_blank" rel="noopener">Emscripten: An LLVM-to-JavaScript Compiler</a>, stars: 9374</li><li>php-src: <a href="https://github.com/php/php-src" target="_blank" rel="noopener">The PHP Interpreter</a>, stars: 8394</li><li>the_silver_searcher: <a href="https://github.com/ggreer/the_silver_searcher" target="_blank" rel="noopener">A code-searching tool similar to ack, but faster.</a>, stars: 7749</li><li>toxcore: <a href="https://github.com/irungentoo/toxcore" target="_blank" rel="noopener">The future of online communications.</a>, stars: 7574</li><li>The-Art-Of-Programming-By-July: <a href="https://github.com/julycoding/The-Art-Of-Programming-By-July" target="_blank" rel="noopener">本github已于14年6月基本停止更新,完整精致的纸质版《编程之法:面试和算法心得》已在京东/当当上销售!</a>, stars: 7552</li><li>wrk: <a href="https://github.com/wg/wrk" target="_blank" rel="noopener">Modern HTTP benchmarking tool</a>, stars: 7243</li><li>jq: <a href="https://github.com/stedolan/jq" target="_blank" rel="noopener">Command-line JSON processor</a>, stars: 5828</li><li>libgit2: <a href="https://github.com/libgit2/libgit2" target="_blank" rel="noopener">The Library</a>, stars: 5396</li><li>Signal-Android: <a href="https://github.com/WhisperSystems/Signal-Android" target="_blank" rel="noopener">A private messenger for Android.</a>, stars: 5360</li><li>h2o: <a href="https://github.com/h2o/h2o" target="_blank" rel="noopener">H2O - the optimized HTTP/1, HTTP/2 server</a>, stars: 5233</li><li>macvim: <a href="https://github.com/b4winckler/macvim" target="_blank" rel="noopener">Vim - the text editor - for Mac OS X</a>, stars: 5169</li><li>fish-shell: <a href="https://github.com/fish-shell/fish-shell" target="_blank" rel="noopener">The user-friendly command line shell.</a>, stars: 5137</li><li>firefox-ios: <a href="https://github.com/mozilla/firefox-ios" target="_blank" rel="noopener">Firefox for iOS</a>, stars: 5136</li><li>ccv: <a href="https://github.com/liuliu/ccv" target="_blank" rel="noopener">C-based/Cached/Core Computer Vision Library, A Modern Computer Vision Library</a>, stars: 4954</li><li>godot: <a href="https://github.com/godotengine/godot" target="_blank" rel="noopener">Godot Game Engine</a>, stars: 4943</li><li>twemproxy: <a href="https://github.com/twitter/twemproxy" target="_blank" rel="noopener">A fast, light-weight proxy for memcached and redis</a>, stars: 4870</li><li>WinObjC: <a href="https://github.com/Microsoft/WinObjC" target="_blank" rel="noopener">Objective-C for Windows</a>, stars: 4844</li><li>mjolnir: <a href="https://github.com/sdegutis/mjolnir" target="_blank" rel="noopener">Lightweight automation and productivity app for OS X</a>, stars: 4760</li><li>robotjs: <a href="https://github.com/octalmage/robotjs" target="_blank" rel="noopener">Node.js Desktop Automation. </a>, stars: 4501</li><li>memcached: <a href="https://github.com/memcached/memcached" target="_blank" rel="noopener">memcached development tree</a>, stars: 4184</li><li>Telegram: <a href="https://github.com/DrKLO/Telegram" target="_blank" rel="noopener">Telegram for Android source</a>, stars: 4138</li><li>disque: <a href="https://github.com/antirez/disque" target="_blank" rel="noopener">Disque is a distributed message broker</a>, stars: 4076</li><li>masscan: <a href="https://github.com/robertdavidgraham/masscan" target="_blank" rel="noopener">TCP port scanner, spews SYN packets asynchronously, scanning entire Internet in under 5 minutes.</a>, stars: 4017</li><li>grpc: <a href="https://github.com/grpc/grpc" target="_blank" rel="noopener">The C based gRPC (C++, Node.js, Python, Ruby, Objective-C, PHP, C#)</a>, stars: 3895</li><li>tengine: <a href="https://github.com/alibaba/tengine" target="_blank" rel="noopener">A distribution of Nginx with some advanced features</a>, stars: 3766</li><li>streem: <a href="https://github.com/matz/streem" target="_blank" rel="noopener">prototype of stream based programming language</a>, stars: 3742</li></ul>]]></content>
<summary type="html">
Github语言排行
</summary>
<category term="github" scheme="http://irusist.github.io/categories/github/"/>
<category term="github" scheme="http://irusist.github.io/tags/github/"/>
<category term="语言" scheme="http://irusist.github.io/tags/%E8%AF%AD%E8%A8%80/"/>
</entry>
<entry>
<title>Java的一些内存泄露</title>
<link href="http://irusist.github.io/2017/11/27/Java%E7%9A%84%E4%B8%80%E4%BA%9B%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2/"/>
<id>http://irusist.github.io/2017/11/27/Java的一些内存泄露/</id>
<published>2017-11-26T16:00:00.000Z</published>
<updated>2017-12-23T10:18:54.000Z</updated>
<content type="html"><![CDATA[<p>最近有个后台项目开发环境报OOM, 最后利用mat分析出具体原因是,在开发环境,开发人员为了方便,用jboss的热部署来部署更新完的war包,重新部署后,会reload spring的容器类,但是有的类实例不能被卸载,导致有多个实例,之前存在的实例的定时任务一直在执行,最后导致OOM。 于是分析了具体不能被卸载的类,主要有以下2种情况:</p><ul class="org-ul"><li>存在定时任务没有被停止,造成有活跃的Thread,由于被根对象引用,造成不能被回收</li><li>实例被静态单例的类实例引用,如果要回收这个实例,必须回收Class对象,但是Class对象ClassLoader引用,而ClassLoader不能被回收的话,造成静态实例不能被回收。</li></ul><a id="more"></a><p>以下用测试程序说明下:</p><div id="outline-container-sec-1" class="outline-2"><h2 id="sec-1">定时任务没有被停止</h2><div class="outline-text-2" id="text-1"></div><div id="outline-container-sec-1-1" class="outline-3"><h3 id="sec-1-1">修改之前</h3><div class="outline-text-3" id="text-1-1"><p>类对象</p><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="annotation">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TimerLeak</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> Timer timer = <span class="keyword">new</span> Timer();</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">TimerLeak</span><span class="params">()</span> </span>{</span><br><span class="line">timer.schedule(<span class="keyword">new</span> TimerTask() {</span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>{</span><br><span class="line"> }</span><br><span class="line">}, <span class="number">0</span>, <span class="number">5000</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p>加载Spring Bean并reload</p><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line">ClassPathXmlApplicationContext ctx = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"appContext.xml"</span>);</span><br><span class="line">ctx.getBean(<span class="string">"timerLeak"</span>);</span><br><span class="line">ctx.refresh();</span><br><span class="line">Thread.currentThread().join();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p>mat分析dump得到如下</p><div class="figure"><p><img src="TimerLeakBefore.png" alt="TimerLeakBefore.png"></p></div><p>查看被哪个根路径引用</p><div class="figure"><p><img src="TimerLeakBeforeRootPath.png" alt="TimerLeakBeforeRootPath.png"></p></div></div></div><div id="outline-container-sec-1-2" class="outline-3"><h3 id="sec-1-2">修改之后</h3><div class="outline-text-3" id="text-1-2"><p>类对象</p><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="annotation">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TimerLeak</span> <span class="keyword">implements</span> <span class="title">DisposableBean</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> Timer timer = <span class="keyword">new</span> Timer();</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">TimerLeak</span><span class="params">()</span> </span>{</span><br><span class="line">timer.schedule(<span class="keyword">new</span> TimerTask() {</span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>{</span><br><span class="line"> }</span><br><span class="line">}, <span class="number">0</span>, <span class="number">5000</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">destroy</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line">timer.cancel();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p>mat分析dump得到如下</p><div class="figure"><p><img src="TimerLeakAfter.png" alt="TimerLeakAfter.png"></p></div></div></div></div><div id="outline-container-sec-2" class="outline-2"><h2 id="sec-2">静态类实例引用</h2><div class="outline-text-2" id="text-2"></div><div id="outline-container-sec-2-1" class="outline-3"><h3 id="sec-2-1">修改之前</h3><div class="outline-text-3" id="text-2-1"><p>类对象</p><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="annotation">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StaticContainerLeak</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="keyword">return</span> <span class="string">"test"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StaticContainer</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Map<String, StaticContainerLeak> map = <span class="keyword">new</span> HashMap<>();</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">addData</span><span class="params">(StaticContainerLeak containerLeak)</span> </span>{</span><br><span class="line">map.put(containerLeak.getName(), containerLeak);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p>reload spring的类</p><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line">ClassPathXmlApplicationContext ctx = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"appContext.xml"</span>);</span><br><span class="line">StaticContainer.addData(ctx.getBean(<span class="string">"staticContainerLeak"</span>, StaticContainerLeak.class));</span><br><span class="line">ctx.refresh();</span><br><span class="line">Thread.currentThread().join();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p>mat分析dump得到如下</p><div class="figure"><p><img src="StaticContainerLeakBefore.png" alt="StaticContainerLeakBefore.png"></p></div><p>查看被哪个根路径引用</p><div class="figure"><p><img src="StaticContainerLeakBeforeRootPath.png" alt="StaticContainerLeakBeforeRootPath.png"></p></div></div></div><div id="outline-container-sec-2-2" class="outline-3"><h3 id="sec-2-2">修改之后</h3><div class="outline-text-3" id="text-2-2"><p>类对象</p><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StaticContainer</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Map<String, StaticContainerLeak> map = <span class="keyword">new</span> HashMap<>();</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">addData</span><span class="params">(StaticContainerLeak containerLeak)</span> </span>{</span><br><span class="line">map.put(containerLeak.getName(), containerLeak);</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">clear</span><span class="params">()</span> </span>{</span><br><span class="line">map.clear();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><div class="org-src-container"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="annotation">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringContextDestory</span> <span class="keyword">implements</span> <span class="title">DisposableBean</span> </span>{</span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">destroy</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line">StaticContainer.clear();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p>mat分析dump得到如下</p><div class="figure"><p><img src="StaticContainerLeakAfter.png" alt="StaticContainerLeakAfter.png"></p></div><p>因此在开发时,尤其是中间件等框架,要注意:</p><ul class="org-ul"><li>对象销毁时需要停止定时任务, 以及设置相关变量的值</li><li>对引用外部实例的API,尤其注意要销毁清除</li></ul></div></div></div>]]></content>
<summary type="html">
<p>
最近有个后台项目开发环境报OOM, 最后利用mat分析出具体原因是,在开发环境,开发人员为了方便,用jboss的热部署来部署更新完的war包,重新部署后,会reload spring的容器类,
但是有的类实例不能被卸载,导致有多个实例,之前存在的实例的定时任务一直在执行,最后导致OOM。 于是分析了具体不能被卸载的类,主要有以下2种情况:
</p>
<ul class="org-ul">
<li>存在定时任务没有被停止,造成有活跃的Thread,由于被根对象引用,造成不能被回收
</li>
<li>实例被静态单例的类实例引用,如果要回收这个实例,必须回收Class对象,但是Class对象ClassLoader引用,而ClassLoader不能被回收的话,造成静态实例不能被回收。
</li>
</ul>
</summary>
<category term="Java" scheme="http://irusist.github.io/categories/Java/"/>
<category term="Java mat" scheme="http://irusist.github.io/tags/Java-mat/"/>
</entry>
<entry>
<title>我的投资记录</title>
<link href="http://irusist.github.io/2017/11/11/%E6%88%91%E7%9A%84%E6%8A%95%E8%B5%84%E8%AE%B0%E5%BD%95/"/>
<id>http://irusist.github.io/2017/11/11/我的投资记录/</id>
<published>2017-11-10T16:00:00.000Z</published>
<updated>2018-01-20T04:16:53.000Z</updated>
<content type="html"><![CDATA[<p>今年6月份开始接触投资,发现一片新的广阔天地,不断学习中,将以后投资的情况记录到这里</p><a id="more"></a><div id="outline-container-sec-1" class="outline-2"><h2 id="sec-1">定投</h2><div class="outline-text-2" id="text-1"><p>以下是刚开始不懂,看网上说定投300,500,创业板指数, 就做的一些定投</p></div><div id="outline-container-sec-1-1" class="outline-3"><h3 id="sec-1-1">沪深300</h3><div class="outline-text-3" id="text-1-1"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">前一天pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-06-01</td><td class="right">000961</td><td class="left">天弘沪深300指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.0135</td><td class="right">88.71</td><td class="right">0.09</td><td class="right">90</td><td class="right">22.06</td><td class="right">49.09%</td><td class="left"> </td></tr><tr><td class="right">2017-06-08</td><td class="right">110020</td><td class="left">易方达沪深300指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.1843</td><td class="right">151.80</td><td class="right">0.22</td><td class="right">180</td><td class="right">22.28</td><td class="right">50.45%</td><td class="left"> </td></tr><tr><td class="right">2017-06-15</td><td class="right">110020</td><td class="left">易方达沪深300指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.1773</td><td class="right">152.71</td><td class="right">0.22</td><td class="right">180</td><td class="right">21.73</td><td class="right">47.99%</td><td class="left"> </td></tr><tr><td class="right">2017-06-22</td><td class="right">110020</td><td class="left">易方达沪深300指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.1984</td><td class="right">150.02</td><td class="right">0.22</td><td class="right">180</td><td class="right">21.95</td><td class="right">48.80%</td><td class="left"> </td></tr><tr><td class="right">2017-06-29</td><td class="right">110020</td><td class="left">易方达沪深300指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.2234</td><td class="right">146.95</td><td class="right">0.22</td><td class="right">180</td><td class="right">22.33</td><td class="right">50.82%</td><td class="left"> </td></tr><tr><td class="right">2017-07-06</td><td class="right">110020</td><td class="left">易方达沪深300指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.2231</td><td class="right">146.99</td><td class="right">0.22</td><td class="right">180</td><td class="right">22.40</td><td class="right">51.55%</td><td class="left"> </td></tr></tbody></table></div></div><div id="outline-container-sec-1-2" class="outline-3"><h3 id="sec-1-2">创业板指数</h3><div class="outline-text-3" id="text-1-2"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">前一天pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-06-01</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.6890</td><td class="right">260.99</td><td class="right">0.18</td><td class="right">180</td><td class="right">44.46</td><td class="right">24.40%</td><td class="left"> </td></tr><tr><td class="right">2017-06-08</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7162</td><td class="right">948.51</td><td class="right">0.68</td><td class="right">680</td><td class="right">45.49</td><td class="right">26.85%</td><td class="left"> </td></tr><tr><td class="right">2017-06-15</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7250</td><td class="right">936.99</td><td class="right">0.68</td><td class="right">680</td><td class="right">45.32</td><td class="right">26.54%</td><td class="left"> </td></tr><tr><td class="right">2017-06-22</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7188</td><td class="right">945.08</td><td class="right">0.68</td><td class="right">680</td><td class="right">46.31</td><td class="right">28.62%</td><td class="left"> </td></tr><tr><td class="right">2017-06-29</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7248</td><td class="right">937.25</td><td class="right">0.68</td><td class="right">680</td><td class="right">45.70</td><td class="right">27.26%</td><td class="left"> </td></tr><tr><td class="right">2017-07-06</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7355</td><td class="right">923.62</td><td class="right">0.68</td><td class="right">680</td><td class="right">46.29</td><td class="right">28.92%</td><td class="left"> </td></tr><tr><td class="right">2017-07-11</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7089</td><td class="right">704.61</td><td class="right">0.50</td><td class="right">500</td><td class="right">45.40</td><td class="right">26.67%</td><td class="left"> </td></tr><tr><td class="right">2017-07-11</td><td class="right">001592</td><td class="left">天弘创业板指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7089</td><td class="right">281.85</td><td class="right">0.20</td><td class="right">200</td><td class="right">45.40</td><td class="right">26.67%</td><td class="left"> </td></tr></tbody></table></div></div><div id="outline-container-sec-1-3" class="outline-3"><h3 id="sec-1-3">中证500</h3><div class="outline-text-3" id="text-1-3"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">前一天pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-06-01</td><td class="right">000962</td><td class="left">天弘中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.9312</td><td class="right">171.65</td><td class="right">0.16</td><td class="right">160</td><td class="right">33.25</td><td class="right">39.15%</td><td class="left"> </td></tr><tr><td class="right">2017-06-08</td><td class="right">160119</td><td class="left">南方中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.4655</td><td class="right">122.67</td><td class="right">0.22</td><td class="right">180</td><td class="right">34.02</td><td class="right">40.46%</td><td class="left"> </td></tr><tr><td class="right">2017-06-15</td><td class="right">160119</td><td class="left">南方中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.4815</td><td class="right">121.35</td><td class="right">0.22</td><td class="right">180</td><td class="right">33.65</td><td class="right">40.10%</td><td class="left"> </td></tr><tr><td class="right">2017-06-22</td><td class="right">160119</td><td class="left">南方中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.4760</td><td class="right">121.80</td><td class="right">0.22</td><td class="right">180</td><td class="right">34.19</td><td class="right">41.05%</td><td class="left"> </td></tr><tr><td class="right">2017-06-29</td><td class="right">160119</td><td class="left">南方中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.5054</td><td class="right">119.42</td><td class="right">0.22</td><td class="right">180</td><td class="right">34.25</td><td class="right">41.32%</td><td class="left"> </td></tr><tr><td class="right">2017-07-06</td><td class="right">160119</td><td class="left">南方中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.5254</td><td class="right">117.86</td><td class="right">0.22</td><td class="right">180</td><td class="right">34.80</td><td class="right">42.81%</td><td class="left"> </td></tr><tr><td class="right">2017-07-11</td><td class="right">160119</td><td class="left">南方中证500指数</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.5090</td><td class="right">198.57</td><td class="right">0.36</td><td class="right">300</td><td class="right">34.84</td><td class="right">42.88%</td><td class="left"> </td></tr></tbody></table></div></div><div id="outline-container-sec-1-4" class="outline-3"><h3 id="sec-1-4">养老产业</h3><div class="outline-text-3" id="text-1-4"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">前一天pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-07-17</td><td class="right">000968</td><td class="left">广发中证养老产业指数A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.9987</td><td class="right">1800.18</td><td class="right">2.16</td><td class="right">1800</td><td class="right">33.97</td><td class="right">44.93%</td><td class="left"> </td></tr></tbody></table></div></div><div id="outline-container-sec-1-5" class="outline-3"><h3 id="sec-1-5">全指医药</h3><div class="outline-text-3" id="text-1-5"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">前一天pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-08-02</td><td class="right">001180</td><td class="left">广发中证医药卫生ETF联接A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.7825</td><td class="right">3191.05</td><td class="right">3.00</td><td class="right">2500</td><td class="right">41.80</td><td class="right">40.22%</td><td class="left"> </td></tr></tbody></table></div></div><div id="outline-container-sec-1-6" class="outline-3"><h3 id="sec-1-6">中证500</h3><div class="outline-text-3" id="text-1-6"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">前一天pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-10-27</td><td class="right">000478</td><td class="left">建信中证500指数增强</td><td class="left">场外</td><td class="left">买入</td><td class="right">2.5004</td><td class="right">1118.15</td><td class="right">4.19</td><td class="right">2800</td><td class="right">33.80</td><td class="right">39.09%</td><td class="left"> </td></tr><tr><td class="right">2017-10-27</td><td class="right">510500</td><td class="left">500ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">6.980</td><td class="right">300</td><td class="right">0.42</td><td class="right">2094.42</td><td class="right">33.80</td><td class="right">39.09%</td><td class="left"> </td></tr></tbody></table></div></div></div><div id="outline-container-sec-2" class="outline-2"><h2 id="sec-2">中证环保</h2><div class="outline-text-2" id="text-2"></div><div id="outline-container-sec-2-1" class="outline-3"><h3 id="sec-2-1">长线</h3><div class="outline-text-3" id="text-2-1"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入金额</td><td class="right">总金额</td><td class="right">总份数</td><td class="right">投入成本</td><td class="left">下期买入成本</td><td class="left">目前市值</td><td class="left">下期平衡日期</td><td class="left">下期期望市值</td><td class="right">pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-09-25</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">1.042</td><td class="right">2000</td><td class="right">0.42</td><td class="right">2084.42</td><td class="right">2084.42</td><td class="right">2000</td><td class="right">1.042</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">34.19</td><td class="right">16.30%</td><td class="left">1份</td></tr><tr><td class="right">2017-09-25</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">1.041</td><td class="right">2800</td><td class="right">0.58</td><td class="right">2915.38</td><td class="right">4999.80</td><td class="right">4800</td><td class="right">1.042</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">34.19</td><td class="right">16.30%</td><td class="left">2份</td></tr><tr><td class="right">2017-09-25</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">1.038</td><td class="right">4800</td><td class="right">1.00</td><td class="right">4983.40</td><td class="right">9983.20</td><td class="right">9600</td><td class="right">1.040</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">34.19</td><td class="right">16.30%</td><td class="left">3份</td></tr><tr><td class="right">2017-12-05</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">0.990</td><td class="right">2500</td><td class="right">0.50</td><td class="right">2475.50</td><td class="right">12458.70</td><td class="right">12100</td><td class="right">1.030</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">30.29</td><td class="right">0.40%</td><td class="left">4份</td></tr><tr><td class="right">2018-01-15</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">0.977</td><td class="right">6100</td><td class="right">1.19</td><td class="right">5960.89</td><td class="right">18419.59</td><td class="right">18200</td><td class="right">1.012</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">30.24</td><td class="right">0.47%</td><td class="left">6份</td></tr><tr><td class="right">2018-01-15</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">0.971</td><td class="right">6200</td><td class="right">1.20</td><td class="right">6021.40</td><td class="right">24440.99</td><td class="right">24400</td><td class="right">1.002</td><td class="left">0.802</td><td class="left">23692.40</td><td class="left">2018-02-14</td><td class="left">24166.25</td><td class="right">30.24</td><td class="right">0.47%</td><td class="left">8份</td></tr></tbody></table></div></div><div id="outline-container-sec-2-2" class="outline-3"><h3 id="sec-2-2">网格</h3><div class="outline-text-3" id="text-2-2"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">阶段</td><td class="right">价格</td><td class="left">类型</td></tr><tr><td class="right">初始</td><td class="right">1.120</td><td class="left"> </td></tr><tr><td class="right">0.95</td><td class="right">1.064</td><td class="left">小网</td></tr><tr><td class="right">0.90</td><td class="right">1.008</td><td class="left">小网</td></tr><tr><td class="right">0.85</td><td class="right">0.952</td><td class="left">小网,中网</td></tr><tr><td class="right">0.80</td><td class="right">0.896</td><td class="left">小网</td></tr><tr><td class="right">0.75</td><td class="right">0.840</td><td class="left">小网</td></tr><tr><td class="right">0.70</td><td class="right">0.784</td><td class="left">小网,中网,大网</td></tr></tbody></table><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="right">下次买入点</td><td class="right">下次卖出点</td><td class="left">备注</td></tr><tr><td class="right">2017-10-24</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">1.060</td><td class="right">1900</td><td class="right">0.40</td><td class="right">2014.40</td><td class="right">1.008</td><td class="right">1.120</td><td class="left">当成1.064买的</td></tr><tr><td class="right">2017-11-01</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">1.067</td><td class="right">3100</td><td class="right">0.66</td><td class="right">3308.36</td><td class="right">1.008</td><td class="right">1.120</td><td class="left">当成1.064买的</td></tr><tr><td class="right">2017-11-06</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">1.041</td><td class="right">4800</td><td class="right">1.00</td><td class="right">4997.80</td><td class="right">1.008</td><td class="right">1.120</td><td class="left">当成1.064买的</td></tr><tr><td class="right">2018-01-15</td><td class="right">512580</td><td class="left">环保ETF</td><td class="left">场内</td><td class="left">买入</td><td class="right">0.982</td><td class="right">6100</td><td class="right">1.20</td><td class="right">5991.40</td><td class="right">0.952</td><td class="right">1.064</td><td class="left">当成1.008买的</td></tr></tbody></table></div></div></div><div id="outline-container-sec-3" class="outline-2"><h2 id="sec-3">全指医药</h2><div class="outline-text-2" id="text-3"></div><div id="outline-container-sec-3-1" class="outline-3"><h3 id="sec-3-1">长线</h3><div class="outline-text-3" id="text-3-1"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="left"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入金额</td><td class="left">总金额</td><td class="left">总份数</td><td class="left">投入成本</td><td class="left">下期买入成本</td><td class="left">目前市值</td><td class="left">下期平衡日期</td><td class="left">下期期望市值</td><td class="right">pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2018-01-03</td><td class="right">001180</td><td class="left">广发中证全指医药卫生ETF联接A</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.8585</td><td class="right">3490.27</td><td class="right">3.60</td><td class="right">3000</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">39.35</td><td class="right">26.95%</td><td class="left"> </td></tr></tbody></table></div></div></div><div id="outline-container-sec-4" class="outline-2"><h2 id="sec-4">养老产业</h2><div class="outline-text-2" id="text-4"></div><div id="outline-container-sec-4-1" class="outline-3"><h3 id="sec-4-1">长线</h3><div class="outline-text-3" id="text-4-1"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入金额</td><td class="right">总金额</td><td class="right">总份数</td><td class="right">投入成本</td><td class="left">下期买入成本</td><td class="left">目前市值</td><td class="left">下期平衡日期</td><td class="left">下期期望市值</td><td class="right">pe</td><td class="right">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2018-01-03</td><td class="right">000968</td><td class="left">广发中证养老产业A</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.0938</td><td class="right">2739.44</td><td class="right">3.60</td><td class="right">3000</td><td class="right">3000</td><td class="right">2739.44</td><td class="right">1.095</td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="left"> </td><td class="right">31.29</td><td class="right">23.63%</td><td class="left">1份</td></tr></tbody></table></div></div></div><div id="outline-container-sec-5" class="outline-2"><h2 id="sec-5">商品</h2><div class="outline-text-2" id="text-5"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="left">前一天pe</td><td class="left">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-08-15</td><td class="right">162411</td><td class="left">华宝兴业油气</td><td class="left">场外</td><td class="left">买入</td><td class="right">0.5020</td><td class="right">1989.04</td><td class="right">1.50</td><td class="right">1000</td><td class="left"> </td><td class="left"> </td><td class="left"> </td></tr></tbody></table></div></div><div id="outline-container-sec-6" class="outline-2"><h2 id="sec-6">债券</h2><div class="outline-text-2" id="text-6"><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"><colgroup><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"><col class="right"><col class="right"><col class="right"><col class="right"><col class="left"><col class="left"><col class="left"></colgroup><tbody><tr><td class="right">时间</td><td class="right">标的编码</td><td class="left">标的名称</td><td class="left">类型</td><td class="left">买入或卖出</td><td class="right">单价</td><td class="right">数量</td><td class="right">手续费</td><td class="right">投入成本</td><td class="left">前一天pe</td><td class="left">pe百分位</td><td class="left">备注</td></tr><tr><td class="right">2017-09-15</td><td class="right">001061</td><td class="left">华夏海外收益债券A</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.2170</td><td class="right">3284.14</td><td class="right">3.20</td><td class="right">4000</td><td class="left"> </td><td class="left"> </td><td class="left"> </td></tr><tr><td class="right">2017-10-16</td><td class="right">050027</td><td class="left">博时信用债纯债债券</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.0720</td><td class="right">2330.22</td><td class="right">2.00</td><td class="right">2500</td><td class="left"> </td><td class="left"> </td><td class="left"> </td></tr><tr><td class="right">2017-10-16</td><td class="right">270048</td><td class="left">广发纯债债券A</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.1890</td><td class="right">2100.93</td><td class="right">2.00</td><td class="right">2500</td><td class="left"> </td><td class="left"> </td><td class="left"> </td></tr><tr><td class="right">2017-10-27</td><td class="right">270048</td><td class="left">广发纯债债券A</td><td class="left">场外</td><td class="left">买入</td><td class="right">1.1800</td><td class="right">2370.98</td><td class="right">2.24</td><td class="right">2800</td><td class="left"> </td><td class="left"> </td><td class="left"> </td></tr></tbody></table></div></div>]]></content>
<summary type="html">
<p>
今年6月份开始接触投资,发现一片新的广阔天地,不断学习中,将以后投资的情况记录到这里
</p>
</summary>
<category term="投资" scheme="http://irusist.github.io/categories/%E6%8A%95%E8%B5%84/"/>
<category term="投资" scheme="http://irusist.github.io/tags/%E6%8A%95%E8%B5%84/"/>
</entry>
<entry>
<title>quant_blog</title>
<link href="http://irusist.github.io/2017/11/05/quant-blog/"/>
<id>http://irusist.github.io/2017/11/05/quant-blog/</id>
<published>2017-11-04T16:00:00.000Z</published>
<updated>2017-12-23T10:18:54.000Z</updated>
<content type="html"><![CDATA[<ul class="org-ul"><li><a href="http://gaoya.blog.163.com/blog/static/602780662009112393655698/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662009112393655698/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066200911308183225/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066200911308183225/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201002001849158/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201002001849158/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010126503294/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010126503294/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010319375924/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010319375924/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/6027806620104121155906/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/6027806620104121155906/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201042051523782/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201042051523782/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201042610157809/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201042610157809/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010426112530980/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010426112530980/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010426113939806/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010426113939806/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010519365096/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010519365096/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010619383140/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010619383140/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010729324227/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010729324227/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201074113815688/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201074113815688/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/6027806620107179221158/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/6027806620107179221158/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010829347981/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010829347981/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201081312125992/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201081312125992/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201099102513505/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201099102513505/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/6027806620109286594389/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/6027806620109286594389/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201010193750848/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201010193750848/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010101815615626/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010101815615626/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/60278066201010244503431/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/60278066201010244503431/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/602780662010102893937970/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/602780662010102893937970/</a></li><li><a href="http://gaoya.blog.163.com/blog/static/6027806620101119541203/" target="_blank" rel="noopener">http://gaoya.blog.163.com/blog/static/6027806620101119541203/</a></li><li></li></ul>]]></content>
<summary type="html">
<ul class="org-ul">
<li><a href="http://gaoya.blog.163.com/blog/static/602780662009112393655698/" target="_blank" rel="noopener">http://ga
</summary>
<category term="quant" scheme="http://irusist.github.io/categories/quant/"/>
<category term="quant" scheme="http://irusist.github.io/tags/quant/"/>
</entry>
<entry>
<title>hexo使用org-mode</title>
<link href="http://irusist.github.io/2017/11/05/hexo%E4%BD%BF%E7%94%A8org-mode/"/>
<id>http://irusist.github.io/2017/11/05/hexo使用org-mode/</id>
<published>2017-11-04T16:00:00.000Z</published>
<updated>2017-11-15T16:17:26.000Z</updated>
<content type="html"><![CDATA[<p>之前hexo用的一直都是markdown,从今天开始切换到org-mode,以下是安装的一些步骤</p><div id="outline-container-sec-1" class="outline-2"><h2 id="sec-1">安装</h2><div class="outline-text-2" id="text-1"><div class="org-src-container"><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g hexo-cli --registry=https://registry.npm.taobao.org --proxy http://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">1080</span></span><br></pre></td></tr></table></figure></div><ul class="org-ul"><li>registry指定镜像</li><li>proxy指定代理</li></ul><a id="more"></a></div></div><div id="outline-container-sec-2" class="outline-2"><h2 id="sec-2">配置</h2><div class="outline-text-2" id="text-2"><div class="org-src-container"><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hexo init blog-source</span><br><span class="line"><span class="built_in">cd</span> blog-source</span><br><span class="line">npm install --registry=https://registry.npm.taobao.org --proxy http://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">1080</span></span><br></pre></td></tr></table></figure></div></div></div><div id="outline-container-sec-3" class="outline-2"><h2 id="sec-3">主题</h2><div class="outline-text-2" id="text-3"><div class="org-src-container"><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/litten/hexo-theme-yilia.git themes/yilia</span><br></pre></td></tr></table></figure></div><p>修改hexo根目录下的 _config.yml : theme: yilia</p></div></div><div id="outline-container-sec-4" class="outline-2"><h2 id="sec-4">org-mode</h2><div class="outline-text-2" id="text-4"><div class="org-src-container"><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install https://github.com/CodeFalling/hexo-renderer-org<span class="comment">#emacs --save</span></span><br></pre></td></tr></table></figure></div><p>在 _config.yml 添加以下内容</p><div class="org-src-container"><figure class="highlight"><table><tr><td class="code"><pre><span class="line">org: emacs: 'D:\soft\emacs-25.1-x86_64-w64-mingw32\bin\emacs.exe' common: | 	#+OPTIONS: toc:nil num:nil</span><br></pre></td></tr></table></figure></div><p>在 _config.yml 的 new_post_name 修改为org文件名</p></div></div>]]></content>
<summary type="html">
<p>
之前hexo用的一直都是markdown,从今天开始切换到org-mode,以下是安装的一些步骤
</p>
<div id="outline-container-sec-1" class="outline-2">
<h2 id="sec-1">安装</h2>
<div class="outline-text-2" id="text-1">
<div class="org-src-container">
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g hexo-cli --registry=https://registry.npm.taobao.org --proxy http://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">1080</span></span><br></pre></td></tr></table></figure>
</div>
<ul class="org-ul">
<li>registry指定镜像
</li>
<li>proxy指定代理
</li>
</ul>
</summary>
<category term="hexo" scheme="http://irusist.github.io/categories/hexo/"/>
<category term="hexo orgmode" scheme="http://irusist.github.io/tags/hexo-orgmode/"/>
</entry>
<entry>
<title>Play的Response处理</title>
<link href="http://irusist.github.io/2016/01/17/Play%E7%9A%84Response%E5%A4%84%E7%90%86/"/>
<id>http://irusist.github.io/2016/01/17/Play的Response处理/</id>
<published>2016-01-17T05:22:54.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>默认情况下,不需要指定<code>Content-Length</code>这个响应头,Play框架会根据响应内容自动计算出来,如<br><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">normal</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"Hello, Response"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>会自动生成如下的响应头</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Content-Length:15</span><br><span class="line">Content-Type:text/plain; charset=utf-8</span><br><span class="line">Date:Sun, 17 Jan 2016 05:26:14 GMT</span><br></pre></td></tr></table></figure><a id="more"></a><p>可以使用<code>play.api.libs.iteratee.Enumerator</code>来生成响应内容,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">normal</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Result</span>(</span><br><span class="line"> header = <span class="type">ResponseHeader</span>(<span class="number">200</span>),</span><br><span class="line"> body = <span class="type">Enumerator</span>(<span class="string">"Hello, Enumerator"</span>.getBytes())</span><br><span class="line"> )</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这时也会生成<code>Content-Length</code>响应头,如下</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Content-Length:17</span><br><span class="line">Date:Sun, 17 Jan 2016 05:31:15 GMT</span><br></pre></td></tr></table></figure><p>在Play框架中,会把所有的相应内容都加载到内存,再计算出响应内容的长度。如果响应内容很多,就会占用很多内容,这时就需要自己来指定<code>Content-Length</code>来解决,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">normal</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="keyword">import</span> play.api.libs.concurrent.<span class="type">Execution</span>.<span class="type">Implicits</span>._</span><br><span class="line"> <span class="keyword">val</span> file = <span class="keyword">new</span> <span class="type">File</span>(<span class="string">"d:\\a.pdf"</span>)</span><br><span class="line"> <span class="type">Result</span>(</span><br><span class="line"> header = <span class="type">ResponseHeader</span>(<span class="number">200</span>, <span class="type">Map</span>(<span class="type">CONTENT_LENGTH</span> -> file.length().toString)),</span><br><span class="line"> body = <span class="type">Enumerator</span>.fromFile(file)</span><br><span class="line"> )</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果要处理文件,可以通过<code>Ok.sendFile</code>方法,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">header</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>.sendFile(content = <span class="keyword">new</span> <span class="type">File</span>(<span class="string">"d:\\a.pdf"</span>))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这时会生成如下的响应头:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Content-Disposition:attachment; filename="a.pdf"</span><br><span class="line">Content-Length:54503</span><br><span class="line">Content-Type:application/pdf</span><br><span class="line">Date:Sun, 17 Jan 2016 05:40:49 GMT</span><br></pre></td></tr></table></figure><p>在浏览器访问时,会自动下载这个文件,文件名为<code>a.pdf</code></p><p>也可以指定其他的下载文件名,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">header</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>.sendFile(content = <span class="keyword">new</span> <span class="type">File</span>(<span class="string">"d:\\a.pdf"</span>), fileName = _ => <span class="string">"custom.pdf"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这时生成的响应头如下:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Content-Disposition:attachment; filename="custom.pdf"</span><br><span class="line">Content-Length:54503</span><br><span class="line">Content-Type:application/pdf</span><br><span class="line">Date:Sun, 17 Jan 2016 05:42:32 GMT</span><br></pre></td></tr></table></figure><p>也可以通过指定<code>inline</code>参数,让浏览器直接打开这个文件,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">header</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>.sendFile(content = <span class="keyword">new</span> <span class="type">File</span>(<span class="string">"d:\\a.pdf"</span>), fileName = _ => <span class="string">"custom.pdf"</span>, inline = <span class="literal">true</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这时生成的响应头如下:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Content-Length:54503</span><br><span class="line">Content-Type:application/pdf</span><br><span class="line">Date:Sun, 17 Jan 2016 05:43:44 GMT</span><br></pre></td></tr></table></figure><p>浏览器会直接显示支持的文件格式的内容。</p><p>在Play中,支持<code>Chunked</code>传输形式,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">chunked</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="keyword">import</span> play.api.libs.concurrent.<span class="type">Execution</span>.<span class="type">Implicits</span>._</span><br><span class="line"> <span class="keyword">val</span> stream = <span class="keyword">new</span> <span class="type">FileInputStream</span>(<span class="string">"d:\\a.pdf"</span>)</span><br><span class="line"> <span class="type">Ok</span>.chunked(<span class="type">Enumerator</span>.fromStream(stream))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>也可以通过<code>Enumerator</code>的<code>apply</code>方法生成chunked的内容,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">chunked</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>.chunked(<span class="type">Enumerator</span>(<span class="string">"Hello"</span>, <span class="string">"World"</span>, <span class="string">"zhulx"</span>).andThen(<span class="type">Enumerator</span>.eof))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在Play中,可以通过chunked机制来实现comet,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">comet</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="keyword">val</span> events = <span class="type">Enumerator</span>(</span><br><span class="line"> <span class="string">""</span><span class="string">"<script>console.log('hello')</script>"</span><span class="string">""</span>,</span><br><span class="line"> <span class="string">""</span><span class="string">"<script>console.log('World')</script>"</span><span class="string">""</span></span><br><span class="line"> )</span><br><span class="line"></span><br><span class="line"> <span class="type">Ok</span>.chunked(events).as(<span class="type">HTML</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这样,在浏览器的控制台就会打印日志。</p><p>可以通过<code>play.api.libs.iteratee.Enumeratee</code>来转换<code>Enumerator</code>对象,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> play.api.libs.concurrent.<span class="type">Execution</span>.<span class="type">Implicits</span>._</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">toCometMessage</span> </span>= <span class="type">Enumeratee</span>.map[<span class="type">String</span>] {</span><br><span class="line"> data => <span class="type">Html</span>( <span class="string">""</span><span class="string">"<script>console.log('"</span><span class="string">""</span> + data + <span class="string">""</span><span class="string">"')</script>"</span><span class="string">""</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">comet</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="keyword">val</span> events = <span class="type">Enumerator</span>(<span class="string">"Hello"</span>, <span class="string">"world"</span>)</span><br><span class="line"> <span class="type">Ok</span>.chunked(events &> toCometMessage)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>也可以使用<code>play.api.libs.Comet</code>帮助类</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">comet</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="keyword">val</span> events = <span class="type">Enumerator</span>(<span class="string">"Hello2"</span>, <span class="string">"World2"</span>)</span><br><span class="line"> <span class="type">Ok</span>.chunked(events &> <span class="type">Comet</span>(<span class="string">"console.log"</span>))</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Play的Response处理
</summary>
<category term="Play" scheme="http://irusist.github.io/categories/Play/"/>
<category term="Play" scheme="http://irusist.github.io/tags/Play/"/>
<category term="Scala" scheme="http://irusist.github.io/tags/Scala/"/>
</entry>
<entry>
<title>ElasticSearch初体验:index的CRUD</title>
<link href="http://irusist.github.io/2016/01/13/ElasticSearch%E5%88%9D%E4%BD%93%E9%AA%8C-index%E7%9A%84CRUD/"/>
<id>http://irusist.github.io/2016/01/13/ElasticSearch初体验-index的CRUD/</id>
<published>2016-01-13T07:41:57.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>最近要使用ElasticSearch, 记录下学习的东西.</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>首先要先安装, 要求JDK7以上, 直接获取安装包</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">// 下在安装包</span><br><span class="line">$ curl -L -O https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.4.tar.gz</span><br><span class="line">// 解压</span><br><span class="line">$ tar xvf elasticsearch-1.7.4.tar.gz</span><br><span class="line">$ <span class="built_in">cd</span> elasticsearch-1.7.4/bin</span><br><span class="line">// 启动, 集群名为 es-test</span><br><span class="line">$ ./elasticsearch --cluster.name es-test</span><br></pre></td></tr></table></figure><a id="more"></a><p>可以通过http请求的rest API来对集群进行操作, 主要可以做以下操作</p><ul><li>检查cluster, node, index的健康度, 状态, 统计信息</li><li>管理cluster, node, index的数据和元数据</li><li>CRUD操作</li><li>执行高级搜索操作,如分页,排序,过滤等等.</li></ul><h2 id="健康检查"><a href="#健康检查" class="headerlink" title="健康检查:"></a>健康检查:</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ curl <span class="string">'localhost:9200/_cat/health?v'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks</span><br><span class="line">1452669619 15:20:19 es-test green 1 1 0 0 0 0 0 0</span><br></pre></td></tr></table></figure><p>其中status表示集群的状态, 有3种状态, green表示一切正常, yellow表示数据是可用的, 但有的replica分片没有创建, red表示有部分数据不可用.</p><h2 id="查询node"><a href="#查询node" class="headerlink" title="查询node:"></a>查询node:</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ curl <span class="string">'localhost:9200/_cat/nodes?v'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">host ip heap.percent ram.percent load node.role master name</span><br><span class="line">localhost.localdomain 127.0.0.1 5 73 0.37 d * Whirlwind</span><br></pre></td></tr></table></figure><h2 id="查询index"><a href="#查询index" class="headerlink" title="查询index"></a>查询index</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ curl <span class="string">'localhost:9200/_cat/indices?v'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">health status index pri rep docs.count docs.deleted store.size pri.store.size</span><br></pre></td></tr></table></figure><h2 id="创建index"><a href="#创建index" class="headerlink" title="创建index"></a>创建index</h2><p>创建名为customer的index</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ curl -XPUT <span class="string">'localhost:9200/customer?pretty'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">{</span><br><span class="line"> <span class="string">"acknowledged"</span> : <span class="literal">true</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>创建完之后再查询</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ curl <span class="string">'localhost:9200/_cat/indices?v'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">health status index pri rep docs.count docs.deleted store.size pri.store.size</span><br><span class="line">yellow open customer 5 1 0 0 575b 575b</span><br></pre></td></tr></table></figure><p>默认创建5个primary分片, 1个replica分片,0个documents.</p><h2 id="创建document"><a href="#创建document" class="headerlink" title="创建document"></a>创建document</h2><p>在customer的index上创建type为external, id为1的document</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">$ curl -XPUT <span class="string">'localhost:9200/customer/external/1?pretty'</span> -d <span class="string">'</span></span><br><span class="line"><span class="string">> {</span></span><br><span class="line"><span class="string">> "name": "John Doe"</span></span><br><span class="line"><span class="string">> }'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">{</span><br><span class="line"> <span class="string">"_index"</span> : <span class="string">"customer"</span>,</span><br><span class="line"> <span class="string">"_type"</span> : <span class="string">"external"</span>,</span><br><span class="line"> <span class="string">"_id"</span> : <span class="string">"1"</span>,</span><br><span class="line"> <span class="string">"_version"</span> : 1,</span><br><span class="line"> <span class="string">"created"</span> : <span class="literal">true</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="查询document"><a href="#查询document" class="headerlink" title="查询document"></a>查询document</h2><p>查询创建的document</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$ curl -XGET <span class="string">'localhost:9200/customer/external/1?pretty'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">{</span><br><span class="line"> <span class="string">"_index"</span> : <span class="string">"customer"</span>,</span><br><span class="line"> <span class="string">"_type"</span> : <span class="string">"external"</span>,</span><br><span class="line"> <span class="string">"_id"</span> : <span class="string">"1"</span>,</span><br><span class="line"> <span class="string">"_version"</span> : 1,</span><br><span class="line"> <span class="string">"found"</span> : <span class="literal">true</span>,</span><br><span class="line"> <span class="string">"_source"</span>:</span><br><span class="line">{</span><br><span class="line"> <span class="string">"name"</span>: <span class="string">"John Doe"</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="删除index"><a href="#删除index" class="headerlink" title="删除index"></a>删除index</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ curl -XDELETE <span class="string">'localhost:9200/customer?pretty'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">{</span><br><span class="line"> <span class="string">"acknowledged"</span> : <span class="literal">true</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>删除之后再查询</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ curl <span class="string">'localhost:9200/_cat/indices?v'</span></span><br><span class="line"></span><br><span class="line">// 返回</span><br><span class="line">health status index pri rep docs.count docs.deleted store.size pri.store.size</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
ElasticSearch初体验:index的CRUD
</summary>
<category term="ElasticSearch" scheme="http://irusist.github.io/categories/ElasticSearch/"/>
<category term="ElasticSearch" scheme="http://irusist.github.io/tags/ElasticSearch/"/>
<category term="NoSQL" scheme="http://irusist.github.io/tags/NoSQL/"/>
</entry>
<entry>
<title>Golang之reflect</title>
<link href="http://irusist.github.io/2016/01/12/Golang%E4%B9%8Breflect/"/>
<id>http://irusist.github.io/2016/01/12/Golang之reflect/</id>
<published>2016-01-12T15:09:37.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Go语言中,使用<code>reflect</code>包可以对类型信息,类型的值进行获取和设置,分别用<code>Type</code>和<code>Value</code>表示。</p><p>可以定义一个类型,并且为类型声明一个方法</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Person <span class="keyword">struct</span> {</span><br><span class="line"> Name <span class="keyword">string</span></span><br><span class="line"> Id <span class="keyword">int32</span></span><br><span class="line"> Age <span class="keyword">int32</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(person Person)</span> <span class="title">Eat</span><span class="params">(food <span class="keyword">string</span>)</span></span> {</span><br><span class="line"> fmt.Println(<span class="string">"eat..."</span>, food)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><a id="more"></a><p><code>TypeOf</code>用于获取<code>Type</code>信息,如</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Type</span></span><br><span class="line">t := reflect.TypeOf(person)</span><br><span class="line"><span class="comment">// output: struct Person 3 1</span></span><br><span class="line">fmt.Println(t.Kind(), t.Name(), t.NumField(), t.NumMethod())</span><br></pre></td></tr></table></figure><p><code>Kind()</code>方法用于表示是哪种类型的,如<code>struct</code>, <code>int</code>, <code>string</code>等。<code>Name</code>方法表示类名,<code>NumField</code>表示字段的个数,<code>NumMethod</code>表示方法的个数。</p><p><code>ValueOf</code>用于获取<code>Value</code>信息,如</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Value</span></span><br><span class="line">v1 := reflect.ValueOf(person)</span><br><span class="line"><span class="comment">// output: struct {zhulx 1 28} 3 1 false</span></span><br><span class="line">fmt.Println(v1.Kind(), v1.Interface(), v1.NumField(), v1.NumMethod(), v1.CanSet())</span><br></pre></td></tr></table></figure><p><code>Interface</code>方法用于获取具体的值,<code>CanSet</code>表示是否可以修改原始类型的值,如果返回false,则不能调用<code>CanXXX()</code>类型的方法用来设置字段的值,也不能调用<code>Call</code>方法用来调用方法。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 指针的Value</span></span><br><span class="line">v2 := reflect.ValueOf(&person)</span><br><span class="line"><span class="comment">// output: ptr &{zhulx 1 28} 3 1 false true</span></span><br><span class="line">fmt.Println(v2.Kind(), v2.Interface(), v2.Elem().NumField(), v2.NumMethod(), v2.CanSet(), v2.Elem().CanSet())</span><br></pre></td></tr></table></figure><p>可以通过传入指针类型对象来对原始对象的字段进行修改,或者调用方法,如</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Field Set</span></span><br><span class="line">v3 := reflect.ValueOf(&person).Elem()</span><br><span class="line">v3.FieldByName(<span class="string">"Age"</span>).SetInt(<span class="number">30</span>)</span><br><span class="line"><span class="comment">// output: 30</span></span><br><span class="line">fmt.Println(person.Age)</span><br></pre></td></tr></table></figure><p>也可以调用<code>Call</code>方法来调用具体某个方法,如</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Method Call</span></span><br><span class="line">v4 := reflect.ValueOf(&person).Elem()</span><br><span class="line"><span class="comment">// output: eat... apple</span></span><br><span class="line">v4.MethodByName(<span class="string">"Eat"</span>).Call([]reflect.Value{reflect.ValueOf(<span class="string">"apple"</span>)})</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Golang之reflect
</summary>
<category term="Go" scheme="http://irusist.github.io/categories/Go/"/>
<category term="Go" scheme="http://irusist.github.io/tags/Go/"/>
</entry>
<entry>
<title>Play框架学习之错误处理</title>
<link href="http://irusist.github.io/2016/01/10/Play%E6%A1%86%E6%9E%B6%E5%AD%A6%E4%B9%A0%E4%B9%8B%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86/"/>
<id>http://irusist.github.io/2016/01/10/Play框架学习之错误处理/</id>
<published>2016-01-10T06:07:50.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Play中,分为2种错误:客户端错误和服务端错误。客户端错误包括不规范的请求头数据,不支持的content type,找不到静态页面等等,服务端错误时会返回一个错误的页面。</p><h2 id="自定义错误处理"><a href="#自定义错误处理" class="headerlink" title="自定义错误处理"></a>自定义错误处理</h2><p>可以在app目录下创建一个名为<code>ErrorHandler</code>的类,实现<code>HttpErrorHandler</code>,注意,必须没有包名,并且类名必须为<code>ErrorHandler</code>,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ErrorHandler</span> <span class="keyword">extends</span> <span class="title">HttpErrorHandler</span> </span>{</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">def</span> <span class="title">onClientError</span></span>(request: <span class="type">RequestHeader</span>, statusCode: <span class="type">Int</span>, message: <span class="type">String</span>) = {</span><br><span class="line"> <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="type">Status</span>(statusCode)(<span class="string">"A client error occurred: "</span> + message)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">def</span> <span class="title">onServerError</span></span>(request: <span class="type">RequestHeader</span>, exception: <span class="type">Throwable</span>) = {</span><br><span class="line"> <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="type">InternalServerError</span>(<span class="string">"A server error occurred: "</span> + exception.getMessage)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 在Action实现中直接抛出异常</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">custom</span></span>() = <span class="type">Action</span> { <span class="keyword">implicit</span> request =></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">RuntimeException</span>(<span class="string">"RuntimeException"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>访问<a href="http://localhost:9000/custom" target="_blank" rel="noopener">http://localhost:9000/custom</a> 时,会返回“A server error occurred: RuntimeException”文本信息。</p><a id="more"></a><p>也可以在其他包中定义其他类名,并且在application.conf中指定,如</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">play.http.errorHandler = "error.CustomErrorHandler"</span><br></pre></td></tr></table></figure><h2 id="继承默认错误处理"><a href="#继承默认错误处理" class="headerlink" title="继承默认错误处理"></a>继承默认错误处理</h2><p>在Play的开发环境中,如果发生服务端错误,会定位出发生错误的代码块,并且提示出来,如果想要使用这种默认的处理机制,又想添加一些自定义的错误处理,则可以继承默认的处理类。</p><p>默认的处理类为<code>DefaultHttpErrorHandler</code>, 可以重写这个类的某些方法,处理一些自定义的方法,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> javax.inject.<span class="type">Inject</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.google.inject.<span class="type">Provider</span></span><br><span class="line"><span class="keyword">import</span> play.api._</span><br><span class="line"><span class="keyword">import</span> play.api.http.<span class="type">DefaultHttpErrorHandler</span></span><br><span class="line"><span class="keyword">import</span> play.api.mvc.{<span class="type">RequestHeader</span>, <span class="type">Results</span>}</span><br><span class="line"><span class="keyword">import</span> play.api.routing.<span class="type">Router</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> scala.concurrent.<span class="type">Future</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ErrorHandler</span> <span class="title">@Inject</span>(<span class="params"></span>)(<span class="params"></span></span></span><br><span class="line"><span class="class"><span class="params"> environment: <span class="type">Environment</span>, configuration: <span class="type">Configuration</span>,</span></span></span><br><span class="line"><span class="class"><span class="params"> sourceMapper: <span class="type">OptionalSourceMapper</span>,</span></span></span><br><span class="line"><span class="class"><span class="params"> router: <span class="type">Provider</span>[<span class="type">Router</span>]</span></span></span><br><span class="line"><span class="class"><span class="params"> </span>) <span class="keyword">extends</span> <span class="title">DefaultHttpErrorHandler</span>(<span class="params">environment, configuration, sourceMapper, router</span>) </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">protected</span> <span class="function"><span class="keyword">def</span> <span class="title">onDevServerError</span></span>(request: <span class="type">RequestHeader</span>, exception: <span class="type">UsefulException</span>) = {</span><br><span class="line"> <span class="type">Logger</span>.info(<span class="string">"server error happens"</span>)</span><br><span class="line"> <span class="keyword">super</span>.onDevServerError(request, exception)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">protected</span> <span class="function"><span class="keyword">def</span> <span class="title">onProdServerError</span></span>(request: <span class="type">RequestHeader</span>, exception: <span class="type">UsefulException</span>) = {</span><br><span class="line"> <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="type">Results</span>.<span class="type">InternalServerError</span>(<span class="string">"A server error occurred: "</span> + exception.getMessage)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">protected</span> <span class="function"><span class="keyword">def</span> <span class="title">onForbidden</span></span>(request: <span class="type">RequestHeader</span>, message: <span class="type">String</span>) = {</span><br><span class="line"> <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="type">Results</span>.<span class="type">Forbidden</span>(<span class="string">"your'are not allowed to access this resource."</span>)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Play框架学习之错误处理
</summary>
<category term="Play" scheme="http://irusist.github.io/categories/Play/"/>
<category term="Play2" scheme="http://irusist.github.io/tags/Play2/"/>
<category term="Play" scheme="http://irusist.github.io/tags/Play/"/>
<category term="Scala" scheme="http://irusist.github.io/tags/Scala/"/>
</entry>
<entry>
<title>Play框架学习之Content negotiation</title>
<link href="http://irusist.github.io/2016/01/10/Play%E6%A1%86%E6%9E%B6%E5%AD%A6%E4%B9%A0%E4%B9%8BContent-negotiation/"/>
<id>http://irusist.github.io/2016/01/10/Play框架学习之Content-negotiation/</id>
<published>2016-01-10T05:42:44.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>内容协商可以通过指定请求头以<code>Accept*</code>形式,对同一个请求地址,可以响应不同的内容。这在对一个服务支持xml或json格式的情况下很有用。</p><h2 id="Language"><a href="#Language" class="headerlink" title="Language"></a>Language</h2><p>在Play中可以通过<code>play.api.mvc.RequestHeader#acceptLanguages</code>方法获取支持的语言类型,它返回一个列表,通过解析请求的<code>Accept-Language</code>请求头,根据他们的quality value进行排序,如<code>zh-CN,zh;q=0.8</code>, 它的quality value为0.8。在Play中有一个隐式转换,转成<code>Lang</code>类型,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">implicit</span> <span class="function"><span class="keyword">def</span> <span class="title">request2lang</span></span>(<span class="keyword">implicit</span> request: <span class="type">RequestHeader</span>): <span class="type">Lang</span> = {</span><br><span class="line"> play.api.<span class="type">Play</span>.maybeApplication.map(app => play.api.i18n.<span class="type">Messages</span>.messagesApiCache(app).preferred(request).lang)</span><br><span class="line"> .getOrElse(request.acceptLanguages.headOption.getOrElse(play.api.i18n.<span class="type">Lang</span>.defaultLang))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>它会找出排序过后列表中第一个支持的语言。</p><a id="more"></a><h2 id="Content"><a href="#Content" class="headerlink" title="Content"></a>Content</h2><p>类似地,<code>play.api.mvc.RequestHeader#acceptedTypes</code>方法会返回请求支持的MIME类型,它是通过解析请求头的<code>Accept</code>参数得到的,并根据quality因子进行排序。可以通过以下的方法来处理:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">custom</span></span>() = <span class="type">Action</span> { <span class="keyword">implicit</span> request =></span><br><span class="line"> render {</span><br><span class="line"> <span class="keyword">case</span> <span class="type">Accepts</span>.<span class="type">Html</span>() => <span class="type">Ok</span>(views.html.index(<span class="string">"html accepts"</span>))</span><br><span class="line"> <span class="keyword">case</span> <span class="type">Accepts</span>.<span class="type">Json</span>() => <span class="type">Ok</span>(<span class="type">Json</span>.toJson(<span class="string">"json accepts"</span>))</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>它解析<code>Accept</code>请求头,如果包含<code>text/html</code>,则返回index页面,如果包含<code>application/json</code>,则返回JSON格式的内容,如果请求头指定的是<code>application/xml</code>, 则会返回<code>val NOT_ACCEPTABLE = 406</code>。</p><h2 id="请求抽取器"><a href="#请求抽取器" class="headerlink" title="请求抽取器"></a>请求抽取器</h2><p>可以通过<code>play.api.mvc.Accepting</code>这个case class来自定义请求头抽取器,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> <span class="type">AcceptsMp3</span> = <span class="type">Accepting</span>(<span class="string">"audio/mp3"</span>)</span><br><span class="line"></span><br><span class="line">render {</span><br><span class="line"> <span class="keyword">case</span> <span class="type">AcceptsMp3</span>() => ???</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Play框架学习之Content negotiation
</summary>
<category term="Play" scheme="http://irusist.github.io/categories/Play/"/>
<category term="Play2" scheme="http://irusist.github.io/tags/Play2/"/>
<category term="Play" scheme="http://irusist.github.io/tags/Play/"/>
<category term="Scala" scheme="http://irusist.github.io/tags/Scala/"/>
</entry>
<entry>
<title>Play框架学习之Action组合</title>
<link href="http://irusist.github.io/2016/01/09/Play%E6%A1%86%E6%9E%B6%E5%AD%A6%E4%B9%A0%E4%B9%8BAction%E7%BB%84%E5%90%88/"/>
<id>http://irusist.github.io/2016/01/09/Play框架学习之Action组合/</id>
<published>2016-01-09T15:21:03.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Play2中,可以组合多个<code>Action</code></p><h2 id="自定义Action"><a href="#自定义Action" class="headerlink" title="自定义Action"></a>自定义Action</h2><p>可以通过继承<code>ActionBuilder</code>来定义一个Action,Play2中自带的Action就是一个默认实现,如下是自定义一个<code>Action</code>,用于对每个请求打印信息。</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">object</span> <span class="title">LoggingAction</span> <span class="keyword">extends</span> <span class="title">ActionBuilder</span>[<span class="type">Request</span>] </span>{</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">def</span> <span class="title">invokeBlock</span></span>[<span class="type">A</span>](request: <span class="type">Request</span>[<span class="type">A</span>], block: (<span class="type">Request</span>[<span class="type">A</span>]) => <span class="type">Future</span>[<span class="type">Result</span>]) = {</span><br><span class="line"> <span class="type">Logger</span>.info(<span class="string">"Calling action"</span>)</span><br><span class="line"> block(request)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>可以通过如下的方法来使用这个自定义的<code>Action</code>:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">custom</span></span>() = <span class="type">LoggingAction</span> {</span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"custom action"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这样,在每次请求时就会打印“Calling action”信息。</p><a id="more"></a><h3 id="组合Action"><a href="#组合Action" class="headerlink" title="组合Action"></a>组合Action</h3><p>在开发时,经常遇到会对每一个<code>Action</code>进行一些通用的处理,如日志, 权限等,在Play2中,可以将它们定义成不同的<code>Action</code>,然后将它们组合起来。</p><p>可以通过继承<code>Action</code>来创建新的<code>Action</code>,它是一个接收其他<code>Action</code>的<code>case class</code>。</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">case</span> <span class="class"><span class="keyword">class</span> <span class="title">Logging</span>[<span class="type">A</span>](<span class="params">action: <span class="type">Action</span>[<span class="type">A</span>]</span>) <span class="keyword">extends</span> <span class="title">Action</span>[<span class="type">A</span>] </span>{</span><br><span class="line"> <span class="keyword">lazy</span> <span class="keyword">val</span> parser: <span class="type">BodyParser</span>[<span class="type">A</span>] = action.parser</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">def</span> <span class="title">apply</span></span>(request: <span class="type">Request</span>[<span class="type">A</span>]): <span class="type">Future</span>[<span class="type">Result</span>] = {</span><br><span class="line"> <span class="type">Logger</span>.info(<span class="string">"Calling action"</span>)</span><br><span class="line"> action(request)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>也可以通过<code>Action.async</code>方法来定义一个接收其他<code>Action</code>的参数,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">logging</span></span>[<span class="type">A</span>](action: <span class="type">Action</span>[<span class="type">A</span>]) = <span class="type">Action</span>.async(action.parser) { request =></span><br><span class="line"> <span class="type">Logger</span>.info(<span class="string">"Calling action"</span>)</span><br><span class="line"> action(request)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>也可以通过<code>ActionBuilder</code>的<code>composeAction</code>方法来将它本身的<code>Action</code>组装到其他<code>Action</code>中,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">object</span> <span class="title">LoggingAction</span> <span class="keyword">extends</span> <span class="title">ActionBuilder</span>[<span class="type">Request</span>] </span>{</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">def</span> <span class="title">invokeBlock</span></span>[<span class="type">A</span>](request: <span class="type">Request</span>[<span class="type">A</span>], block: (<span class="type">Request</span>[<span class="type">A</span>]) => <span class="type">Future</span>[<span class="type">Result</span>]) = {</span><br><span class="line"> block(request)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">protected</span> <span class="function"><span class="keyword">def</span> <span class="title">composeAction</span></span>[<span class="type">A</span>](action: <span class="type">Action</span>[<span class="type">A</span>]): <span class="type">Action</span>[<span class="type">A</span>] = <span class="type">Logging</span>[<span class="type">A</span>](action)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>可以通过以下方法来使用<code>logging</code>方法:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">custom</span></span>() = logging {</span><br><span class="line"> <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"custom action"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="更复杂的Action"><a href="#更复杂的Action" class="headerlink" title="更复杂的Action"></a>更复杂的Action</h3><p>可以通过组合<code>Action</code>来修改request对象,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">xForwardedFor</span></span>[<span class="type">A</span>](action: <span class="type">Action</span>[<span class="type">A</span>]) = <span class="type">Action</span>.async(action.parser) { request =></span><br><span class="line"> <span class="keyword">val</span> newRequest = request.headers.get(<span class="type">X_FORWARDED_FOR</span>).map { xff =></span><br><span class="line"> <span class="keyword">new</span> <span class="type">WrappedRequest</span>[<span class="type">A</span>](request) {</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">def</span> <span class="title">remoteAddress</span> </span>= xff</span><br><span class="line"> }</span><br><span class="line"> } getOrElse request</span><br><span class="line"> action(newRequest)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>也可以修改返回的结果,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">addUaHeader</span></span>[<span class="type">A</span>](action: <span class="type">Action</span>[<span class="type">A</span>]) = <span class="type">Action</span>.async(action.parser) { request =></span><br><span class="line"> action(request).map(_.withHeaders(<span class="string">"X-UA-Compatible"</span> -> <span class="string">"Chrome=1"</span>))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="不同的请求类型"><a href="#不同的请求类型" class="headerlink" title="不同的请求类型"></a>不同的请求类型</h2><p><code>ActionFunction</code>是一个作用于request的方法,它可以用于权限,认证,查询数据库对象等。有以下内置的<code>ActionFunction</code>:</p><ul><li><p><code>ActionTransformer</code>:可以用来修改request,如增加一些额外的信息。</p></li><li><p><code>ActionFilter</code>:可以用来拦截某些不符合条件的请求,不用来改变请求的值。</p></li><li><p><code>ActionRefiner</code>:是上面2个的父类</p></li><li><p><code>ActionBuilder</code>:以<code>Request</code>作为输入参数,生成Action,是上面3个的父类,最通用的类。</p></li></ul><h3 id="认证"><a href="#认证" class="headerlink" title="认证"></a>认证</h3><p>以下是一个认证的例子,通过组合以上的<code>ActionFunction</code>。</p><p>首先,自定义一个请求类,并且定义Action</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserRequest</span>[<span class="type">A</span>](<span class="params">val username: <span class="type">Option</span>[<span class="type">String</span>], request: <span class="type">Request</span>[<span class="type">A</span>]</span>) <span class="keyword">extends</span> <span class="title">WrappedRequest</span>[<span class="type">A</span>](<span class="params">request</span>)</span></span><br><span class="line"><span class="class"></span></span><br><span class="line"><span class="class"><span class="title">object</span> <span class="title">UserAction</span> <span class="keyword">extends</span></span></span><br><span class="line"><span class="class"> <span class="title">ActionBuilder</span>[<span class="type">UserRequest</span>] <span class="keyword">with</span> <span class="title">ActionTransformer</span>[<span class="type">Request</span>, <span class="type">UserRequest</span>] </span>{</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">transform</span></span>[<span class="type">A</span>](request: <span class="type">Request</span>[<span class="type">A</span>]) = <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="keyword">new</span> <span class="type">UserRequest</span>(request.session.get(<span class="string">"username"</span>), request)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>添加一些额外的信息,生成另一个请求对象</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ItemRequest</span>[<span class="type">A</span>](<span class="params">val item: <span class="type">Item</span>, request: <span class="type">UserRequest</span>[<span class="type">A</span>]</span>) <span class="keyword">extends</span> <span class="title">WrappedRequest</span>[<span class="type">A</span>](<span class="params">request</span>) </span>{</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">username</span> </span>= request.username</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>然后对请求信息进行转换</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">ItemAction</span></span>(itemId: <span class="type">String</span>) = <span class="keyword">new</span> <span class="type">ActionRefiner</span>[<span class="type">UserRequest</span>, <span class="type">ItemRequest</span>] {</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">refine</span></span>[<span class="type">A</span>](input: <span class="type">UserRequest</span>[<span class="type">A</span>]) = <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="type">ItemDao</span>.findById(itemId)</span><br><span class="line"> .map(<span class="keyword">new</span> <span class="type">ItemRequest</span>(_, input))</span><br><span class="line"> .toRight(<span class="type">NotFound</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>验证请求内容</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">object</span> <span class="title">PermissionCheckAction</span> <span class="keyword">extends</span> <span class="title">ActionFilter</span>[<span class="type">ItemRequest</span>] </span>{</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">filter</span></span>[<span class="type">A</span>](input: <span class="type">ItemRequest</span>[<span class="type">A</span>]) = <span class="type">Future</span>.successful {</span><br><span class="line"> <span class="keyword">if</span> (!input.item.accessibleByUser(input.username))</span><br><span class="line"> <span class="type">Some</span>(<span class="type">Forbidden</span>)</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="type">None</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>最后将所有的转换组合在一起:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">tagItem</span></span>(itemId: <span class="type">String</span>, tag: <span class="type">String</span>) =</span><br><span class="line"> (<span class="type">UserAction</span> andThen <span class="type">ItemAction</span>(itemId) andThen <span class="type">PermissionCheckAction</span>) { request =></span><br><span class="line"> request.item.addTag(tag)</span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"User "</span> + request.username + <span class="string">" tagged "</span> + request.item.id)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Play框架学习之Action组合
</summary>
<category term="Play" scheme="http://irusist.github.io/categories/Play/"/>
<category term="Play2" scheme="http://irusist.github.io/tags/Play2/"/>
<category term="Play" scheme="http://irusist.github.io/tags/Play/"/>
<category term="Scala" scheme="http://irusist.github.io/tags/Scala/"/>
</entry>
<entry>
<title>Play框架学习之Action, Controller, Result</title>
<link href="http://irusist.github.io/2016/01/08/Play%E6%A1%86%E6%9E%B6%E5%AD%A6%E4%B9%A0%E4%B9%8BAction-Controller-Result/"/>
<id>http://irusist.github.io/2016/01/08/Play框架学习之Action-Controller-Result/</id>
<published>2016-01-08T14:34:46.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>折腾了2个晚上,终于把Play2框架编译成功搭建起来,跟着官网的文档体验一下。</p><h2 id="Action"><a href="#Action" class="headerlink" title="Action"></a>Action</h2><p>Action是用于请求的地方,最简单的Action就是返回一些文本或页面的Result,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Action</span> {</span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"Hello world"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>其中OK是一个<code>Status</code>对象,它接收一个值为200的<code>Int</code>类型代表响应头的状态码,同时<code>Status</code>类有一个<code>apply</code>方法,它有一个参数,代表响应的内容。</p><p>Action也接收一个<code>Request => Result</code>类型的参数, 可以对请求信息进行处理,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span> </span>= <span class="type">Action</span> { request =></span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"request is: "</span> + request)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><a id="more"></a><p>request参数可以定义成隐式参数的形式</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span> </span>= <span class="type">Action</span> { <span class="keyword">implicit</span> request =></span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"request is: "</span> + request)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Action还可以有一个<code>BodyParser</code>参数,用于解析请求body的内容,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span> </span>= <span class="type">Action</span>(parse.json) { <span class="keyword">implicit</span> request =></span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"request is: "</span> + request)</span><br></pre></td></tr></table></figure><p>表示请求的body可以通过json来解析,因此body的格式必须为<code>text/json</code>或者<code>application/json</code>的。</p><h2 id="Controller"><a href="#Controller" class="headerlink" title="Controller"></a>Controller</h2><p>Controller是一个用来定义<code>Action</code>的一个单例对象。最简单的<code>Controller</code>的方法是没有参数的</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span> </span>= <span class="type">Action</span> { request =></span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"request is: "</span> + request)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>方法也可以有参数,这些参数可以被<code>Action</code>中的代码块使用,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span></span>(name : <span class="type">String</span>) = <span class="type">Action</span> { request =></span><br><span class="line"> <span class="type">Ok</span>(<span class="string">"parameter is: "</span> + name)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="Result"><a href="#Result" class="headerlink" title="Result"></a>Result</h2><p><code>Result</code>是<code>Action</code>的返回类型,它可以设置响应头和响应体,如:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span> </span>= <span class="type">Action</span> {</span><br><span class="line"> <span class="type">Result</span>(</span><br><span class="line"> header = <span class="type">ResponseHeader</span>(<span class="number">200</span>, <span class="type">Map</span>(<span class="type">CONTENT_TYPE</span> -> <span class="string">"text/plain"</span>)),</span><br><span class="line"> body = <span class="type">Enumerator</span>(<span class="string">"response"</span>.getBytes)</span><br><span class="line"> )</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>也可以设置各种响应码,如404,500等,一些常用的如下</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/** Generates a ‘403 FORBIDDEN’ result. */</span></span><br><span class="line"><span class="keyword">val</span> <span class="type">Forbidden</span> = <span class="keyword">new</span> <span class="type">Status</span>(<span class="type">FORBIDDEN</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Generates a ‘404 NOT_FOUND’ result. */</span></span><br><span class="line"><span class="keyword">val</span> <span class="type">NotFound</span> = <span class="keyword">new</span> <span class="type">Status</span>(<span class="type">NOT_FOUND</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Generates a ‘500 INTERNAL_SERVER_ERROR’ result. */</span></span><br><span class="line"><span class="keyword">val</span> <span class="type">InternalServerError</span> = <span class="keyword">new</span> <span class="type">Status</span>(<span class="type">INTERNAL_SERVER_ERROR</span>)</span><br></pre></td></tr></table></figure><p><code>Result</code>也可以返回一个重定向的结果,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">redirect</span> </span>= <span class="type">Action</span> { request =></span><br><span class="line"> <span class="type">Redirect</span>(<span class="string">"/add"</span>, <span class="type">MOVED_PERMANENTLY</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>重定向时如果不指定第2个参数,则默认响应头为<code>val SEE_OTHER = 303</code></p><p><code>Action</code>也支持一个默认的<code>TODO</code>页面,如</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span></span>(name:<span class="type">String</span>) = <span class="type">TODO</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Play框架学习之Action, Controller, Result
</summary>
<category term="Play" scheme="http://irusist.github.io/categories/Play/"/>
<category term="Play2" scheme="http://irusist.github.io/tags/Play2/"/>
<category term="Play" scheme="http://irusist.github.io/tags/Play/"/>
<category term="Scala" scheme="http://irusist.github.io/tags/Scala/"/>
</entry>
<entry>
<title>Java 8之Arrays新增方法</title>
<link href="http://irusist.github.io/2016/01/07/Java-8%E4%B9%8BArrays%E6%96%B0%E5%A2%9E%E6%96%B9%E6%B3%95/"/>
<id>http://irusist.github.io/2016/01/07/Java-8之Arrays新增方法/</id>
<published>2016-01-07T14:43:46.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Java 8中,在Arrays工具类中增加了一些对数组相关的并行和流的操作。</p><h2 id="parallelSort-方法"><a href="#parallelSort-方法" class="headerlink" title="parallelSort 方法"></a>parallelSort 方法</h2><p><code>parallelSort</code>方法是并行地对数组进行排序,它有很多个重载方法,可以对基本类型, <code>Comparable</code>类型对象,或者提供一个<code>Comparator</code>接口对一般对象进行排序。</p><p>如果数组的大小小于或等于8192(1 << 13),会直接排序,不会并行。并行排序使用的是ForkJoin框架。</p><a id="more"></a><h2 id="parallelPrefix-方法"><a href="#parallelPrefix-方法" class="headerlink" title="parallelPrefix 方法"></a>parallelPrefix 方法</h2><p><code>parallelPrefix</code>方法需要提供一个操作方法,通过遍历数组的元素,将当前索引位置的值与它之前索引的值进行操作,然后将操作后的值覆盖当前索引位置的值。下面用一个简单说明一下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span>[] array = <span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">5</span>};</span><br><span class="line"><span class="comment">// [2, 3, 1, 0, 5]</span></span><br><span class="line"><span class="comment">// [2, 5, 1, 0, 5]</span></span><br><span class="line"><span class="comment">// [2, 5, 6, 0, 5]</span></span><br><span class="line"><span class="comment">// [2, 5, 6, 6, 5]</span></span><br><span class="line">Arrays.parallelPrefix(array, (left, right) ->{</span><br><span class="line"> System.out.println(Arrays.toString(array));</span><br><span class="line"> <span class="keyword">return</span> left + right;</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">// 输出 [2, 5, 6, 6, 11]</span></span><br><span class="line">System.out.println(Arrays.toString(array));</span><br></pre></td></tr></table></figure><p>上面将每一步操作都输出结果,首先,从索引为1开始循环,将索引为0的值2, 与索引为1的值3进行相加,得到5覆盖索引为1的值,依此直到达到数组的最后一个元素。</p><h2 id="setAll-方法"><a href="#setAll-方法" class="headerlink" title="setAll 方法"></a>setAll 方法</h2><p><code>setAll</code>方法提供一个 <code>int -> T</code>的函数接口,通过该接口对数组的索引进行操作,然后将指定数组当前索引位置的值赋值为操作后的值,以下是例子</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span>[] array = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">10</span>];</span><br><span class="line">Arrays.setAll(array, i -> i * <span class="number">10</span>);</span><br><span class="line"><span class="comment">// 输出 [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]</span></span><br><span class="line">System.out.println(Arrays.toString(array));</span><br></pre></td></tr></table></figure><p><code>parallelSetAll</code>方法是 <code>setAll</code>的并行操作版本。</p><h2 id="spliterator-方法"><a href="#spliterator-方法" class="headerlink" title="spliterator 方法"></a>spliterator 方法</h2><p><code>spliterator</code>方法返回一个<code>Spliterator</code>, 关于<code>Spliterator</code>的内容,后续再详细说明下。</p><h2 id="stream-方法"><a href="#stream-方法" class="headerlink" title="stream 方法"></a>stream 方法</h2><p><code>stream</code> 方法是将数组转换为<code>Stream</code>的操作,可以是任意类型的数组, 并且可以指定数组的范围。</p>]]></content>
<summary type="html">
Java 8之Arrays新增方法
</summary>
<category term="Java" scheme="http://irusist.github.io/categories/Java/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
<category term="Java" scheme="http://irusist.github.io/tags/Java/"/>
</entry>
<entry>
<title>Java 8之并行Stream</title>
<link href="http://irusist.github.io/2016/01/05/Java-8%E4%B9%8B%E5%B9%B6%E8%A1%8CStream/"/>
<id>http://irusist.github.io/2016/01/05/Java-8之并行Stream/</id>
<published>2016-01-05T15:09:53.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>Java 8中的Stream的操作可以通过并行的操作执行,通过<code>Stream.parallel</code>或者<code>Collection.parallelStream</code>方法可以获取并行操作的流。</p><p>并行流需要满足以下2个要求:</p><ul><li><p>恒等性:初始值必须为组合函数的恒等值,拿恒等值和其他值做reduce操作时,其他值保持不变。</p></li><li><p>组合律:改变组合操作的顺序不会影响最终的结果。</p></li></ul><a id="more"></a><p>在书中有个蒙特卡洛模拟法的例子,为了学习,参考书中,写个一样的例子如下</p><p>Java 8之前的版本</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MonteCarloMethod</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> ConcurrentMap<Integer, Double> map = <span class="keyword">new</span> ConcurrentHashMap<>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> threadCount = Runtime.getRuntime().availableProcessors();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> ExecutorService pool = Executors.newFixedThreadPool(threadCount);</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="comment">// 执行次数</span></span><br><span class="line"> <span class="keyword">long</span> count = <span class="number">100000000L</span>;</span><br><span class="line"></span><br><span class="line"> MonteCarloMethod bean = <span class="keyword">new</span> MonteCarloMethod();</span><br><span class="line"> bean.loop(count);</span><br><span class="line"> bean.print();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">loop</span><span class="params">(<span class="keyword">long</span> count)</span> </span>{</span><br><span class="line"> <span class="comment">// 每个线程执行的个数</span></span><br><span class="line"> <span class="keyword">long</span> taskPerThread = count / threadCount;</span><br><span class="line"></span><br><span class="line"> List<Future> futures = <span class="keyword">new</span> ArrayList<>(threadCount);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < threadCount; i++) {</span><br><span class="line"> futures.add(pool.submit(getTask(count, taskPerThread)));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 等待执行完成</span></span><br><span class="line"> futures.forEach(future -> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> future.get();</span><br><span class="line"> } <span class="keyword">catch</span> (ExecutionException | InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> pool.shutdown();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取每个线程的执行任务</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> count</span></span><br><span class="line"><span class="comment"> * 总的任务数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> taskPerThread</span></span><br><span class="line"><span class="comment"> * 每个线程的任务数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 执行任务</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> Runnable <span class="title">getTask</span><span class="params">(<span class="keyword">long</span> count, <span class="keyword">long</span> taskPerThread)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> () -> {</span><br><span class="line"> <span class="keyword">double</span> data = <span class="number">1.0</span> / count;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < taskPerThread; i++) {</span><br><span class="line"> map.compute(doTask(), (key, value) -> {</span><br><span class="line"> <span class="keyword">if</span> (value == <span class="keyword">null</span>)</span><br><span class="line"> <span class="keyword">return</span> data;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> value + data;</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取2个随机1到6的数字之和</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 随机数之和</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">doTask</span><span class="params">()</span> </span>{</span><br><span class="line"> ThreadLocalRandom random = ThreadLocalRandom.current();</span><br><span class="line"> <span class="keyword">int</span> first = random.nextInt(<span class="number">1</span>, <span class="number">7</span>);</span><br><span class="line"> <span class="keyword">int</span> second = random.nextInt(<span class="number">1</span>, <span class="number">7</span>);</span><br><span class="line"> <span class="keyword">return</span> first + second;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 打印map内容</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">()</span> </span>{</span><br><span class="line"> map.entrySet().forEach(System.out::println);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Java 8版本如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MonteCarloMethodStream</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="keyword">new</span> MonteCarloMethodStream().loop(<span class="number">100000000L</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">loop</span><span class="params">(<span class="keyword">long</span> count)</span> </span>{</span><br><span class="line"> <span class="keyword">double</span> data = <span class="number">1.0</span> / count;</span><br><span class="line"> LongStream.range(<span class="number">0</span>, count).parallel()</span><br><span class="line"> .mapToObj(origin -> random())</span><br><span class="line"> .collect(Collectors.groupingBy(origin -> origin, Collectors.summingDouble(origin -> data)))</span><br><span class="line"> .entrySet().forEach(System.out::println);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取2个随机1到6的数字之和</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 随机数之和</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">random</span><span class="params">()</span> </span>{</span><br><span class="line"> ThreadLocalRandom random = ThreadLocalRandom.current();</span><br><span class="line"> <span class="keyword">int</span> first = random.nextInt(<span class="number">1</span>, <span class="number">7</span>);</span><br><span class="line"> <span class="keyword">int</span> second = random.nextInt(<span class="number">1</span>, <span class="number">7</span>);</span><br><span class="line"> <span class="keyword">return</span> first + second;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在Java 8中,并行流替我们做了一些并发处理的逻辑,代码显得简洁很多。</p>]]></content>
<summary type="html">
Java 8之并行Stream
</summary>
<category term="Java" scheme="http://irusist.github.io/categories/Java/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
<category term="Java" scheme="http://irusist.github.io/tags/Java/"/>
</entry>
<entry>
<title>Java 8之Map新增方法</title>
<link href="http://irusist.github.io/2016/01/04/Java-8%E4%B9%8BMap%E6%96%B0%E5%A2%9E%E6%96%B9%E6%B3%95/"/>
<id>http://irusist.github.io/2016/01/04/Java-8之Map新增方法/</id>
<published>2016-01-04T14:52:04.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Java 8中的<code>Map.Entry</code>接口中增加了<code>comparingByKey</code>, <code>comparingByValue</code>方法,它们都返回<code>Comparator<Map.Entry<K,V>></code>, <code>Comparator</code>是一个函数接口,主要是方便Lambda表达式的使用。</p><p>在Java 8中的<code>Map</code>接口增加了一些default方法,提升了对key, value操作的便利性。下面是基本数据的定义,通过这些数据说明新增的一些方法。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Map<Integer, String> map = <span class="keyword">new</span> HashMap<>();</span><br><span class="line">map.put(<span class="number">1</span>, <span class="string">"a"</span>);</span><br><span class="line">map.put(<span class="number">2</span>, <span class="string">"b"</span>);</span><br><span class="line">map.put(<span class="number">3</span>, <span class="string">"c"</span>);</span><br></pre></td></tr></table></figure><a id="more"></a><h2 id="getOrDefault-方法"><a href="#getOrDefault-方法" class="headerlink" title="getOrDefault 方法"></a>getOrDefault 方法</h2><p>如果指定的key存在,则返回该key对应的value,如果不存在,则返回指定的值。例子如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// key为4不存在,输出 d</span></span><br><span class="line">System.out.println(map.getOrDefault(<span class="number">4</span>, <span class="string">"d"</span>));</span><br></pre></td></tr></table></figure><h2 id="forEach-方法"><a href="#forEach-方法" class="headerlink" title="forEach 方法"></a>forEach 方法</h2><p>遍历<code>Map</code>中的所有Entry, 对key, value进行处理, 接收参数 <code>(K, V) -> void</code>, 例子如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出1a, 2b, 3c</span></span><br><span class="line">map.forEach((key, value) -> System.out.println(key + value));</span><br></pre></td></tr></table></figure><h2 id="replaceAll-方法"><a href="#replaceAll-方法" class="headerlink" title="replaceAll 方法"></a>replaceAll 方法</h2><p>替换<code>Map</code>中所有Entry的value值,这个值由旧的key和value计算得出,接收参数 <code>(K, V) -> V</code>, 类似如下代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (Map.Entry<K, V> entry : map.entrySet())</span><br><span class="line"> entry.setValue(function.apply(entry.getKey(), entry.getValue()));</span><br></pre></td></tr></table></figure><p>例如如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">map.replaceAll((key, value) -> (key + <span class="number">1</span>) + value);</span><br><span class="line"><span class="comment">// 输出 12a 23b 34c</span></span><br><span class="line">map.forEach((key, value) -> System.out.println(key + value));</span><br></pre></td></tr></table></figure><h2 id="putIfAbsent-方法"><a href="#putIfAbsent-方法" class="headerlink" title="putIfAbsent 方法"></a>putIfAbsent 方法</h2><p>如果key关联的value不存在,则关联新的value值,返回key关联的旧的值,类似如下代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">V v = map.get(key);</span><br><span class="line"><span class="keyword">if</span> (v == <span class="keyword">null</span>)</span><br><span class="line"> v = map.put(key, value);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> v;</span><br></pre></td></tr></table></figure><p>示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">map.putIfAbsent(<span class="number">3</span>, <span class="string">"d"</span>);</span><br><span class="line">map.putIfAbsent(<span class="number">4</span>, <span class="string">"d"</span>);</span><br><span class="line"><span class="comment">// 输出 c</span></span><br><span class="line">System.out.println(map.get(<span class="number">3</span>));</span><br><span class="line"><span class="comment">// 输出 d</span></span><br><span class="line">System.out.println(map.get(<span class="number">4</span>));</span><br></pre></td></tr></table></figure><h2 id="remove-方法"><a href="#remove-方法" class="headerlink" title="remove 方法"></a>remove 方法</h2><p>接收2个参数,key和value,如果key关联的value值与指定的value值相等(<code>equals</code>),则删除这个元素,类似代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (map.containsKey(key) && Objects.equals(map.get(key), value)) {</span><br><span class="line"> map.remove(key);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">} <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br></pre></td></tr></table></figure><p>示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">map.remove(<span class="number">1</span>, <span class="string">"b"</span>);</span><br><span class="line"><span class="comment">// 未删除成功, 输出 a</span></span><br><span class="line">System.out.println(map.get(<span class="number">1</span>));</span><br><span class="line"></span><br><span class="line">map.remove(<span class="number">2</span>, <span class="string">"b"</span>);</span><br><span class="line"><span class="comment">// 删除成功,输出 null</span></span><br><span class="line">System.out.println(map.get(<span class="number">2</span>));</span><br></pre></td></tr></table></figure><h2 id="replace-K-key-V-oldValue-V-newValue-方法"><a href="#replace-K-key-V-oldValue-V-newValue-方法" class="headerlink" title="replace(K key, V oldValue, V newValue) 方法"></a>replace(K key, V oldValue, V newValue) 方法</h2><p>如果key关联的值与指定的oldValue的值相等,则替换成新的newValue,类似代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (map.containsKey(key) && Objects.equals(map.get(key), value)) {</span><br><span class="line"> map.put(key, newValue);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">} <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br></pre></td></tr></table></figure><p>示例代码如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">map.replace(<span class="number">3</span>, <span class="string">"a"</span>, <span class="string">"z"</span>);</span><br><span class="line"><span class="comment">// 未替换成功,输出 c</span></span><br><span class="line">System.out.println(map.get(<span class="number">3</span>));</span><br><span class="line"></span><br><span class="line">map.replace(<span class="number">1</span>, <span class="string">"a"</span>, <span class="string">"z"</span>);</span><br><span class="line"><span class="comment">// 替换成功, 输出 z</span></span><br><span class="line">System.out.println(map.get(<span class="number">1</span>));</span><br></pre></td></tr></table></figure><h2 id="replace-K-key-V-value-方法"><a href="#replace-K-key-V-value-方法" class="headerlink" title="replace(K key, V value) 方法"></a>replace(K key, V value) 方法</h2><p>如果map中存在key,则替换成value值,否则返回<code>null</code>, 类似代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (map.containsKey(key)) {</span><br><span class="line"> <span class="keyword">return</span> map.put(key, value);</span><br><span class="line">} <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br></pre></td></tr></table></figure><p>示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出旧的值, a</span></span><br><span class="line">System.out.println(map.replace(<span class="number">1</span>, <span class="string">"aa"</span>));</span><br><span class="line"><span class="comment">// 替换成功,输出新的值, aa</span></span><br><span class="line">System.out.println(map.get(<span class="number">1</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 不存在key为4, 输出 null</span></span><br><span class="line">System.out.println(map.replace(<span class="number">4</span>, <span class="string">"d"</span>));</span><br><span class="line"><span class="comment">// 不存在key为4, 输出 null</span></span><br><span class="line">System.out.println(map.get(<span class="number">4</span>));</span><br></pre></td></tr></table></figure><h2 id="computeIfAbsent-方法"><a href="#computeIfAbsent-方法" class="headerlink" title="computeIfAbsent 方法"></a>computeIfAbsent 方法</h2><p>如果指定的key不存在,则通过指定的<code>K -> V</code>计算出新的值设置为key的值,类似代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (map.get(key) == <span class="keyword">null</span>) {</span><br><span class="line"> V newValue = mappingFunction.apply(key);</span><br><span class="line"> <span class="keyword">if</span> (newValue != <span class="keyword">null</span>)</span><br><span class="line"> map.put(key, newValue);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">map.computeIfAbsent(<span class="number">1</span>, key -> key + <span class="string">" computed"</span>);</span><br><span class="line"><span class="comment">// 存在key为1,则不进行计算,输出值 a</span></span><br><span class="line">System.out.println(map.get(<span class="number">1</span>));</span><br><span class="line"></span><br><span class="line">map.computeIfAbsent(<span class="number">4</span>, key -> key + <span class="string">" computed"</span>);</span><br><span class="line"><span class="comment">// 不存在key为4,则进行计算,输出值 4 computed</span></span><br><span class="line">System.out.println(map.get(<span class="number">4</span>));</span><br></pre></td></tr></table></figure><h2 id="computeIfPresent-方法"><a href="#computeIfPresent-方法" class="headerlink" title="computeIfPresent 方法"></a>computeIfPresent 方法</h2><p>如果指定的key存在,则根据旧的key和value计算新的值newValue, 如果newValue不为<code>null</code>,则设置key新的值为newValue, 如果newValue为<code>null</code>, 则删除该key的值,类似代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (map.get(key) != <span class="keyword">null</span>) {</span><br><span class="line"> V oldValue = map.get(key);</span><br><span class="line"> V newValue = remappingFunction.apply(key, oldValue);</span><br><span class="line"> <span class="keyword">if</span> (newValue != <span class="keyword">null</span>)</span><br><span class="line"> map.put(key, newValue);</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> map.remove(key);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">map.computeIfPresent(<span class="number">1</span>, (key, value) -> (key + <span class="number">1</span>) + value);</span><br><span class="line"><span class="comment">// 存在key为1, 则根据旧的key和value计算新的值,输出 2a</span></span><br><span class="line">System.out.println(map.get(<span class="number">1</span>));</span><br><span class="line"></span><br><span class="line">map.computeIfPresent(<span class="number">2</span>, (key, value) -> <span class="keyword">null</span>);</span><br><span class="line"><span class="comment">// 存在key为2, 根据旧的key和value计算得到null,删除该值,输出 null</span></span><br><span class="line">System.out.println(map.get(<span class="number">2</span>));</span><br></pre></td></tr></table></figure><h2 id="compute-方法"><a href="#compute-方法" class="headerlink" title="compute 方法"></a>compute 方法</h2><p><code>compute</code>方法是<code>computeIfAbsent</code>与<code>computeIfPresent</code>的综合体。</p><h2 id="merge-K-key-V-value-BiFunction-lt-super-V-super-V-extends-V-gt-remappingFunction-方法"><a href="#merge-K-key-V-value-BiFunction-lt-super-V-super-V-extends-V-gt-remappingFunction-方法" class="headerlink" title="merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) 方法"></a>merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) 方法</h2><p>如果指定的key不存在,则设置指定的value值,否则根据key的旧的值oldvalue,value计算出新的值newValue, 如果newValue为<code>null</code>, 则删除该key,否则设置key的新值newValue。类似如下代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">V oldValue = map.get(key);</span><br><span class="line">V newValue = (oldValue == <span class="keyword">null</span>) ? value :</span><br><span class="line"> remappingFunction.apply(oldValue, value);</span><br><span class="line"><span class="keyword">if</span> (newValue == <span class="keyword">null</span>)</span><br><span class="line"> map.remove(key);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"> map.put(key, newValue);</span><br></pre></td></tr></table></figure><p>示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 存在key为1, 输出 a merge</span></span><br><span class="line">System.out.println(map.merge(<span class="number">1</span>, <span class="string">" merge"</span>, (oldValue, newValue) -> oldValue + newValue));</span><br><span class="line"><span class="comment">// 新值为null,删除key,输出 null</span></span><br><span class="line">System.out.println(map.merge(<span class="number">1</span>, <span class="string">" merge"</span>, (oldValue, newValue) -> <span class="keyword">null</span>));</span><br><span class="line"><span class="comment">// 输出 " merge"</span></span><br><span class="line">System.out.println(map.merge(<span class="number">4</span>, <span class="string">" merge"</span>, (oldValue, newValue) -> oldValue + newValue));</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Java 8之Map新增方法
</summary>
<category term="Java" scheme="http://irusist.github.io/categories/Java/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
<category term="Java" scheme="http://irusist.github.io/tags/Java/"/>
<category term="Map" scheme="http://irusist.github.io/tags/Map/"/>
</entry>
<entry>
<title>Java 8之Collector</title>
<link href="http://irusist.github.io/2016/01/04/Java-8%E4%B9%8BCollector/"/>
<id>http://irusist.github.io/2016/01/04/Java-8之Collector/</id>
<published>2016-01-04T13:17:25.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>Java 8中有一个<code>Collector</code>接口,主要是为Stream中的元素转换成其他值提供的一个接口,在<code>Collectors</code>工具类中有很多<code>Collector</code>接口的实现方式。</p><p>Collector的定义为<code>Collector<T, A, R></code>, 其中泛型参数<code>T</code>表示Stream中元素的类型, <code>A</code>表示定义一个初始容器的类型,<code>R</code>表示最终转换的类型。</p><p>Collector接口主要定义了如下几个方法:</p><ul><li><p>supplier:这个方法主要是生成一个初始容器,用于存放转换的数据。它返回一个<code>Supplier<A></code>类型,用Lambda表示为<code>() -> A</code></p></li><li><p>accumulator: 这个方法是将初始容器与Stream中的每个元素进行计算,它返回一个<code>BiConsumer<A, T></code>类型,用Lambda表示为<code>(A, T) -> void</code></p></li><li><p>combiner: 这个方法用于在并发Stream中,将多个容器组合成一个容器,它返回一个<code>BinaryOperator<A></code>类型,用Lambda表示为<code>(A, A) -> A</code></p></li><li><p>finisher:这个方法用于将初始容器转换成最终的值,它返回一个<code>Function<A, R></code>类型,用Lambda表示为<code>A -> R</code></p></li><li><p>characteristics: 这个方法返回该Collector具有的哪些特征,返回的是一个<code>Set</code>, 分别是<code>CONCURRENT</code>(并发), <code>UNORDERED</code>(未排序),<code>IDENTITY_FINISH</code>(<code>finisher</code>方法直接返回初始容器)等特征的组合。</p></li></ul><a id="more"></a><p>在<code>Collectors</code>中有一个<code>joining</code>方法,它是将<code>Stream</code>中的字符序列类型的元素串接在一起,下面是一个例子:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 abcd</span></span><br><span class="line">System.out.println(Stream.of(<span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"c"</span>, <span class="string">"d"</span>).collect(Collectors.joining()));</span><br></pre></td></tr></table></figure><p>下面通过自己实现joining方法来理解如何实现<code>Collector</code>接口。</p><p>定义自己实现的<code>JoinCollector</code>类:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JoinCollector</span> <span class="keyword">implements</span> <span class="title">Collector</span><<span class="title">CharSequence</span>, <span class="title">StringBuilder</span>, <span class="title">String</span>> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Supplier<StringBuilder> <span class="title">supplier</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> StringBuilder::<span class="keyword">new</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> BiConsumer<StringBuilder, CharSequence> <span class="title">accumulator</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> StringBuilder::append;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> BinaryOperator<StringBuilder> <span class="title">combiner</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> StringBuilder::append;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Function<StringBuilder, String> <span class="title">finisher</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> StringBuilder::toString;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Set<Characteristics> <span class="title">characteristics</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> Collections.emptySet();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>其中,<code>supplier</code>方法返回一个<code>StringBuilder</code>对象,用于表示初始容器。</p><p><code>accumulator</code>方法返回的是<code>StringBuilder</code>的<code>append</code>方法的方法引用, 用于将<code>Stream</code>中的元素加入到初始容器<code>StringBuilder</code>中。</p><p><code>combiner</code>方法用于将多个<code>StringBuilder</code>容器通过<code>append</code>方法组合成一个<code>StringBuilder</code>对象。</p><p><code>finisher</code>方法是将<code>StringBuilder</code>对象通过<code>toString</code>方法最终转换成<code>String</code>对象。</p><p>使用自定义的<code>Collector</code>的例子如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 abcd</span></span><br><span class="line">System.out.println(Stream.of(<span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"c"</span>, <span class="string">"d"</span>).collect(<span class="keyword">new</span> JoinCollector()));</span><br></pre></td></tr></table></figure><p>得到的结果与<code>Collectors.joining</code>方法是一样的。</p>]]></content>
<summary type="html">
Java 8之Collector
</summary>
<category term="Java" scheme="http://irusist.github.io/categories/Java/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
<category term="Java" scheme="http://irusist.github.io/tags/Java/"/>
</entry>
<entry>
<title>Java 8之Optional</title>
<link href="http://irusist.github.io/2016/01/02/Java-8%E4%B9%8BOptional/"/>
<id>http://irusist.github.io/2016/01/02/Java-8之Optional/</id>
<published>2016-01-02T15:25:07.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>由于<code>NullPointerException</code>是Java开发中发生次数最多的一个异常, 所以在Java 8中提供了一个<code>Optional</code>类, 用来避免该异常的发生, 这个类类似于Scala中的<code>Option</code>。</p><p><code>Optional</code>类的所有构造方法都是<code>private</code>的,因此可以使用它的静态方法来初始化,如:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 用来生成一个空值的Optional</span></span><br><span class="line">Optional empty = Optional.empty();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 用来生成一个非空值的Optional</span></span><br><span class="line">Optional<String> notNull = Optional.of(<span class="string">"optional"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以根据传入的值生成空或非空的Optional</span></span><br><span class="line">Optional<String> nullValue = Optional.ofNullable(<span class="keyword">null</span>);</span><br></pre></td></tr></table></figure><a id="more"></a><p>可以使用<code>isPresent</code> 方法来判Optional内的值是否存在,如:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 返回 false</span></span><br><span class="line">System.out.println(Optional.empty().isPresent());</span><br><span class="line"></span><br><span class="line"><span class="comment">// 返回 true</span></span><br><span class="line">System.out.println(Optional.of(<span class="number">1</span>).isPresent());</span><br></pre></td></tr></table></figure><p>使用<code>get</code>方法获取Optional内的值,如果是<code>empty</code>,则抛出<code>NoSuchElementException</code>异常。</p><p>使用<code>ifPresent</code> 方法可以先判断这个值是否存在,如果存在,则 执行一个操作。</p><p><code>filter</code>, <code>map</code>, <code>flatMap</code>等方法与<code>Stream</code>的操作类似, 这里不再说明。</p><p><code>orElse</code> 方法接收一个与Optional类型一致的参数,表示如果这个<code>Optional</code>是empty,则返回这个传入的值。</p><p><code>orElseGet</code>方法接受一个<code>Supplier</code>接口,表示当<code>Optional</code>内的值不存在时,通过<code>Supplier</code>获取到这个值。</p><p><code>orElseThrow</code> 方法接受一个 <code>Supplier</code>接口,表示当<code>Optional</code>内的值不存在时,通过<code>Supplier</code> 获取到一个异常值,并抛出这个异常。</p>]]></content>
<summary type="html">
Java 8之Optional
</summary>
<category term="Java" scheme="http://irusist.github.io/categories/Java/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
<category term="Java" scheme="http://irusist.github.io/tags/Java/"/>
</entry>
<entry>
<title>Java 8之default方法</title>
<link href="http://irusist.github.io/2016/01/02/Java-8%E4%B9%8Bdefault%E6%96%B9%E6%B3%95/"/>
<id>http://irusist.github.io/2016/01/02/Java-8之default方法/</id>
<published>2016-01-02T14:26:14.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Java 8中可以在接口定义方法的实现, 称为default方法, 类似用于Scala中的<code>trait</code>, 在<code>Iterable</code>中有类似以下的定义</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">default</span> <span class="keyword">void</span> <span class="title">forEach</span><span class="params">(Consumer<? <span class="keyword">super</span> T> action)</span> </span>{</span><br><span class="line"> Objects.requireNonNull(action);</span><br><span class="line"> <span class="keyword">for</span> (T t : <span class="keyword">this</span>) {</span><br><span class="line"> action.accept(t);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>Iterable</code>中的default方法的主要目的是为Java 8的Lambda表达式提供支持, 如果将这个方法定义成普通接口方法,则会对现有的JDK中的其他使用<code>Iterable</code>接口造成影响, 因此提供了default方法的功能。</p><a id="more"></a><p>一个接口中可以定义多个default方法。 下面写个简单的例子说明下default方法的使用</p><p>存在一个父接口, 定义了一个default方法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Parent</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">default</span> String <span class="title">doIt</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"Parent"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>有一个类实现该接口,使用默认的default方法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ParentImpl</span> <span class="keyword">implements</span> <span class="title">Parent</span> </span>{</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>ParentImpl</code>有一个实现类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ParentImpl2</span> <span class="keyword">extends</span> <span class="title">ParentImpl</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">doIt</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"ParentImpl2"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>ParentImpl2</code>有一个实现类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ChildImpl2</span> <span class="keyword">extends</span> <span class="title">ParentImpl2</span> <span class="keyword">implements</span> <span class="title">Child</span> </span>{</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>有一个接口继承<code>Parent</code>接口</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Child</span> <span class="keyword">extends</span> <span class="title">Parent</span> </span>{</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 重写父接口的default方法</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> String</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">default</span> String <span class="title">doIt</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"Child"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>Child</code>有一个实现类,使用<code>Child</code>的default方法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ChildImpl</span> <span class="keyword">implements</span> <span class="title">Child</span> </span>{</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>以下为测试代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DefaultMethodTest</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"></span><br><span class="line"> Parent parent = <span class="keyword">new</span> ParentImpl();</span><br><span class="line"> <span class="comment">// default方法的实现类可以直接调用default方法</span></span><br><span class="line"> <span class="comment">// 输出 Parent</span></span><br><span class="line"> System.out.println(parent.doIt());</span><br><span class="line"></span><br><span class="line"> Child child = <span class="keyword">new</span> ChildImpl();</span><br><span class="line"> <span class="comment">// Child接口重写了Parent接口的default方法</span></span><br><span class="line"> <span class="comment">// 输出 Child</span></span><br><span class="line"> System.out.println(child.doIt());</span><br><span class="line"></span><br><span class="line"> <span class="comment">// ParentImpl2类重写了Parent接口的default方法</span></span><br><span class="line"> <span class="comment">// 输出 ParentImpl2</span></span><br><span class="line"> Parent parent1 = <span class="keyword">new</span> ParentImpl2();</span><br><span class="line"> System.out.println(parent1.doIt());</span><br><span class="line"></span><br><span class="line"> <span class="comment">// ChildImpl2父类与接口都有default方法, 使用类中定义的default方法</span></span><br><span class="line"> <span class="comment">// 输出 ParentImpl2</span></span><br><span class="line"> Child child1 = <span class="keyword">new</span> ChildImpl2();</span><br><span class="line"> System.out.println(child1.doIt());</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>通过以上的例子中可以得出以下几点:</p><ul><li><p>实现类可以直接使用父接口中定义的default方法</p></li><li><p>接口可以重写父接口中定义的default方法</p></li><li><p>实现类可以重写父接口中定义的default方法</p></li><li><p>当父类与父接口都存在default方法时, 使用父类中重写的default方法</p></li></ul><p>如果一个类实现了2个接口,这2个接口有相同的default方法签名时, 此时会编译失败, 必须在子类中重写这个default方法。</p>]]></content>
<summary type="html">
Java 8之default方法
</summary>
<category term="Java8" scheme="http://irusist.github.io/categories/Java8/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
<category term="Java" scheme="http://irusist.github.io/tags/Java/"/>
</entry>
<entry>
<title>Java 8之基本类型优化</title>
<link href="http://irusist.github.io/2016/01/02/Java-8%E4%B9%8B%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E4%BC%98%E5%8C%96/"/>
<id>http://irusist.github.io/2016/01/02/Java-8之基本类型优化/</id>
<published>2016-01-02T13:02:58.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>在Java中, 泛型必须使用引用类型, 而不能使用基本类型。 所以要表示基本类型的列表或者数组时, 必须使用对应基本类型的引用类型, 如<br><code>int</code>对应<code>Integer</code>, <code>long</code>对应<code>Long</code>等, 在基本类型与引用类型可以自动地装箱与拆箱, 但是会有一些性能损失。</p><p>在Java 8的Stream API中提供了<code>of</code>方法,如果传入基本类型的参数,内部其实得到的是一个引用类型的Stream。如下面代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 得到的是Integer类型的 Stream</span></span><br><span class="line">Stream<Integer> stream = Stream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br></pre></td></tr></table></figure><p>因此, Java 8的提供了一些专门针对基本类型优化的API,如 <code>IntStream</code>, <code>LongStream</code>, <code>DoubleStream</code>, 应该优先使用它们。</p><a id="more"></a><h2 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h2><p>定义基本类型的Stream, 可以使用<code>IntStream</code>, <code>LongStream</code>, <code>DoubleStream</code>的接口静态方法<code>of</code>, <code>range</code>, <code>empty</code>, 下面为例子</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个空的 IntStream</span></span><br><span class="line">IntStream empty = IntStream.empty();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建包含基本类型1, 2, 3的 IntStream</span></span><br><span class="line">IntStream intStream = IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个包含1到9的 IntStream</span></span><br><span class="line">IntStream range = IntStream.range(<span class="number">1</span>, <span class="number">10</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个包含1到10的 IntStream</span></span><br><span class="line">IntStream rangeClosed = IntStream.rangeClosed(<span class="number">1</span>, <span class="number">10</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个包含3的 IntStream</span></span><br><span class="line">IntStream generated = IntStream.generate(() -> <span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 得到一个无限循环的 IntStream, 值为 1, 3, 5, 7 ...</span></span><br><span class="line">IntStream infinite = IntStream.iterate(<span class="number">1</span>, operand -> operand + <span class="number">2</span>);</span><br></pre></td></tr></table></figure><p>也可以基于 int 数组创建 IntStream, 如</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span>[] array = <span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>};</span><br><span class="line"><span class="comment">// 包含整个数组的IntStream</span></span><br><span class="line">IntStream arrayStream = Arrays.stream(array);</span><br><span class="line"><span class="comment">// 包含数组的索引位置2开始,4结束(不包含)的IntStream</span></span><br><span class="line">IntStream rangeArray = Arrays.stream(array, <span class="number">2</span>, <span class="number">4</span>);</span><br></pre></td></tr></table></figure><h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><p>基本类型的Stream,内部使用的都是与基本类型相关的接口函数来进行操作, 进而避免装箱成相应的引用类型, <code>IntStream</code> 主要有以下几个操作方法</p><h3 id="filter方法"><a href="#filter方法" class="headerlink" title="filter方法"></a>filter方法</h3><p><code>filter</code>方法于过滤Stream中的数据,它接收一个 <code>IntPredicate</code> 接口, 它是一个 <code>int -> boolean</code> 的接口函数, 例子代码如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 2, 4, 6</span></span><br><span class="line">IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>).filter(elem -> elem % <span class="number">2</span> == <span class="number">0</span>).forEach(System.out::println);</span><br></pre></td></tr></table></figure><h3 id="map-方法"><a href="#map-方法" class="headerlink" title="map 方法"></a>map 方法</h3><p><code>map</code>方法主要是对Stream的元素进行某种映射,转换成另一个基本类型的值, 它接收一个 <code>IntUnaryOperator</code> 接口, 它是一个 <code>int -> int</code> 的函数接口,例子代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 10, 20, 30, 40, 50, 60, 70</span></span><br><span class="line">IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>).map(elem -> elem * <span class="number">10</span>).forEach(System.out::println);</span><br></pre></td></tr></table></figure><h3 id="mapToObj-方法"><a href="#mapToObj-方法" class="headerlink" title="mapToObj 方法"></a>mapToObj 方法</h3><p><code>mapToObj</code> 方法主要是将Stream中的元素进行装箱操作, 转换成一个引用类型的值, 它接收一个 <code>IntFunction</code> 接口, 它是一个 <code>int -> R</code> 的函数接口, 例子代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出a1, a2, a3, a4, a5, a6, a7</span></span><br><span class="line">IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>).mapToObj(elem -> <span class="string">"a"</span> + elem).forEach(System.out::println);</span><br></pre></td></tr></table></figure><h3 id="mapToLong-方法"><a href="#mapToLong-方法" class="headerlink" title="mapToLong 方法"></a>mapToLong 方法</h3><p><code>mapToLong</code> 方法是将Stream中的 元素转换成基本类型<code>long</code>, 它接收一个 <code>IntToLongFunction</code> 接口, 它是一个 <code>int -> long</code> 的函数接口, 例子代码如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 100, 200, 300, 400, 500, 600, 700</span></span><br><span class="line">IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>).mapToLong(elem -> elem * <span class="number">100L</span>).forEach(System.out::println);</span><br></pre></td></tr></table></figure><h3 id="mapToDouble-方法"><a href="#mapToDouble-方法" class="headerlink" title="mapToDouble 方法"></a>mapToDouble 方法</h3><p><code>mapToDouble</code> 方法是将Stream中的 元素转换成基本类型<code>double</code>, 它接收一个 <code>IntToDoubleFunction</code> 接口, 它是一个 <code>int -> double</code> 的函数接口, 例子代码如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1</span></span><br><span class="line">IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>).mapToDouble(elem -> elem + <span class="number">0.1</span>).forEach(System.out::println);</span><br></pre></td></tr></table></figure><h3 id="min-方法"><a href="#min-方法" class="headerlink" title="min 方法"></a>min 方法</h3><p><code>min</code> 方法获取Stream中最小的元素, 它返回 <code>OptionalInt</code> 类型, 它是一个int版的<code>Optional</code>, 同样是为了避免拆箱装箱操作。 示例代码如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出 1</span></span><br><span class="line">System.out.println(IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>).min().getAsInt());</span><br></pre></td></tr></table></figure><h3 id="summaryStatistics-方法"><a href="#summaryStatistics-方法" class="headerlink" title="summaryStatistics 方法"></a>summaryStatistics 方法</h3><p><code>summaryStatistics</code> 方法主要是获取Stream中元素的统计信息, 它返回 <code>IntSummaryStatistics</code>, 示例代码如下:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">IntSummaryStatistics summary = IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">10</span>).summaryStatistics();</span><br><span class="line"><span class="comment">// 输出 1</span></span><br><span class="line">System.out.println(summary.getMin());</span><br><span class="line"><span class="comment">// 输出 10</span></span><br><span class="line">System.out.println(summary.getMax());</span><br><span class="line"><span class="comment">// 输出 55</span></span><br><span class="line">System.out.println(summary.getSum());</span><br><span class="line"><span class="comment">// 输出 10</span></span><br><span class="line">System.out.println(summary.getCount());</span><br><span class="line"><span class="comment">// 输出 5.5</span></span><br><span class="line">System.out.println(summary.getAverage());</span><br></pre></td></tr></table></figure><p>此外, 还有 <code>flatMap</code>, <code>distinct</code>, <code>sorted</code>, <code>peek</code>, <code>limit</code>, <code>skip</code>, <code>forEach</code>, <code>reduce</code>, <code>collect</code>, <code>anyMatch</code>, <code>allMatch</code>, <code>noneMatch</code>等方法, 与<code>Stream</code>的方法都差不多。</p>]]></content>
<summary type="html">
Java 8之基本类型优化
</summary>
<category term="Java8" scheme="http://irusist.github.io/categories/Java8/"/>
<category term="Java8" scheme="http://irusist.github.io/tags/Java8/"/>
</entry>
<entry>
<title>2015年终总结</title>
<link href="http://irusist.github.io/2015/12/31/2015%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/"/>
<id>http://irusist.github.io/2015/12/31/2015年终总结/</id>
<published>2015-12-31T12:20:51.000Z</published>
<updated>2017-11-06T15:29:11.000Z</updated>
<content type="html"><![CDATA[<p>今天是2015年的最后一天, 这一年总体感觉就是各种不顺, 无论生活还是工作, 感觉总是很压抑.</p><h2 id="生活"><a href="#生活" class="headerlink" title="生活"></a>生活</h2><p>今年唯一比较庆幸的是女儿在年初的时候出生了, 她给我带来了很多幸福, 虽然分开两地, 每次也只有节假日回去的那几天, 可每每想到她的笑脸,瞬间感觉就算再大的委屈也要咽下去, 我相信未来的路一定很美好, 因为我还有父母, 妻子, 女儿, 他们才是我的一切.</p><a id="more"></a><p>就在今年, 爷爷奶奶相继去世了. 虽然这几年, 他们对我们家远远不如其他的叔叔家, 关系也不是那么好, 可是又少了2个亲人, 心情很低落. 人生真是无常啊, 有时候总觉得有些事情, 放一放以后再做, 可是谁又能确保这一放, 以后是否就真的还有机会呢. 人生总是有那么多因错过机会而遗憾的事情, 唯一能做的也就只有把握当下, 抓住每一个机会.</p><p>然后就是房子, 去年就已经签完合同, 本来合同是今年6月份拿房的, 开发商一而再地延期, 并且赔偿金也少得可怜, 维权也没什么后果, 我们都是小人物, 这么大的国家, 难道政府就看着这种现象不断发生, 一点也不考虑制约吗.</p><h2 id="工作-事业"><a href="#工作-事业" class="headerlink" title="工作, 事业"></a>工作, 事业</h2><p>今年的工作好像也没什么进展, 我是个比较内向的人, 不会讲一些好听的话, 也不喜欢做一些唯心的事, 自然也得到某些领导的赏识. 尽职尽责地工作, 可有些时候, 你做得好了反而没有了存在感.在很多公司, 员工的薪水往往是由他们是否被分配到重点项目决定的, 你再有本事, 分点不痛不痒的项目, 你也只能在那天天干瞪眼消磨时间. 某些人就算能力低, 分个重点项目, 就算做得漏洞百出,反而会得到重视. </p><p>一直都向往着一份工作便是一份事业, 有志同道合的同事, 朝着共同的目标努力. 俗话说得好, 机会是留给有准备的人, 我相信总会有那样的机会在未来等着我.</p><h2 id="学习"><a href="#学习" class="headerlink" title="学习"></a>学习</h2><p>技术上主要还是以Java为主, 重温了JVM相关的一些内容, 自发地做了一个分布式跟踪系统, 使用了HBase, 因此对HBase也相应地有了一些了解. 对Scala和Golang零零散散地学习了一些知识.网络方面对Netty有一定了解, Linux系统也在持续学习及应用中.</p><p>明年决定对Scala和Golang系统地学习下, 并写点东西, 数据库相关的内容也要彻底深入地学习下. 对分布式和架构方面也要持续不断地学习. 对NodeJs和Spark也要了解了解.</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>无论2015年如何, 它毕竟已经要过去了, 我相信2016年总会更好的, 因为每个人的命运都是掌握在自己手中. </p>]]></content>
<summary type="html">
2015年终总结
</summary>
<category term="总结" scheme="http://irusist.github.io/categories/%E6%80%BB%E7%BB%93/"/>
<category term="总结" scheme="http://irusist.github.io/tags/%E6%80%BB%E7%BB%93/"/>
</entry>
</feed>