<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5682856111471502603</id><updated>2012-02-02T16:13:21.150+04:00</updated><category term='i/o'/><category term='xml'/><category term='media'/><category term='math'/><category term='idea'/><category term='reflection'/><category term='scala'/><category term='ant'/><category term='jdbc'/><category term='swing'/><category term='junit'/><category term='aop'/><category term='maven'/><category term='projecteuler'/><category term='music'/><category term='serialization'/><category term='tomcat'/><category term='regexp'/><category term='aspectj'/><category term='bash'/><category term='oracle'/><category term='jws'/><category term='threading'/><category term='sc2'/><category term='mtgo'/><category term='jni'/><category term='certification'/><category term='travel'/><category term='js'/><category term='opensource'/><category term='groovy'/><category term='society'/><category term='software'/><category term='generics'/><category term='spring'/><category term='uml'/><category term='pets'/><category term='jnlp'/><category term='fun'/><category term='eclipse'/><category term='collections'/><category term='ubuntu'/><category term='jms'/><category term='profiling'/><category term='empathy'/><category term='ide'/><category term='visualvm'/><category term='ioc'/><title type='text'>programming addicted</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>88</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-5709896125985083219</id><published>2012-01-06T22:57:00.011+04:00</published><updated>2012-01-09T21:46:04.037+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><title type='text'>Exploring the world: Eclipse after IntelliJ</title><content type='html'>&lt;span style="font-weight:bold;"&gt;updated on 09.01.2012&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've been an &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; fan for quite a long time but there are pretty many buddies at the web who are happy with &lt;a href="http://eclipse.org"&gt;eclipse&lt;/a&gt;. Having my knowledge of the basic IntelliJ facilities improved significantly by working at the IntelliJ Core team, I've decided to try using eclipse at home for a while and build own opinion about it.&lt;br /&gt;&lt;br /&gt;This post is expected to be expanded as I spend more time with eclipse and collect more information about it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#editor"&gt;editor&lt;/a&gt;;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#editor-braces-txt"&gt;- Highlighting braces at the txt files&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#call-action-speed-search"&gt;- Call action by name&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#editor-appearance"&gt;- Appearance&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#maven"&gt;maven&lt;/a&gt;;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#maven-pom-ui"&gt;+ UI for pom.xml&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#maven-dependencies"&gt;+ Adding maven dependencies&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="editor"&gt;Editor&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;h5&gt;&lt;a name="editor-braces-txt"&gt;Highlighting braces at the txt files&lt;/a&gt;&lt;/h5&gt;&lt;br /&gt;Haven't found a way to teach eclipse to highlight matched braces at the plain text file. IntelliJ does that perfectly (fixed couple of bugs at that area myself :) ):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-Kq-G83yK_Ec/TwgzMyhd1zI/AAAAAAAAAZI/OdOnFVrSwa0/s1600/braces-txt-intellij.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 222px;" src="http://3.bp.blogspot.com/-Kq-G83yK_Ec/TwgzMyhd1zI/AAAAAAAAAZI/OdOnFVrSwa0/s320/braces-txt-intellij.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5694858023623579442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;&lt;a name="call-action-speed-search"&gt;Call action by name&lt;/a&gt;&lt;/h5&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;'Call action by name'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Ctrl+Shift+L'&lt;/span&gt; in eclipse) supports speed search at IntelliJ. I.e. it's possible to start typing a name and the actions list is automatically trimmed:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-1Bdoe0XjCwk/TwgyZyev28I/AAAAAAAAAY8/hqRAP0JWqRc/s1600/call-action-intellij.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 167px;" src="http://1.bp.blogspot.com/-1Bdoe0XjCwk/TwgyZyev28I/AAAAAAAAAY8/hqRAP0JWqRc/s320/call-action-intellij.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5694857147438848962" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h5&gt;&lt;a name="editor-appearance"&gt;Appearance&lt;/a&gt;&lt;/h5&gt;&lt;br /&gt;Imho, eclipse doesn't provide enough visual separation between editing area and auxiliary information like line numbers, foldings etc:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;eclipse&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-EKLmITz-BZk/Twsm2cLJrSI/AAAAAAAAAg0/N6sDNLFEji0/s1600/editor-appearance-eclipse.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 54px;" src="http://4.bp.blogspot.com/-EKLmITz-BZk/Twsm2cLJrSI/AAAAAAAAAg0/N6sDNLFEji0/s320/editor-appearance-eclipse.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5695688870457879842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The same code looks as follows at the intellij:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-7aAt0xVH3fU/TwsnpGospdI/AAAAAAAAAhA/iPjbsCpNyBo/s1600/editor-appearance-intellij.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 54px;" src="http://2.bp.blogspot.com/-7aAt0xVH3fU/TwsnpGospdI/AAAAAAAAAhA/iPjbsCpNyBo/s320/editor-appearance-intellij.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5695689740849554898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="maven"&gt;Maven&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;h5&gt;&lt;a name="maven-pom-ui"&gt;UI for pom.xml&lt;/a&gt;&lt;/h5&gt;&lt;br /&gt;I like the additional pom.xml UI provided by eclipse:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-zCOxsVW-H94/TwgsmABoI8I/AAAAAAAAAYY/kgbD0GbqcAg/s1600/pom-views-eclipse.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 222px;" src="http://3.bp.blogspot.com/-zCOxsVW-H94/TwgsmABoI8I/AAAAAAAAAYY/kgbD0GbqcAg/s320/pom-views-eclipse.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5694850760163468226" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;&lt;a name="maven-dependencies"&gt;Adding maven dependencies&lt;/a&gt;&lt;/h5&gt;&lt;br /&gt;It's much more convenient to add new maven dependencies at eclipse:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-tmEWQ9Irf1U/TwgtxSTiWzI/AAAAAAAAAYk/wTQyF6-m9L4/s1600/maven-new-dependency-eclipse.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 312px;" src="http://2.bp.blogspot.com/-tmEWQ9Irf1U/TwgtxSTiWzI/AAAAAAAAAYk/wTQyF6-m9L4/s320/maven-new-dependency-eclipse.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5694852053560613682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;it's possible to do that via UI;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;completion is provided;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;the dependency is automatically added to the pom.xml;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;IntelliJ also allows to do that but the facilities are not so productive:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-lFyFEXVxqX8/TwgutYtnstI/AAAAAAAAAYw/4KnFOZ-wox4/s1600/maven-new-dependency-intellij.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 261px;" src="http://3.bp.blogspot.com/-lFyFEXVxqX8/TwgutYtnstI/AAAAAAAAAYw/4KnFOZ-wox4/s320/maven-new-dependency-intellij.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5694853086072779474" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-5709896125985083219?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/5709896125985083219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5709896125985083219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5709896125985083219'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2012/01/exploring-world-eclipse-after-intellij.html' title='Exploring the world: Eclipse after IntelliJ'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Kq-G83yK_Ec/TwgzMyhd1zI/AAAAAAAAAZI/OdOnFVrSwa0/s72-c/braces-txt-intellij.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-223666321476499541</id><published>2011-08-04T17:32:00.002+04:00</published><updated>2011-08-04T17:34:30.433+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swing'/><title type='text'>Swing color keys</title><content type='html'>Always forget about the place to check available Swing LAF property keys (like text box text foreground, label background etc). Here it is - &lt;a href="http://kickjava.com/src/javax/swing/plaf/basic/BasicLookAndFeel.java.htm"&gt;BasicLookAndFeel&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-223666321476499541?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/223666321476499541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/08/swing-color-keys.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/223666321476499541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/223666321476499541'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/08/swing-color-keys.html' title='Swing color keys'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-4599170401985295661</id><published>2011-08-02T14:50:00.003+04:00</published><updated>2011-11-02T12:09:45.432+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Closing Empathy chat by 'escape;</title><content type='html'>Standard shortcut for closing &lt;a href="http://live.gnome.org/Empathy"&gt;empathy&lt;/a&gt; chat tab is &lt;span style="font-style:italic;"&gt;'Ctrl+W'&lt;/span&gt;. Thanks God, it's possible to reassign it to &lt;span style="font-style:italic;"&gt;'escape'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Open /usr/share/empathy/empathy-chat-window.ui;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Change &lt;span style="font-style:italic;"&gt;'&amp;lt;accelerator key="W" modifiers="GDK_CONTROL_MASK"/&amp;gt;'&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;'&amp;lt;accelerator key="Escape" /&amp;gt;'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-4599170401985295661?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/4599170401985295661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/08/closing-empathy-chat-by-escape.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4599170401985295661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4599170401985295661'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/08/closing-empathy-chat-by-escape.html' title='Closing Empathy chat by &apos;escape;'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-1958416915760251168</id><published>2011-07-28T17:18:00.002+04:00</published><updated>2011-07-28T17:23:16.305+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='empathy'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Empathy opens hyperlinks at new browser window</title><content type='html'>Started using &lt;a href="http://live.gnome.org/Empathy"&gt;empathy&lt;/a&gt; recently. So far so good except for the one annoying feature - every time I click hyperlink at the messenger's window it starts firefox (though I use chrome) and displays it there.&lt;br /&gt;&lt;br /&gt;It looks like chrome guys didn't handle properly 'set chrome as default browser' option. Go to 'System - Preferences - Preferred Applications' and ensure that the desired browser is set at 'Web Browser' there (firefox was there in my case).&lt;br /&gt;&lt;br /&gt;Everything works fine after setting 'chrome' there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-1958416915760251168?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/1958416915760251168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/07/empathy-opens-hyperlinks-at-new-browser.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/1958416915760251168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/1958416915760251168'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/07/empathy-opens-hyperlinks-at-new-browser.html' title='Empathy opens hyperlinks at new browser window'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-3404604958442473309</id><published>2011-07-26T13:06:00.013+04:00</published><updated>2011-12-30T13:22:22.955+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>IntelliJ IDEA: from Windows to Linux</title><content type='html'>Default IntelliJ IDEA keymap contains number of shortcuts that conflict with standard Gnome shortcuts. It's possible to use the dedicated 'Gnome' keymap inside the IDE but I've used the standard keymap for a while and don't want to change my fingertips memory.&lt;br /&gt;&lt;br /&gt;Here is a the list of the conflicting Gnome actions I've encountered:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;System | Preferences | Windows&lt;/span&gt;&lt;br /&gt;1. Disable alt+click over window (system - preferences - windows)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;System | Preferences | Keyboard Shortcuts&lt;/span&gt;&lt;br /&gt;1. Show the panel's main menu - alt+f1;&lt;br /&gt;2. Switch to workspace on the left/right' - 'ctrl+alt+left/right';&lt;br /&gt;3. Lock screen - 'ctrl + alt + L'&lt;br /&gt;4. Move window - 'alt + f7'&lt;br /&gt;5. Resize window - 'alt + f8'&lt;br /&gt;6. Run a terminal - 'ctrl + alt + t'&lt;br /&gt;7. Minimize window - 'alt + f9'&lt;br /&gt;8. Toggle maximization state - 'alt + f10'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-3404604958442473309?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/3404604958442473309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/07/intellij-idea-from-windows-to-linux.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3404604958442473309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3404604958442473309'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/07/intellij-idea-from-windows-to-linux.html' title='IntelliJ IDEA: from Windows to Linux'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2650297278276742834</id><published>2011-07-05T19:49:00.002+04:00</published><updated>2011-07-05T19:50:58.910+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Fanboys!</title><content type='html'>Couldn't resist:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-R6MNjR2z-7I/ThMyuBKFpmI/AAAAAAAAATs/6r7WYkB6_qU/s1600/programming-languages-fanboys.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 210px;" src="http://3.bp.blogspot.com/-R6MNjR2z-7I/ThMyuBKFpmI/AAAAAAAAATs/6r7WYkB6_qU/s320/programming-languages-fanboys.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5625896125682001506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/--YnUyQQjxbc/ThMy0Y5ouqI/AAAAAAAAAT0/dP6f7nX1J_Q/s1600/os-fanboy.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 234px;" src="http://3.bp.blogspot.com/--YnUyQQjxbc/ThMy0Y5ouqI/AAAAAAAAAT0/dP6f7nX1J_Q/s320/os-fanboy.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5625896235134663330" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2650297278276742834?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2650297278276742834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/07/fanboys.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2650297278276742834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2650297278276742834'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/07/fanboys.html' title='Fanboys!'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-R6MNjR2z-7I/ThMyuBKFpmI/AAAAAAAAATs/6r7WYkB6_qU/s72-c/programming-languages-fanboys.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-8648741453424702606</id><published>2011-04-20T20:22:00.012+04:00</published><updated>2011-05-08T14:20:17.345+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - column mode</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2011/04/idea-candy-column-mode.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2011/04/idea-candy-column-mode.html#column-mode"&gt;Column mode editing&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;IntelliJ IDEA contains uncountable number of features and most of them are unknown to the end-users. I'm going to talk about one of them that is quite useful under some circumstances.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="column-mode"&gt;Column mode editing&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's rather often that we want to perform similar action on a number of subsequent lines. For example we may have a private static class that was used internally and holds data at public final fields. Let's imagine that we want to make it public and change fields visibility from 'public' to 'private' and provide corresponding getters. The later can be done quickly via &lt;a href="http://www.jetbrains.com/idea/webhelp/generating-getters-and-setters.html"&gt;'generate getters'&lt;/a&gt; feature and the former can be achieved by the following:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Select target modifiers at &lt;a href="http://www.jetbrains.com/idea/webhelp/selecting-text-in-the-editor.html"&gt;column mode&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Type 'private';&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Here is a small video that illustrates that:&lt;br /&gt;&lt;object style="height: 390px; width: 640px"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7NqW7Sshpks?version=3"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/7NqW7Sshpks?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;It's also possible to perform column selection by left mouse button holding &lt;span style="font-style:italic;"&gt;Alt&lt;/span&gt;. In example below we have a newly introduced method that overloads existing one and uses default value as the one of the arguments. Javadoc stub is generated by IntelliJ and we want to copy description from the remained parameters. The algorithm is pretty simple:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Copy target parameters description at 'column mode';&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Start column mode in a place where we want to perform 'paste';&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Perform paste;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;object style="height: 390px; width: 640px"&gt;&lt;param name="movie" value="http://www.youtube.com/v/GGkG7TJNpKA?version=3"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/GGkG7TJNpKA?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;One more use-case - copying to external application. IntelliJ IDEA provides &lt;a href="http://www.jetbrains.com/idea/webhelp/editor-smart-keys.html"&gt;'Reformat on paste'&lt;/a&gt; feature that automatically adapts pasted text to the current context. However, that is not the case for external applications. So, we can select the text at column mode in order to avoid unnecessary indentation then:&lt;br /&gt;&lt;object style="height: 390px; width: 640px"&gt;&lt;param name="movie" value="http://www.youtube.com/v/5QQnrH3pE9Q?version=3"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/5QQnrH3pE9Q?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-8648741453424702606?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/8648741453424702606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/04/idea-candy-column-mode.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8648741453424702606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8648741453424702606'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/04/idea-candy-column-mode.html' title='IDEA candy - column mode'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-7336314086633653927</id><published>2011-04-19T21:38:00.007+04:00</published><updated>2011-04-19T22:13:47.976+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - custom context menu</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2011/04/idea-candy-custom-context-menu.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2011/04/idea-candy-custom-context-menu.html#tip"&gt;The tip&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;IDEA provides a great number of features and is very customizable. Today I'm going to talk about ability to customize context menus for your needs and reduce necessity to use a mouse even more.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="tip"&gt;The tip&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Suppose you use particular actions rather often and want to be able to invoke them quickly. One solution is to assign dedicated shortcut to every action but number of convenient key combinations is not too big and most of them are already assigned to the useful actions. IntelliJ IDEA has a solution for that - &lt;a href="http://www.jetbrains.com/idea/webhelp/configuring-quick-lists.html"&gt;custom quick lists&lt;/a&gt;. Here is a detailed instruction:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Say, I realize that I frequently use set of vcs-related operations. I want to be able to call them quickly. First of all, create new custom quick list:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-UraplLiXjsg/Ta3NYLnl3MI/AAAAAAAAASQ/DnPnwhgo6OA/s1600/new-quick-list.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/-UraplLiXjsg/Ta3NYLnl3MI/AAAAAAAAASQ/DnPnwhgo6OA/s320/new-quick-list.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5597355727210798274" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Next step is to assign that newly created quick list to the convenient shortcut. My choice is 'Ctrl+Shift+Q' because it's rather convenient and is not used at default IDEA keymap:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-Grevn7CTiVs/Ta3OjAujsvI/AAAAAAAAASY/L7ZkdWolK3Q/s1600/quick-list.shortcut.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/-Grevn7CTiVs/Ta3OjAujsvI/AAAAAAAAASY/L7ZkdWolK3Q/s320/quick-list.shortcut.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5597357012777415410" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Save the changes and we're done. Now it's possible to quickly invoke all of the actions configured for the quick list. Press assigned shortcut ('Ctrl+Shift+Q' at our example) and custom context menu appears:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-WxqA4IP_UAc/Ta3PuyO_AkI/AAAAAAAAASg/ky-B8WFFfHA/s1600/quick-list-context-menu.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/-WxqA4IP_UAc/Ta3PuyO_AkI/AAAAAAAAASg/ky-B8WFFfHA/s320/quick-list-context-menu.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5597358314556949058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;The feature becomes very useful when you get accustomed to it a little. For example, I automatically press the following sequence to see file history: &lt;span style="font-style:italic;"&gt;'Ctrl+Shift+Q Enter'&lt;/span&gt;; &lt;span style="font-style:italic;"&gt;'Ctrl+Shift+Q down Enter'&lt;/span&gt; for 'annotate' etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-7336314086633653927?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/7336314086633653927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/04/idea-candy-custom-context-menu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7336314086633653927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7336314086633653927'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/04/idea-candy-custom-context-menu.html' title='IDEA candy - custom context menu'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-UraplLiXjsg/Ta3NYLnl3MI/AAAAAAAAASQ/DnPnwhgo6OA/s72-c/new-quick-list.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-3323554283662437676</id><published>2011-04-15T14:51:00.002+04:00</published><updated>2011-04-19T15:55:07.202+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>The Black Keys</title><content type='html'>Recently found these guys. Like them very much so far:&lt;br /&gt;&lt;br /&gt;&lt;object style="height: 390px; width: 640px"&gt;&lt;param name="movie" value="http://www.youtube.com/v/_LWBt9TVxOY?version=3"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/_LWBt9TVxOY?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-3323554283662437676?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/3323554283662437676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/04/black-keys.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3323554283662437676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3323554283662437676'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2011/04/black-keys.html' title='The Black Keys'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-4940165942467962171</id><published>2010-12-09T17:15:00.001+03:00</published><updated>2010-12-09T17:17:38.119+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>Intellij IDEA X is here</title><content type='html'>First release of the most intelligent IDE made with my active participation is here - &lt;a href="http://blogs.jetbrains.com/idea/2010/12/intellij-idea-10-released-new-decade-of-evolution-ahead/"&gt;IntelliJ IDEA 10 Released. New Decade of Evolution Ahead&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-4940165942467962171?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/4940165942467962171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/12/intellij-idea-x-is-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4940165942467962171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4940165942467962171'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/12/intellij-idea-x-is-here.html' title='Intellij IDEA X is here'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-7990589723637816337</id><published>2010-09-24T15:16:00.002+04:00</published><updated>2010-09-24T15:20:51.955+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sc2'/><title type='text'>Free time</title><content type='html'>Sorry for being absent here for so long. Blizzard released StartCraft II eventually and I'm completely lost there :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/TJyJgsVzt_I/AAAAAAAAAQ0/4bxjkybm7F4/s1600/sc2-state.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 158px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/TJyJgsVzt_I/AAAAAAAAAQ0/4bxjkybm7F4/s320/sc2-state.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5520438438000834546" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-7990589723637816337?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/7990589723637816337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/09/free-time.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7990589723637816337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7990589723637816337'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/09/free-time.html' title='Free time'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wBtqK4BXFZc/TJyJgsVzt_I/AAAAAAAAAQ0/4bxjkybm7F4/s72-c/sc2-state.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-111145976935096838</id><published>2010-07-02T21:28:00.005+04:00</published><updated>2010-07-02T21:44:58.199+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - find usages trick</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/07/idea-candy-find-usages-trick.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/07/idea-candy-find-usages-trick.html#trick"&gt;The trick&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;I rather often use &lt;span style="font-style:italic;"&gt;'Find Usages'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Alt+F7'&lt;/span&gt;) at IDEA. I like it more than &lt;span style="font-style:italic;"&gt;'Show Usages'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Ctrl+Alt+F7'&lt;/span&gt;) because the former keeps search results and it's possible to navigate between them easily without necessity to repeat the search.&lt;br /&gt;&lt;br /&gt;However, this functionality may be configured in a way to get even better user experience.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="trick"&gt;The trick&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's not too seldom to get a single result from &lt;span style="font-style:italic;"&gt;'Find Usages'&lt;/span&gt; and it's not convenient to view separate panel with it then:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/TC4jLZQ2scI/AAAAAAAAAQA/wU_wqsxT_eo/s1600/find-usages1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 218px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/TC4jLZQ2scI/AAAAAAAAAQA/wU_wqsxT_eo/s320/find-usages1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489363674478326210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I never noticed that we can configure &lt;span style="font-style:italic;"&gt;'Find Usages'&lt;/span&gt; dialog in order to get a better behavior exactly at situation like this - there is a small check box at the dialog shown when you press &lt;span style="font-style:italic;"&gt;'Alt+F7'&lt;/span&gt; - &lt;span style="font-style:italic;"&gt;'Skip results tab with one usage'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/TC4kLI4MVFI/AAAAAAAAAQI/N14zMvuFNVs/s1600/find-usages2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/TC4kLI4MVFI/AAAAAAAAAQI/N14zMvuFNVs/s320/find-usages2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489364769591546962" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's perform the search now and IDE directly points us to the single found match:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/TC4lEnro4PI/AAAAAAAAAQQ/XktX0BXx7uQ/s1600/find-usages3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 218px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/TC4lEnro4PI/AAAAAAAAAQQ/XktX0BXx7uQ/s320/find-usages3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489365757112934642" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-111145976935096838?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/111145976935096838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/07/idea-candy-find-usages-trick.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/111145976935096838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/111145976935096838'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/07/idea-candy-find-usages-trick.html' title='IDEA candy - find usages trick'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wBtqK4BXFZc/TC4jLZQ2scI/AAAAAAAAAQA/wU_wqsxT_eo/s72-c/find-usages1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2193042340868592948</id><published>2010-07-02T20:28:00.008+04:00</published><updated>2010-07-02T21:26:08.724+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - Highlighting by exception</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/07/idea-candy-highlighting-by-exception.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/07/idea-candy-highlighting-by-exception.html#throws"&gt;From 'throws'&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/07/idea-candy-highlighting-by-exception.html#catch"&gt;From 'catch'&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's been quite a long time since I wrote here last time. The reason is quite simple - I work hard on a new exciting IDEA feature - &lt;a href="http://youtrack.jetbrains.net/issue/IDEA-53596"&gt;soft wraps&lt;/a&gt; and spend most of my free time to rewriting &lt;a href="http://text-colorer.appspot.com/"&gt;syntax highlighter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I became &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; fun as I started to use it at work, so, the highlighter is hosted on &lt;a href="https://github.com/"&gt;github&lt;/a&gt; now - &lt;a href="http://github.com/denis-zhdanov/web-view"&gt;web-view&lt;/a&gt;.&lt;br /&gt;It's main features are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;pleasant UI;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;performance;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I'll provide more details about the project as the first milestone is over.&lt;br /&gt;&lt;br /&gt;Anyway, I want to continue my blogging activity and going to talk about new cool IDEA features I encountered recently.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="throws"&gt;From 'throws'&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's rather common situtation when you see a method that declares multiple exceptions at &lt;span style="font-style:italic;"&gt;'throws'&lt;/span&gt; clause but you don't have a clue on what expresssions may actually throw them. IDEA can provide information about that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Example.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Consider that you have a code like the one below:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; java.io.FileNotFoundException;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; java.net.SocketException;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jul 2, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; TestClass {&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test() &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; FileNotFoundException, SocketException {&lt;br /&gt;        method1();&lt;br /&gt;        method2();&lt;br /&gt;        method3();&lt;br /&gt;        method4();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; method1() &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; FileNotFoundException {}&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; method2() &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; SocketException {}&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; method3() &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; SocketException {}&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; method4() &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; FileNotFoundException {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You can see that &lt;span style="font-style:italic;"&gt;'test()'&lt;/span&gt; method declares two checked exceptions at &lt;span style="font-style:italic;"&gt;'throws'&lt;/span&gt; clause but it may be hard to understand what expressions may throw it, especially if method body is rather large and involves calls to other classes.&lt;br /&gt;&lt;br /&gt;It's possible to do the following to relief the analysis:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Put caret on method's &lt;span style="font-style:italic;"&gt;'throws'&lt;/span&gt; clause;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Press &lt;span style="font-style:italic;"&gt;'Ctrl+Shift+F7'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Highlight usages in a file'&lt;/span&gt;);&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Result:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4aBI45TII/AAAAAAAAAPg/mttY1OPxar8/s1600/highlight-throws1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 134px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4aBI45TII/AAAAAAAAAPg/mttY1OPxar8/s320/highlight-throws1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489353602679524482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We need to decide what exactly should be highlighted. The options are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;highlight all expressions that may throw checked exceptions declared at &lt;span style="font-style:italic;"&gt;'throws'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;highlight expressions that may throw checked exception of particular type;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Let's highlight, for example, all expressions that may throw &lt;span style="font-style:italic;"&gt;FileNotFoundException&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4bCWQMwoI/AAAAAAAAAPo/WU5VM5_ai2g/s1600/highlight-throws2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 130px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4bCWQMwoI/AAAAAAAAAPo/WU5VM5_ai2g/s320/highlight-throws2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489354722958426754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;IDEA also supports &lt;span style="font-style:italic;"&gt;IS-A&lt;/span&gt; relation during highlighting. E.g. all expressions that may throw &lt;span style="font-style:italic;"&gt;FileNotFoundExceptions&lt;/span&gt; are highlighted when we ask to show expressions that may throw &lt;span style="font-style:italic;"&gt;IOException&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4b8wSiqJI/AAAAAAAAAPw/G-fAKUuYnY8/s1600/highlight-throws3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 136px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4b8wSiqJI/AAAAAAAAAPw/G-fAKUuYnY8/s320/highlight-throws3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489355726379985042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="catch"&gt;From 'catch'&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Similar capability for highlighting expressions by checked exception they may throw is provided for &lt;span style="font-style:italic;"&gt;'catch'&lt;/span&gt; blocks. Just put caret on a &lt;span style="font-style:italic;"&gt;'catch'&lt;/span&gt; keyword of the target clause and press &lt;span style="font-style:italic;"&gt;'Ctrl+Shift+F7'&lt;/span&gt;. Result:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/TC4fde_vu7I/AAAAAAAAAP4/eC4Vg5pyuwo/s1600/highlight-catch1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 181px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/TC4fde_vu7I/AAAAAAAAAP4/eC4Vg5pyuwo/s320/highlight-catch1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5489359587208313778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;P.S. I already adopted all IDEA features discovered during working at JetBrains and use them all the time. It's hard to imagine how to live without &lt;span style="font-style:italic;"&gt;'Step Into'&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;'Step to Cursor'&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt; etc :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2193042340868592948?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2193042340868592948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/07/idea-candy-highlighting-by-exception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2193042340868592948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2193042340868592948'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/07/idea-candy-highlighting-by-exception.html' title='IDEA candy - Highlighting by exception'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wBtqK4BXFZc/TC4aBI45TII/AAAAAAAAAPg/mttY1OPxar8/s72-c/highlight-throws1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-4805839100488634476</id><published>2010-05-26T22:39:00.005+04:00</published><updated>2010-05-26T23:14:18.507+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - Harnessing debugger</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-harnessing-debugger.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-harnessing-debugger.html#smart-step-into"&gt;Smart step into&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-harnessing-debugger.html#run-to-cursor"&gt;Run to cursor&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;This article contains convenient tricks that may be used during debugging under IDEA. I've been IDEA user for more than five years but got know about them only today. They are so cool that I believe I use them all the time now.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="smart-step-into"&gt;Smart step into&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;There is a possible situation that break point is set for the statement that contains multiple method calls. Consider example below:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; com.spring.example.test;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; MyTest {&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(String[] args) {&lt;br /&gt;        MyTest test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; MyTest();&lt;br /&gt;        test.bar(test.baz(test), test.foo());&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(test.foo());&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(test);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; MyTest foo() {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;&lt;span style="color:#660e7a;font-weight:bold;"&gt;this&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; MyTest bar(MyTest ... t) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;&lt;span style="color:#660e7a;font-weight:bold;"&gt;this&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; MyTest baz(MyTest t) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; t;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can set break point to the line containing statement &lt;span style="font-style:italic;"&gt;'test.bar(test.baz(test), test.foo());'&lt;/span&gt;, start the application and wait for break point hit.&lt;br /&gt;&lt;br /&gt;We can go into method body now via &lt;span style="font-style:italic;"&gt;'Step Into'&lt;/span&gt; action (&lt;span style="font-style:italic;"&gt;'F7'&lt;/span&gt; shortcut), however, we'll be dispatched to the first method body (&lt;span style="font-style:italic;"&gt;'bar()'&lt;/span&gt;). It's possible that we want to proceed to &lt;span style="font-style:italic;"&gt;'foo()'&lt;/span&gt;/&lt;span style="font-style:italic;"&gt;'baz()'&lt;/span&gt; instead.&lt;br /&gt;&lt;br /&gt;I used to do the following at such situations - skip any number of uninteresting calls via performing &lt;span style="font-style:italic;"&gt;'Step Into'&lt;/span&gt; + &lt;span style="font-style:italic;"&gt;'Step Out'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Shift + F8'&lt;/span&gt;). I was really surprised that IDEA provides much more convenient way to manage that - &lt;span style="font-style:italic;"&gt;'Main Menu -&gt; Run -&gt; Smart Step Into'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Shift + F7'&lt;/span&gt; shortcut). Here is its execution result:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S_1vZOgjIbI/AAAAAAAAAPA/cWAZfxSJIVU/s1600/idea-smart-step-into.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S_1vZOgjIbI/AAAAAAAAAPA/cWAZfxSJIVU/s320/idea-smart-step-into.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5475655201134420402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I.e. we can choose target method which body should be inspected. Really enjoy this feature!&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="run-to-cursor"&gt;Run to cursor&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Another cool debugger feature I want to talk about is &lt;span style="font-style:italic;"&gt;'Run to cursor'&lt;/span&gt;. Consider the same code as above. Suppose that we setup breakpoints as mentioned at screenshot below, start application and wait while the first one is hit:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S_1wa6xH8GI/AAAAAAAAAPI/bU_udJX2cbQ/s1600/idea-go-to-cursor.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S_1wa6xH8GI/AAAAAAAAAPI/bU_udJX2cbQ/s320/idea-go-to-cursor.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5475656329706598498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We can ask to proceed debugging and automatically pause when any of conditions below is met:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;control flow reaches the line where editor caret is located at the moment;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;any existing break point is hit before condition above;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I.e. we can execute &lt;span style="font-style:italic;"&gt;'Main Menu -&gt; Run -&gt; Run to Cursor'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Alt + F9'&lt;/span&gt; shortcut) - that produces behavior described above. Here break point at &lt;span style="font-style:italic;"&gt;'baz()'&lt;/span&gt; method is reached before the line where editor caret is located now, hence, debug session automatically stops there.&lt;br /&gt;&lt;br /&gt;However, it's possible to execute &lt;span style="font-style:italic;"&gt;'Force Run to Cursor'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Ctrl + Alt + F9'&lt;/span&gt;) - that makes debugger to temporary ignore any intermediate breakpoints and stop exactly at the line with caret.&lt;br /&gt;&lt;br /&gt;I used to use the following trick before - set break point at target line, perform &lt;span style="font-style:italic;"&gt;'Resume Debug'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'F9'&lt;/span&gt;), remove break point. Will make a habit to use feature above instead since it's provide much more convenient way to achieve the same result and is more powerful in that it allows to ignore intermediate break points.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-4805839100488634476?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/4805839100488634476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/05/idea-candy-harnessing-debugger.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4805839100488634476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4805839100488634476'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/05/idea-candy-harnessing-debugger.html' title='IDEA candy - Harnessing debugger'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wBtqK4BXFZc/S_1vZOgjIbI/AAAAAAAAAPA/cWAZfxSJIVU/s72-c/idea-smart-step-into.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-4830458360548447866</id><published>2010-05-15T15:43:00.012+04:00</published><updated>2010-05-15T16:53:08.291+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - Live code formatting</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html#horizontal-move"&gt;Horizontal code block move&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html#indent-line"&gt;'Indent Lines' action&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html#join-line"&gt;'Join Lines' action&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html#unwrap"&gt;'Unwrap' action&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;I'm continuing the theme of describing IDEA features new to me and going to talk about various live code formatting facilities provided out of the box.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="horizontal-move"&gt;Horizontal code block move&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's possible to perform horizontal move of code located at current line (selected multiline code) to the standard indentation value (defined via &lt;span style="font-style:italic;"&gt;'Settings -&gt; Code Style -&gt; General -&gt; Indent'&lt;/span&gt;). Move to right is performed via pressing &lt;span style="font-style:italic;"&gt;'Tab'&lt;/span&gt;; move to left via &lt;span style="font-style:italic;"&gt;'Shift + Tab'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Example&lt;/span&gt;: consider the following class:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt;[] data) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (data[&lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;1&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;10&lt;/span&gt; &lt;br /&gt;                &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;4&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;6&lt;/span&gt;&lt;br /&gt;                &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;18&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;20&lt;/span&gt;) &lt;br /&gt;        {                &lt;br /&gt;                System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"crazy condition is satisfied"&lt;/span&gt;);        &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Suppose you want last line at &lt;span style="font-style:italic;"&gt;'if'&lt;/span&gt; condition section to have additional indent. Put cursor to it and press &lt;span style="font-style:italic;"&gt;'Tab'&lt;/span&gt;. Result:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt;[] data) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (data[&lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;1&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;10&lt;/span&gt;&lt;br /&gt;                &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;4&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;6&lt;/span&gt;&lt;br /&gt;                    &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;18&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;20&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;                System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"crazy condition is satisfied"&lt;/span&gt;);        &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Suppose you want to have the second and the third lines of &lt;span style="font-style:italic;"&gt;'if'&lt;/span&gt; condition to have one more additional indent. Select them and press &lt;span style="font-style:italic;"&gt;'Tab'&lt;/span&gt; again:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S-6NZekvGuI/AAAAAAAAAN4/Mt969xQ8ey4/s1600/idea-move-lines.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S-6NZekvGuI/AAAAAAAAAN4/Mt969xQ8ey4/s320/idea-move-lines.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471466066145123042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Result:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt;[] data) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (data[&lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;1&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;10&lt;/span&gt;&lt;br /&gt;                    &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;4&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;6&lt;/span&gt;&lt;br /&gt;                        &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;18&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;20&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;                System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"crazy condition is satisfied"&lt;/span&gt;);        &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You can perform line(s) code move to left via pressing &lt;span style="font-style:italic;"&gt;'Shit + Tab'&lt;/span&gt; instead of &lt;span style="font-style:italic;"&gt;'Tab'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="indent-line"&gt;'Indent Lines' action&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Let's continue with our example - it's &lt;span style="font-style:italic;"&gt;'if'&lt;/span&gt; condition clause contains two lines that are indented too far to the right now. We'd like to fix indentation in accordance with current formatting settings (i.e. make both lines to have single indent to the first &lt;span style="font-style:italic;"&gt;'if'&lt;/span&gt; line). There are two ways to go - the first one is to reformat the code via &lt;span style="font-style:italic;"&gt;'Reformat Action'&lt;/span&gt; (&lt;span style="font-style:italic;"&gt;'Ctrl + Alt + L'&lt;/span&gt;). This is rather ubiqutious approach known to most of IDEA users. It's drawback is in its power - it can introduce/remove line breaks in accordance with current formatting options and we may don't want that.&lt;br /&gt;&lt;br /&gt;However, there is a dedicated action that just fixes indentation  for selected code (active line). Select target code to indent:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6PtnUhMEI/AAAAAAAAAOI/6ItCgY4YemM/s1600/idea-indent-lines.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6PtnUhMEI/AAAAAAAAAOI/6ItCgY4YemM/s320/idea-indent-lines.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471468611113660482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Press &lt;span style="font-style:italic;"&gt;'Ctrl + Alt + I'&lt;/span&gt; now - &lt;span style="font-style:italic;"&gt;'Indent Lines'&lt;/span&gt; action. Result:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt;[] data) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (data[&lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;1&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;10&lt;/span&gt;&lt;br /&gt;                &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;4&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;6&lt;/span&gt;&lt;br /&gt;                &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;18&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;20&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;                System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"crazy condition is satisfied"&lt;/span&gt;);        &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="join-line"&gt;'Join Lines' action&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;We can notice that we don't need line breaks at out &lt;span style="font-style:italic;"&gt;'if'&lt;/span&gt; condition. IDEA allows to automatically collapse multiple lines to the single one.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Example&lt;/span&gt;: select target lines to collapse (join):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6RBQwim-I/AAAAAAAAAOQ/luzc1KXJ5PI/s1600/idea-join-lines.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6RBQwim-I/AAAAAAAAAOQ/luzc1KXJ5PI/s320/idea-join-lines.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471470048166190050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Invoke &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt; action (&lt;span style="font-style:italic;"&gt;'Ctrl + Shift + J'&lt;/span&gt;). Result:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt;[] data) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (data[&lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;1&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;10&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;4&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;2&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;6&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;gt; &lt;span style="color:#0000ff;"&gt;18&lt;/span&gt; &amp;&amp; data[&lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;] &amp;lt; &lt;span style="color:#0000ff;"&gt;20&lt;/span&gt;) {&lt;br /&gt;            System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"crazy condition is satisfied"&lt;/span&gt;);        &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Note that &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt; action is rather smart - it correctly handles string literals:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Before&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S-6SRowz0YI/AAAAAAAAAOY/hFsNVmPDu2I/s1600/idea-join-lines-string-literal.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S-6SRowz0YI/AAAAAAAAAOY/hFsNVmPDu2I/s320/idea-join-lines-string-literal.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471471428999303554" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;After&lt;/span&gt; &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt; is called for selection:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt;[] data) {&lt;br /&gt;        foo(&lt;span style="color:#008000;font-weight:bold;"&gt;"xxxxxyyyyzzzz"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; foo(String s) {        &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Also it manages variable declaration and assignment:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Before&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S-6TmRm1Z7I/AAAAAAAAAOg/nE7_e81_QOE/s1600/idea-join-lines-var-declaration.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S-6TmRm1Z7I/AAAAAAAAAOg/nE7_e81_QOE/s320/idea-join-lines-var-declaration.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471472883072329650" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;After&lt;/span&gt; &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test() {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt; i = &lt;span style="color:#0000ff;"&gt;12&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Also &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt; tries to collapse multiple statements to the single one:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Before&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6UVZVKpFI/AAAAAAAAAOo/ZekQYBczECg/s1600/idea-join-lines-statements.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6UVZVKpFI/AAAAAAAAAOo/ZekQYBczECg/s320/idea-join-lines-statements.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471473692599559250" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;After&lt;/span&gt; &lt;span style="font-style:italic;"&gt;'Join Lines'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(&lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt; i) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt; j = i * &lt;span style="color:#0000ff;"&gt;14&lt;/span&gt; + &lt;span style="color:#0000ff;"&gt;3&lt;/span&gt;;&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(j);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Also there is feature request for smart processing of &lt;span style="font-style:italic;"&gt;StringBuilder&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;StringBuffers&lt;/span&gt; - &lt;a href="http://youtrack.jetbrains.net/issue/IDEA-54209"&gt;IDEA-54209&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="unwrap"&gt;'Unwrap' action&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Last but not least cool action is &lt;span style="font-style:italic;"&gt;'Unwrap'&lt;/span&gt;. It simplifies the process of wrapping blocks removal. Consider the following example:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; java.util.concurrent.Callable;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(Callable&amp;lt;Object&amp;gt; task) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;try&lt;/span&gt; {&lt;br /&gt;            task.call();&lt;br /&gt;        } &lt;span style="color:#000080;font-weight:bold;"&gt;catch&lt;/span&gt; (Exception e) {&lt;br /&gt;            &lt;span style="color:#660e7a;font-weight:bold;"&gt;e&lt;/span&gt;.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Here method &lt;span style="font-style:italic;"&gt;'foo()'&lt;/span&gt; doesn't declare any checked exceptions but calls &lt;span style="font-style:italic;"&gt;Callable.call()&lt;/span&gt; that declares Throwable. We wrapped the call into &lt;span style="font-style:italic;"&gt;try/catch&lt;/span&gt; block initially but decide to throw the Throwable to the upper stack now.&lt;br /&gt;&lt;br /&gt;We do the following then:&lt;br /&gt;&lt;br /&gt;Remove unnecessary &lt;span style="font-style:italic;"&gt;try/catch&lt;/span&gt; - move caret inside &lt;span style="font-style:italic;"&gt;'try'&lt;/span&gt; block and invoke &lt;span style="font-style:italic;"&gt;'Unwrap'&lt;/span&gt; action (&lt;span style="font-style:italic;"&gt;'Ctrl + Shift + Del'&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S-6Wfx7nbMI/AAAAAAAAAOw/rYwDcMC91FQ/s1600/idea-unwrap.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S-6Wfx7nbMI/AAAAAAAAAOw/rYwDcMC91FQ/s320/idea-unwrap.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471476070025227458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Result:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; java.util.concurrent.Callable;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(Callable&amp;lt;Object&amp;gt; task) {&lt;br /&gt;        task.call();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Then we can add &lt;span style="font-style:italic;"&gt;'throws Throwable'&lt;/span&gt; to the method signature using &lt;span style="font-style:italic;"&gt;'Add Exception to Method Signature'&lt;/span&gt; quickfix - put the caret to the problem call (&lt;span style="font-style:italic;"&gt;'task.call()'&lt;/span&gt;) and press &lt;span style="font-style:italic;"&gt;'Alt + Enter'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6XM8KI6gI/AAAAAAAAAO4/M805dB9gtcI/s1600/idea-add-exception-quickfix.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S-6XM8KI6gI/AAAAAAAAAO4/M805dB9gtcI/s320/idea-add-exception-quickfix.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471476845864610306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Result:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; java.util.concurrent.Callable;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FormattingTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(Callable&amp;lt;Object&amp;gt; task) &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; Exception {&lt;br /&gt;        task.call();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Develop with pleasure! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-4830458360548447866?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/4830458360548447866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4830458360548447866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4830458360548447866'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/05/idea-candy-live-code-formatting.html' title='IDEA candy - Live code formatting'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_wBtqK4BXFZc/S-6NZekvGuI/AAAAAAAAAN4/Mt969xQ8ey4/s72-c/idea-move-lines.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-8086877146141186688</id><published>2010-05-15T13:25:00.007+04:00</published><updated>2010-05-15T14:12:18.656+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><title type='text'>IDEA candy - Analyze external stack trace</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-analyze-external-stack-trace.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/05/idea-candy-analyze-external-stack-trace.html#usage"&gt;Usage&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;I've been &lt;a href="http://www.jetbrains.com/idea/index.html"&gt;IDEA&lt;/a&gt; user for more than five years but still discover new nice features with it. The rate of that discovering is increased since I've become IDEA developer because I work with people that implemented those features and, more importantly, use them in every day programming. So, I'm starting to blog about IDEA candies that are new to me.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="usage"&gt;Usage&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;I encounter the following use-case rather often - someone reports a problem and provides its stack-trace. IDEA allows to view it with convenient facility to directly navigate to target source code location.&lt;br /&gt;&lt;br /&gt;Let me illustrate that. Suppose you want to help to solve a problem - e.g. &lt;a href="http://forum.springsource.org/showthread.php?t=89289"&gt;this forum thread&lt;/a&gt; contains stack trace:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;java.lang.ArrayIndexOutOfBoundsException: -1&lt;br /&gt; at org.springframework.core.MethodParameter.getParameterType(MethodParameter.java:154)&lt;br /&gt; at org.springframework.core.convert.TypeDescriptor.getType(TypeDescriptor.java:190)&lt;br /&gt; at org.springframework.core.convert.TypeDescriptor.isTypeAssignableTo(TypeDescriptor.java:525)&lt;br /&gt; at org.springframework.core.convert.TypeDescriptor.isMap(TypeDescriptor.java:283)&lt;br /&gt; at org.springframework.expression.spel.ast.Indexer.getValueInternal(Indexer.java:92)&lt;br /&gt; at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57)&lt;br /&gt; at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)&lt;br /&gt; at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:71)&lt;br /&gt; at net.youngdev.springutils.expression.SpELUtilsTest.testGetValue(SpELUtilsTest.java:37)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)&lt;br /&gt; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)&lt;br /&gt; at java.lang.reflect.Method.invoke(Method.java:616)&lt;br /&gt; at junit.framework.TestCase.runTest(TestCase.java:154)&lt;br /&gt; at junit.framework.TestCase.runBare(TestCase.java:127)&lt;br /&gt; at junit.framework.TestResult$1.protect(TestResult.java:106)&lt;br /&gt; at junit.framework.TestResult.runProtected(TestResult.java:124)&lt;br /&gt; at junit.framework.TestResult.run(TestResult.java:109)&lt;br /&gt; at junit.framework.TestCase.run(TestCase.java:118)&lt;br /&gt; at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)&lt;br /&gt; at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)&lt;br /&gt; at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)&lt;br /&gt; at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)&lt;br /&gt; at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)&lt;br /&gt; at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;You can copy the stack trace to the clipboard and view it at IDEA:&lt;br /&gt;&lt;br /&gt;Open &lt;span style="font-style:italic;"&gt;'Analyze stacktrace'&lt;/span&gt; dialog via &lt;span style="font-style:italic;"&gt;'Main Menu -&gt; Analyze -&gt; Analyze Stacktrace'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S-5xGaO4HgI/AAAAAAAAANg/N3NigSihvgw/s1600/idea-analyze-stacktrace.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S-5xGaO4HgI/AAAAAAAAANg/N3NigSihvgw/s320/idea-analyze-stacktrace.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471434952236604930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Paste target stack trace and press &lt;span style="font-style:italic;"&gt;'Ok'&lt;/span&gt; button:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S-5xrfOYCmI/AAAAAAAAANo/k75y4fy61QA/s1600/idea-analyze-stacktrace2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S-5xrfOYCmI/AAAAAAAAANo/k75y4fy61QA/s320/idea-analyze-stacktrace2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471435589231839842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Check that analysed stack trace appears at &lt;span style="font-style:italic;"&gt;'Debug'&lt;/span&gt; panel - it contains clickable links to the source code (if source file for corresponding class is configured for the project):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S-5ycfP7O1I/AAAAAAAAANw/Fnweh7L8prk/s1600/idea-analyze-stacktrace3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S-5ycfP7O1I/AAAAAAAAANw/Fnweh7L8prk/s320/idea-analyze-stacktrace3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5471436431051930450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also see that IDEA folds infrastructure calls (reflection processing, groovy internal processing etc) as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-8086877146141186688?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/8086877146141186688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/05/idea-candy-analyze-external-stack-trace.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8086877146141186688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8086877146141186688'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/05/idea-candy-analyze-external-stack-trace.html' title='IDEA candy - Analyze external stack trace'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wBtqK4BXFZc/S-5xGaO4HgI/AAAAAAAAANg/N3NigSihvgw/s72-c/idea-analyze-stacktrace.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-8256991534431618494</id><published>2010-04-28T20:38:00.012+04:00</published><updated>2010-05-10T23:26:36.892+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy features, part 3 - method gotchas</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#operators"&gt;Operator-like methods&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#equals"&gt;Groovy Equals&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#multimethods"&gt;Multimethods&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#overloaded-operators"&gt;Overloaded operators&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#optional-params"&gt;Optional parameters&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#vararg"&gt;Vararg methods&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#named-params"&gt;Named parameters&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#constructor-named"&gt;Constructors with named parameters&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#constructor-positional"&gt;Constructors with positional parameters&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;This is a regular article produced on Groovy exploration way. We'll talk about Groovy method calls processing here.&lt;br /&gt;&lt;br /&gt;Previous part may be found here - &lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html"&gt;Groovy features, part 2 - java beans&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="operators"&gt;Operator-like methods&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Groovy offers convenient call syntax for predefined set of methods. It looks like operator appliance at source code level but is compiled to a method call. Example:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Integer i = 1;&lt;br /&gt;Integer j = 2;&lt;br /&gt;println i.class&lt;br /&gt;println j.class&lt;br /&gt;println i + j&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;class java.lang.Integer&lt;br /&gt;class java.lang.Integer&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can see that it looks like &lt;span style="font-style:italic;"&gt;'+'&lt;/span&gt; operator is applied to two objects of type &lt;span style="font-style:italic;"&gt;'java.lang.Integer'&lt;/span&gt;, howver, it's transformed to call 'i.&lt;a href="http://groovy.codehaus.org/groovy-jdk/java/lang/Number.html#plus(java.lang.Number)"&gt;plus&lt;/a&gt;(j)'. I.e. Groovy automatically converts &lt;span style="font-style:italic;"&gt;'+'&lt;/span&gt; defined at source level to invocation of &lt;span style="font-style:italic;"&gt;'plus()'&lt;/span&gt; method at runtime.&lt;br /&gt;&lt;br /&gt;That means that it's possible to declare such a method at custom class and use operator-like syntax for it:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; FirstNumberWrapper {&lt;br /&gt;  Number i&lt;br /&gt;&lt;br /&gt;  def plus(j) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"FirstNumberWrapper.plus($j) is called"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; FirstNumberWrapper(i: i + j)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  String toString() {&lt;span style="color:#008000;font-weight:bold;"&gt;"'wrapper for $i'"&lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; SecondNumberWrapper {&lt;br /&gt;  Number i&lt;br /&gt;&lt;br /&gt;  String toString() {&lt;span style="color:#008000;font-weight:bold;"&gt;"'wrapper for $i'"&lt;/span&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;first = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; FirstNumberWrapper(i: 1)&lt;br /&gt;second = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; SecondNumberWrapper(i: 2)&lt;br /&gt;&lt;br /&gt;println &lt;span style="color:#008000;font-weight:bold;"&gt;"Adding 3 to first wrapper ($first)..."&lt;/span&gt;&lt;br /&gt;first += 3&lt;br /&gt;println &lt;span style="color:#008000;font-weight:bold;"&gt;"done. Result: $first"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;println &lt;span style="color:#008000;font-weight:bold;"&gt;"Adding 3 to second wrapper ($second)..."&lt;/span&gt;&lt;br /&gt;second += 3&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Adding 3 to first wrapper ('wrapper for 1')...&lt;br /&gt;FirstNumberWrapper.plus(3) is called&lt;br /&gt;done. Result: 'wrapper for 4'&lt;br /&gt;Adding 3 to second wrapper ('wrapper for 2')...&lt;br /&gt;Caught: groovy.lang.MissingMethodException: No signature of method: SecondNumberWrapper.plus() is applicable for argument types: (java.lang.Integer) values: [3]&lt;br /&gt; at GroovyTestScript.run(GroovyTestScript.groovy:26)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here is a complete list of method name - operator sign mappings:&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;br /&gt;&lt;thead&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;th&gt;Operator&lt;/th&gt;&lt;br /&gt;&lt;th&gt;Method&lt;/th&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/thead&gt;&lt;br /&gt;&lt;tbody&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a + b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.plus(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a - b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.minus(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a * b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.multiply(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a / b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.div(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a % b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.mod(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a++; ++a&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.next()&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a--; --a&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.previous()&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a ** b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.power(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a | b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.or(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &amp; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.and(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a ^ b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.xor(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;~a&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.negate()&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a[b]&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.getAt(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a[b] = c&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.putAt(b, c)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &lt;&lt; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.leftShift(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &gt;&gt; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.rightShift(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &gt;&gt;&gt; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.rightShiftUnsigned(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;switch (a) { case b: }&lt;/td&gt;&lt;br /&gt;&lt;td&gt;b.isCase(a)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a == b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.equals(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a != b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;!a.equals(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &lt;=&gt; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.compareTo(b)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &gt; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.compareTo(b) &gt; 0&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &gt;= b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.compareTo(b) &gt;= 0&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &lt; b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.compareTo(b) &lt; 0&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a &lt;= b&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.compareTo(b) &lt;= 0&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;a as type&lt;/td&gt;&lt;br /&gt;&lt;td&gt;a.asType(typeClass)&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tbody&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="equals"&gt;Groovy Equals&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I want to pay special attention to ' == ' operator processing - it is automatically mapped to &lt;span style="font-style:italic;"&gt;'equals()'&lt;/span&gt; call. You should use &lt;a href="http://groovy.codehaus.org/groovy-jdk/java/lang/Object.html#is(java.lang.Object)"&gt;is()&lt;/a&gt; method to compare objects by identity:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;s1 = &lt;span style="color:#008000;font-weight:bold;"&gt;"xxx"&lt;/span&gt;&lt;br /&gt;s2 = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; String(&lt;span style="color:#008000;font-weight:bold;"&gt;"xxx"&lt;/span&gt;)&lt;br /&gt;s3 = s2&lt;br /&gt;&lt;br /&gt;println s1 == s2  &lt;span style="color:#808080;font-style:italic;"&gt;// true&lt;br /&gt;&lt;/span&gt;println s1.is(s2) &lt;span style="color:#808080;font-style:italic;"&gt;// false&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;println s2 == s3  &lt;span style="color:#808080;font-style:italic;"&gt;// true&lt;br /&gt;&lt;/span&gt;println s2.is(s3) // true&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#multimethods"&gt;Multimethods&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;Java selects target overloaded method at compile-time, hence, it looks at static reference type. Consider the following example:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GeneralItem {}&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; SubItem &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; GeneralItem {}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; BaseService {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(Object data) {&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"BaseService.test()"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; SubService &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; BaseService {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test(String data) {&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"SubService.test()"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; JavaTest {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(String[] args) {&lt;br /&gt;        BaseService subService = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; SubService();&lt;br /&gt;        subService.test(&lt;span style="color:#008000;font-weight:bold;"&gt;""&lt;/span&gt;); &lt;span style="color:#808080;font-style:italic;"&gt;// prints 'BaseService.test()'&lt;br /&gt;&lt;/span&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here actual object type is &lt;span style="font-style:italic;"&gt;'SubService'&lt;/span&gt; and argument type is &lt;span style="font-style:italic;"&gt;'String'&lt;/span&gt;. However, BaseService.test() is called because static type of &lt;span style="font-style:italic;"&gt;'SubService'&lt;/span&gt; reference is &lt;span style="font-style:italic;"&gt;'BaseService'&lt;/span&gt;, hence, algorithm that resolves overloaded method to use selects &lt;span style="font-style:italic;"&gt;'BaseService.test()'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;We can perform the same test in Groovy and see that &lt;span style="font-style:italic;"&gt;'SubService.test()'&lt;/span&gt; is printed. The reason is that Groovy resolves all method calls in runtime, hence, it checks both actual argument types and target reference type. This is really cool!&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#overloaded-operators"&gt;Overloaded operators&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;Multimethods allow to do the following nice trick - it's possible to define overloaded versions of base operator methods. Necessary version is automatically chose in runtime:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; NumberWrapper {&lt;br /&gt;  def number;&lt;br /&gt;&lt;br /&gt;  def multiply(Number number) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'muliply(Number)'&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; NumberWrapper(number: &lt;span style="color:#000080;font-weight:bold;"&gt;this&lt;/span&gt;.number * number)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def multiply(NumberWrapper wrapper) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'muliply(NumberWrapper)'&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; NumberWrapper(number: number * wrapper.number)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def String toString() {&lt;br /&gt;    &lt;span style="color:#008000;font-weight:bold;"&gt;"wrapper for $number"&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def wrapper1 = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; NumberWrapper(number: 1)&lt;br /&gt;def wrapper2 = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; NumberWrapper(number: 2)&lt;br /&gt;&lt;br /&gt;println(wrapper1 * wrapper2)&lt;br /&gt;println(wrapper1 * 3)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;muliply(NumberWrapper)&lt;br /&gt;wrapper for 2&lt;br /&gt;muliply(Number)&lt;br /&gt;wrapper for 3&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="optional-params"&gt;Optional parameters&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's possible to define default parameters values for Groovy method arguments. Any number of such parameters can be introduced. The only restriction is that they should be trailing within the method definition:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def sum(first, second, third = 3, forth = 4) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"sum($first, $second, $third, $forth)"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sum(10, 20)&lt;br /&gt;sum(10, 20, 30)&lt;br /&gt;sum(10, 20, 30, 40)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;sum(10, 20, 3, 4)&lt;br /&gt;sum(10, 20, 30, 4)&lt;br /&gt;sum(10, 20, 30, 40)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="vararg"&gt;Vararg methods&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Groovy supports java syntax sugar for var-arg parameter delivered as array at runtime. Moreover, any trailing array parameter is treated as vararg parameter with 0..* cardinality:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def test1(first, ... trailing) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"test1($first, $trailing)"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def test2(first, Object[] trailing) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"test2($first, $trailing)"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;test1(1, 2, 3, 4)&lt;br /&gt;test1(1)&lt;br /&gt;&lt;br /&gt;test2(10, 20, 30, 40)&lt;br /&gt;test2(10)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;test1(1, [2, 3, 4])&lt;br /&gt;test1(1, [])&lt;br /&gt;test2(10, [20, 30, 40])&lt;br /&gt;test2(10, [])&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="named-params"&gt;Named parameters&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;All method calls above used so-called &lt;span style="font-style:italic;"&gt;'positional parameters'&lt;/span&gt;, i.e. parameter meaning is defined by its position at method call expression. However, it's possible to use rather convenient alternative to that - &lt;span style="font-style:italic;"&gt;'named parameters'&lt;/span&gt;. Method caller supplies every parameter with it's name and it's position doesn't matter at all. Moreover, it's even possible to provide support for optional parameters within method implementation:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def test(Map args) {&lt;br /&gt;  args.get(&lt;span style="color:#008000;font-weight:bold;"&gt;'quantity'&lt;/span&gt;, 1) &lt;span style="color:#808080;font-style:italic;"&gt;// Provide default value for 'quantity' argument&lt;br /&gt;&lt;/span&gt;  println &lt;span style="color:#008000;font-weight:bold;"&gt;"Total price: ${args.quantity * args.price}"&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;test(quantity: 3, price: 2)&lt;br /&gt;test(price: 4, quantity: 2)&lt;br /&gt;test(price: 10)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Total price: 6&lt;br /&gt;Total price: 8&lt;br /&gt;Total price: 10&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="constructor-named"&gt;Constructors with named parameters&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Groovy allows to create instances of classes with &lt;span style="font-style:italic;"&gt;'named parameters syntax'&lt;/span&gt; for their properties. The only restriction for such usage is that class which object is constructed should have no-args constructor:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; TestClass {&lt;br /&gt;  String property1, property2&lt;br /&gt;&lt;br /&gt;  def String toString() {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; &lt;span style="color:#008000;font-weight:bold;"&gt;"property1: $property1; property2: $property2"&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;println &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; TestClass(property1: &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;)&lt;br /&gt;println &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; TestClass(property2: &lt;span style="color:#008000;font-weight:bold;"&gt;'zzz'&lt;/span&gt;, property1: &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;property1: xxx; property2: null&lt;br /&gt;property1: xxx; property2: zzz&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="constructor-positional"&gt;Constructors with positional parameters&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;There is convenient syntax for calling constructors with positional parameters as well.&lt;br /&gt;&lt;br /&gt;The main idea is that every time Groovy sees the need to convert list to some other type it tries to call appropriate type's constructor with all list items as arguments (at same order). Such a conversion may be performed either explicitly (via &lt;span style="font-weight:bold;"&gt;'as'&lt;/span&gt; operator) or implicitly:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; TestClass {&lt;br /&gt;  String property1, property2&lt;br /&gt;&lt;br /&gt;  def TestClass(property1, property2) {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;this&lt;/span&gt;.property1 = property1&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;this&lt;/span&gt;.property2 = property2&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def String toString() {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; &lt;span style="color:#008000;font-weight:bold;"&gt;"property1: $property1; property2: $property2"&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def obj1 = [1, 2] as TestClass&lt;br /&gt;TestClass obj2 = [&lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;, &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Date()] &lt;span style="color:#808080;font-style:italic;"&gt;// Note that we use explicit variable typing here&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;println obj1&lt;br /&gt;println obj2&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;property1: 1; property2: 2&lt;br /&gt;property1: xxx; property2: Mon May 10 23:14:43 MSD 2010&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-8256991534431618494?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/8256991534431618494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8256991534431618494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8256991534431618494'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html' title='Groovy features, part 3 - method gotchas'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2962422681277232900</id><published>2010-04-21T21:39:00.013+04:00</published><updated>2010-05-10T23:17:46.512+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy features, part 2 - java beans</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#definition"&gt;Property definition&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#custom"&gt;Custom getters/setters&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#access"&gt;Working with properties&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#read-only"&gt;Read-only properties&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#constructor"&gt;Convenient properties initialisation&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#fields"&gt;Declare instance/static fields&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#listeners"&gt;Bound and constrained properties support&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I'm continuing my dairy of groovy exploration, here is a second part that talks about groovy syntax sugar for JavaBeans support. Feel free to check the previous topic - &lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html"&gt;Exploring Groovy, part 1 - common stuff&lt;/a&gt;. Next article - &lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-3-method-gotchas.html"&gt;Groovy features, part 3 - method gotchas&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="definition"&gt;Property definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's possible to define JavaBean property for the groovy class with relaxed groovy supported-syntax. Basically, &lt;span style="font-style:italic;"&gt;'property'&lt;/span&gt; here means private field and implicitly generated and used getter/setter. &lt;br /&gt;&lt;br /&gt;Two property types are supported - &lt;span style="font-style:italic;"&gt;'typed'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'untyped'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Here is an example that shows property definition:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; def staticUntypedProperty;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;long&lt;/span&gt; staticTypedProperty;&lt;br /&gt;&lt;br /&gt;  def untypedInstanceProperty;&lt;br /&gt;  Integer typedInstanceProperty;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can check structure of the class generated by Groovy for such a source:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;$ javap org.denis.GroovyTestClass&lt;br /&gt;Compiled from "GroovyTestClass.groovy"&lt;br /&gt;public class org.denis.GroovyTestClass extends java.lang.Object implements groovy.lang.GroovyObject{&lt;br /&gt;    public static final java.lang.Class $ownClass;&lt;br /&gt;    public static java.lang.Long __timeStamp;&lt;br /&gt;    public static java.lang.Long __timeStamp__239_neverHappen1271917491545;&lt;br /&gt;    public org.denis.GroovyTestClass();&lt;br /&gt;    protected groovy.lang.MetaClass $getStaticMetaClass();&lt;br /&gt;    public groovy.lang.MetaClass getMetaClass();&lt;br /&gt;    public void setMetaClass(groovy.lang.MetaClass);&lt;br /&gt;    public java.lang.Object invokeMethod(java.lang.String, java.lang.Object);&lt;br /&gt;    public java.lang.Object getProperty(java.lang.String);&lt;br /&gt;    public void setProperty(java.lang.String, java.lang.Object);&lt;br /&gt;    static {};&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;    public static java.lang.Object getStaticUntypedProperty();&lt;br /&gt;    public static void setStaticUntypedProperty(java.lang.Object);&lt;br /&gt;    public static long getStaticTypedProperty();&lt;br /&gt;    public static void setStaticTypedProperty(long);&lt;br /&gt;    public java.lang.Object getUntypedInstanceProperty();&lt;br /&gt;    public void setUntypedInstanceProperty(java.lang.Object);&lt;br /&gt;    public java.lang.Integer getTypedInstanceProperty();&lt;br /&gt;    public void setTypedInstanceProperty(java.lang.Integer);&lt;/span&gt;&lt;br /&gt;    public void super$1$wait();&lt;br /&gt;    public java.lang.String super$1$toString();&lt;br /&gt;    public void super$1$wait(long);&lt;br /&gt;    public void super$1$wait(long, int);&lt;br /&gt;    public void super$1$notify();&lt;br /&gt;    public void super$1$notifyAll();&lt;br /&gt;    public java.lang.Class super$1$getClass();&lt;br /&gt;    public java.lang.Object super$1$clone();&lt;br /&gt;    public boolean super$1$equals(java.lang.Object);&lt;br /&gt;    public int super$1$hashCode();&lt;br /&gt;    public void super$1$finalize();&lt;br /&gt;    static java.lang.Class class$(java.lang.String);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I.e. Groovy generated getters and setters for both instance and static properties.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="custom"&gt;Custom getters/setters&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's also possible to define custom getters/setters with desired visibility for particular property. The only trick here is to explicitly declare return type as &lt;span style="font-style:italic;"&gt;'void'&lt;/span&gt; for setters because methods declared via &lt;span style="font-style:italic;"&gt;'def'&lt;/span&gt; have return type &lt;span style="font-style:italic;"&gt;'Object'&lt;/span&gt; by default:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt; typedProperty;&lt;br /&gt;  def untypedProperty;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#808080;font-style:italic;"&gt;// Custom setter.&lt;br /&gt;&lt;/span&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;protected&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; setTypedProperty(value) {&lt;br /&gt;    typedProperty = value&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#808080;font-style:italic;"&gt;// Custom getter&lt;br /&gt;&lt;/span&gt;  def getUntypedProperty() {&lt;br /&gt;    untypedProperty&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="access"&gt;Working with properties&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Groovy not only generates getters and setters for properties, it also implicitly uses them during working with properties:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;int&lt;/span&gt; typedProperty;&lt;br /&gt;  def untypedProperty;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; setTypedProperty(value) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"'typedProperty' is set to '$value' via custom setter"&lt;/span&gt;&lt;br /&gt;    typedProperty = value&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def getUntypedProperty() {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"'untypedProperty' is accessed via via custom getter"&lt;/span&gt;&lt;br /&gt;    untypedProperty&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; AnotherGroovyTestClass {&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Typed property: $test.typedProperty"&lt;/span&gt;&lt;br /&gt;    test.typedProperty = 1&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Typed property: $test.typedProperty"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Untyped property: $test.untypedProperty"&lt;/span&gt;&lt;br /&gt;    test.untypedProperty = 2&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Untyped property: $test.untypedProperty"&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We get the following output if we run &lt;span style="font-style:italic;"&gt;AnotherGroovyTestClass&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Typed property: 0&lt;br /&gt;'typedProperty' is set to '1' via custom setter&lt;br /&gt;Typed property: 1&lt;br /&gt;'untypedProperty' is accessed via via custom getter&lt;br /&gt;Untyped property: null&lt;br /&gt;'untypedProperty' is accessed via via custom getter&lt;br /&gt;Untyped property: 2&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;br /&gt;&lt;br /&gt;Note: direct access to the property is used every time it is accessed at compile time from the same class via explicit or implicit &lt;span style="font-style:italic;"&gt;'this'&lt;/span&gt; reference:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  def untypedProperty;&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Direct property access from &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; context'&lt;/span&gt;&lt;br /&gt;    println test.untypedProperty&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;''&lt;/span&gt;&lt;br /&gt;    test.indirectPropertyAccess()&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def indirectPropertyAccess() {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Direct property access from instance context'&lt;/span&gt;&lt;br /&gt;    println untypedProperty&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def getUntypedProperty() {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"'untypedProperty' is accessed via via custom getter"&lt;/span&gt;&lt;br /&gt;    untypedProperty&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Direct property access from static context&lt;br /&gt;'untypedProperty' is accessed via via custom getter&lt;br /&gt;null&lt;br /&gt;&lt;br /&gt;Direct property access from instance context&lt;br /&gt;null&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Also there is a trick to access the property directly from outside the class (i.e. ignore all custom getters/setters if any). That is done via &lt;span style="font-style:italic;"&gt;'.@'&lt;/span&gt; operator:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  def untypedProperty;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; setUntypedProperty(value) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"'untypedProperty' is set to '$value' via custom setter"&lt;/span&gt;&lt;br /&gt;    untypedProperty = value&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def getUntypedProperty() {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"'untypedProperty' is accessed via via custom getter"&lt;/span&gt;&lt;br /&gt;    untypedProperty&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; AnotherGroovyTestClass {&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Setting property using standard syntax'&lt;/span&gt;&lt;br /&gt;    test.untypedProperty = 1&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Getting property using standard syntax'&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Property: $test.untypedProperty"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    println()&lt;br /&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Setting property using non-standard syntax'&lt;/span&gt;&lt;br /&gt;    test.&lt;span style="color:#808000;"&gt;@untypedProperty&lt;/span&gt; = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Getting property using non-standard syntax'&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Property: ${test.@untypedProperty}"&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Setting property using standard syntax&lt;br /&gt;'untypedProperty' is set to '1' via custom setter&lt;br /&gt;Getting property using standard syntax&lt;br /&gt;'untypedProperty' is accessed via via custom getter&lt;br /&gt;Property: 1&lt;br /&gt;&lt;br /&gt;Setting property using non-standard syntax&lt;br /&gt;Getting property using non-standard syntax&lt;br /&gt;Property: xxx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="read-only"&gt;Read-only properties&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Often we need to make property read-only for external clients, i.e. define only getter for it. We can achieve that in Groovy by using &lt;span style="font-style:italic;"&gt;'final'&lt;/span&gt; keyword with the property:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;final&lt;/span&gt; myProperty = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; AnotherGroovyTestClass {&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Getting property...'&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Property: $test.myProperty"&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Setting property...'&lt;/span&gt;&lt;br /&gt;    test.myProperty = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt; &lt;span style="color:#808080;font-style:italic;"&gt;// fails at runtime because the property is read-only&lt;br /&gt;&lt;/span&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Getting property...&lt;br /&gt;Property: xxx&lt;br /&gt;Setting property...&lt;br /&gt;Exception in thread "main" groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: myProperty for class: org.denis.GroovyTestClass&lt;br /&gt; at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2406)&lt;br /&gt; at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3307)&lt;br /&gt; at org.denis.GroovyTestClass.setProperty(GroovyTestClass.groovy)&lt;br /&gt; at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:179)&lt;br /&gt; at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:483)&lt;br /&gt; at org.denis.AnotherGroovyTestClass.main(GroovyTestClass.groovy:14)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Please note that read-only property still can be accessed from the 'instance' context of the same class:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;final&lt;/span&gt; def myProperty = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Initial read-only property value: '$test.myProperty'"&lt;/span&gt;&lt;br /&gt;    print &lt;span style="color:#008000;font-weight:bold;"&gt;'Setting read-only property from instance context...'&lt;/span&gt;&lt;br /&gt;    test.setPropertyFromInstanceContext(2)&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"done. Current read-only property value: '$test.myProperty'"&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;'Trying to set read-only property value from &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; context...'&lt;/span&gt;&lt;br /&gt;    test.myProperty = 3 &lt;span style="color:#808080;font-style:italic;"&gt;// fails at runtime because we attempt to set read-only property value from static context&lt;br /&gt;&lt;/span&gt;  }&lt;br /&gt;&lt;br /&gt;  def setPropertyFromInstanceContext(value) {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;this&lt;/span&gt;.myProperty = value&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Initial read-only property value: 'xxx'&lt;br /&gt;Setting read-only property from instance context...done. Current read-only property value: '2'&lt;br /&gt;Trying to set read-only property value from static context...&lt;br /&gt;Exception in thread "main" groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: myProperty for class: org.denis.GroovyTestClass&lt;br /&gt; at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2406)&lt;br /&gt; at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3307)&lt;br /&gt; at org.denis.GroovyTestClass.setProperty(GroovyTestClass.groovy)&lt;br /&gt; at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:179)&lt;br /&gt; at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:483)&lt;br /&gt; at org.denis.GroovyTestClass.main(GroovyTestClass.groovy:14)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That means that it's possible to define a property with, say, public getter and protected setter:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;final&lt;/span&gt; def myProperty = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Initial property value: '$test.myProperty'"&lt;/span&gt;&lt;br /&gt;    print &lt;span style="color:#008000;font-weight:bold;"&gt;'Setting property from instance context...'&lt;/span&gt;&lt;br /&gt;    test.myProperty = 2 &lt;span style="color:#808080;font-style:italic;"&gt;// Allowed because of 'protected' setter visibility&lt;br /&gt;&lt;/span&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"done. Current property value: '$test.myProperty'"&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;protected&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; setMyProperty(value) {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;this&lt;/span&gt;.myProperty = value&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Initial property value: 'xxx'&lt;br /&gt;Setting property from instance context...done. Current property value: '2'&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="constructor"&gt;Convenient properties initialisation&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Properties may be initialised using the following convenient syntax:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;&lt;br /&gt;  def property1&lt;br /&gt;  def property2&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass(property1: 1, property2: &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;)&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Properties are initialized: $test.property1 $test.property2"&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It is executed as if new object is created and target properties setters are called on it. Here is equivalent java code for that:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass();&lt;br /&gt;test.setProperty1(1);&lt;br /&gt;test.setProperty2(&lt;span style="color:#008000;font-weight:bold;"&gt;"xxx"&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;&lt;h4&gt;&lt;a name="fields"&gt;Declare instance/static fields&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's cool to have relaxed syntax for declaring and using properties but sometimes we need just fields, i.e. we don't want Groovy to generate and use getters and setters. We can achieve that simply by almost the same syntax as we used for properties. The only difference is that we explicitly define field visibility:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; def property1&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;protected&lt;/span&gt; String property2&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;$ javap org.denis.GroovyTestClass&lt;br /&gt;Compiled from "GroovyTestClass.groovy"&lt;br /&gt;public class org.denis.GroovyTestClass extends java.lang.Object implements groovy.lang.GroovyObject{&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;    public java.lang.Object property1;&lt;br /&gt;    protected java.lang.String property2;&lt;/span&gt;&lt;br /&gt;    public static java.lang.Long __timeStamp;&lt;br /&gt;    public static java.lang.Long __timeStamp__239_neverHappen1271924017378;&lt;br /&gt;    public org.denis.GroovyTestClass();&lt;br /&gt;    public java.lang.Object this$dist$invoke$2(java.lang.String, java.lang.Object);&lt;br /&gt;    public void this$dist$set$2(java.lang.String, java.lang.Object);&lt;br /&gt;    public java.lang.Object this$dist$get$2(java.lang.String);&lt;br /&gt;    protected groovy.lang.MetaClass $getStaticMetaClass();&lt;br /&gt;    public groovy.lang.MetaClass getMetaClass();&lt;br /&gt;    public void setMetaClass(groovy.lang.MetaClass);&lt;br /&gt;    public java.lang.Object invokeMethod(java.lang.String, java.lang.Object);&lt;br /&gt;    public java.lang.Object getProperty(java.lang.String);&lt;br /&gt;    public void setProperty(java.lang.String, java.lang.Object);&lt;br /&gt;    static {};&lt;br /&gt;    public void super$1$wait();&lt;br /&gt;    public java.lang.String super$1$toString();&lt;br /&gt;    public void super$1$wait(long);&lt;br /&gt;    public void super$1$wait(long, int);&lt;br /&gt;    public void super$1$notify();&lt;br /&gt;    public void super$1$notifyAll();&lt;br /&gt;    public java.lang.Class super$1$getClass();&lt;br /&gt;    public java.lang.Object super$1$clone();&lt;br /&gt;    public boolean super$1$equals(java.lang.Object);&lt;br /&gt;    public int super$1$hashCode();&lt;br /&gt;    public void super$1$finalize();&lt;br /&gt;    static java.lang.Class class$(java.lang.String);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Also note that it's still allowed to explicitly define getter/setter and Groovy automatically picks it up during field access:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; def property1&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;protected&lt;/span&gt; String property2&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Current 'property1' field value is $test.property1"&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Setting value to the 'property1' field..."&lt;/span&gt;&lt;br /&gt;    test.property1 = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Current 'property1' field value is $test.property1"&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; setProperty1(value) {&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"setProperty1() is called with value '$value'"&lt;/span&gt;&lt;br /&gt;    property1 = value&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Current 'property1' field value is null&lt;br /&gt;Setting value to the 'property1' field...&lt;br /&gt;setProperty1() is called with value 'xxx'&lt;br /&gt;Current 'property1' field value is xxx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="listeners"&gt;Bound and constrained properties support&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Groovy provides convenient way to define bound and constrained properties:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;bound property&lt;/span&gt; - property which change fires notification for interested listeners;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;constrained property&lt;/span&gt; - property which change may be prevented;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;@Bindable&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;@Vetoable&lt;/span&gt; annotations are used for that:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; groovy.beans.Bindable&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; groovy.beans.Vetoable&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; java.beans.PropertyVetoException&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#808000;"&gt;@Bindable&lt;/span&gt; def property1&lt;br /&gt;  &lt;span style="color:#808000;"&gt;@Vetoable&lt;/span&gt; Integer property2&lt;br /&gt;&lt;br /&gt;  def &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(args) {&lt;br /&gt;    def test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; GroovyTestClass()&lt;br /&gt;&lt;br /&gt;    test.propertyChange = {&lt;br /&gt;      println &lt;span style="color:#008000;font-weight:bold;"&gt;"Got notification that '$it.propertyName' property value is set to '$it.newValue'"&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    test.vetoableChange = {&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (it.newValue &amp;lt;= 0) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;throw&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; PropertyVetoException(&lt;span style="color:#008000;font-weight:bold;"&gt;"Detected attempt to set non-positive value ($it.newValue) to the property"&lt;/span&gt;&lt;br /&gt;                                           + &lt;span style="color:#008000;font-weight:bold;"&gt;"'$it.propertyName'. Rejected."&lt;/span&gt;, it)&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Setting 'xxx' value to the 'property1' field..."&lt;/span&gt;&lt;br /&gt;    test.property1 = &lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Setting '1' value to the 'property1' field..."&lt;/span&gt;&lt;br /&gt;    test.property2 = 1&lt;br /&gt;&lt;br /&gt;    println &lt;span style="color:#008000;font-weight:bold;"&gt;"Setting '-1' value to the 'property1' field..."&lt;/span&gt;&lt;br /&gt;    test.property2 = -1&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Setting 'xxx' value to the 'property1' field...&lt;br /&gt;Got notification that 'property1' property value is set to 'xxx'&lt;br /&gt;Setting '1' value to the 'property1' field...&lt;br /&gt;Setting '-1' value to the 'property1' field...&lt;br /&gt;Exception in thread "main" java.beans.PropertyVetoException: Detected attempt to set non-positive value (-1) to the property'property2'. Rejected.&lt;br /&gt; at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)&lt;br /&gt; at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)&lt;br /&gt; at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)&lt;br /&gt; at java.lang.reflect.Constructor.newInstance(Constructor.java:513)&lt;br /&gt; at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)&lt;br /&gt; at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:71)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:52)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:192)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:204)&lt;br /&gt; at org.denis.GroovyTestClass$_main_closure2.doCall(GroovyTestClass.groovy:21)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;br /&gt; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;br /&gt; at java.lang.reflect.Method.invoke(Method.java:597)&lt;br /&gt; at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)&lt;br /&gt; at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)&lt;br /&gt; at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273)&lt;br /&gt; at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)&lt;br /&gt; at groovy.lang.Closure.call(Closure.java:276)&lt;br /&gt; at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:51)&lt;br /&gt; at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:79)&lt;br /&gt; at $Proxy1.vetoableChange(Unknown Source)&lt;br /&gt; at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.java:335)&lt;br /&gt; at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.java:252)&lt;br /&gt; at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.java:273)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;br /&gt; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;br /&gt; at java.lang.reflect.Method.invoke(Method.java:597)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:229)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:54)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)&lt;br /&gt; at org.denis.GroovyTestClass.fireVetoableChange(GroovyTestClass.groovy)&lt;br /&gt; at org.denis.GroovyTestClass$fireVetoableChange.callCurrent(Unknown Source)&lt;br /&gt; at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)&lt;br /&gt; at org.denis.GroovyTestClass$fireVetoableChange.callCurrent(Unknown Source)&lt;br /&gt; at org.denis.GroovyTestClass.setProperty2(GroovyTestClass.groovy)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;br /&gt; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;br /&gt; at java.lang.reflect.Method.invoke(Method.java:597)&lt;br /&gt; at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)&lt;br /&gt; at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)&lt;br /&gt; at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2387)&lt;br /&gt; at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3307)&lt;br /&gt; at org.denis.GroovyTestClass.setProperty(GroovyTestClass.groovy)&lt;br /&gt; at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:179)&lt;br /&gt; at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:483)&lt;br /&gt; at org.denis.GroovyTestClass.main(GroovyTestClass.groovy:33)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Note that Groovy closuers are used at the last example. We'll talk about them at the next articles.&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2962422681277232900?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2962422681277232900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2962422681277232900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2962422681277232900'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html' title='Groovy features, part 2 - java beans'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-6756617285143856625</id><published>2010-04-20T12:11:00.007+04:00</published><updated>2010-04-22T12:56:55.109+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Exploring Groovy, part 1 - common stuff</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#foreword"&gt;Foreword&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#semicolon"&gt;Semicolon&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#return"&gt;Return&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#visibility"&gt;Default visibility&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#safe-navigation-operator"&gt;Safe navigation operator&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#boolean-evaluation"&gt;Boolean evaluation&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#elvis-operator"&gt;Elvis operator&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#exception"&gt;Exception handling&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="foreword"&gt;Foreword&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I &lt;a href="http://denis-zhdanov.blogspot.com/2010/04/jet-fuel.html"&gt;started working at new company&lt;/a&gt; recently and encountered that &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; is used for various non-performance critical tasks here. I follow the principle that &lt;a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;leaky abstractions&lt;/a&gt; should be avoided whenever possible, hence, it's a time to learn Groovy.&lt;br /&gt;&lt;br /&gt;Couple of words about it - &lt;span style="font-style:italic;"&gt;Groovy&lt;/span&gt; is a dynamic language that provides concise syntax and metaprogramming facilities, is executed under JVM and completely interoperable with java code, i.e. it's possible either to use groovy from java or java from groovy. The only drawback I see for now is performance aspect - groovy heavily uses reflection, type-checks, exception-based processing. However, that may be the tool of choice for application prototyping and various support tasks like buildmastering.&lt;br /&gt;&lt;br /&gt;I'm going to highlight groovy faetures that are the most significant for java developers that want to get familiar with groovy.&lt;br /&gt;&lt;br /&gt;Next part - &lt;a href="http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-2-java-beans.html"&gt;Groovy features, part 2 - java beans&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="semicolon"&gt;Semicolon&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Semicolon is almost optional in Groovy. You can use it to separate the statements if necessary. I.e. following groovy script works just fine&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;print(&lt;span style="color:#008000;font-weight:bold;"&gt;'hello, '&lt;/span&gt;)&lt;br /&gt;println(&lt;span style="color:#008000;font-weight:bold;"&gt;'world'&lt;/span&gt;)&lt;br /&gt;print(&lt;span style="color:#008000;font-weight:bold;"&gt;'hello '&lt;/span&gt;); println(&lt;span style="color:#008000;font-weight:bold;"&gt;'one more time'&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="return"&gt;Return&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;'return'&lt;/span&gt; keyword is optional:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def test(i) { i &amp;gt; 0 }&lt;br /&gt;&lt;br /&gt;value = 4&lt;br /&gt;printf(&lt;span style="color:#008000;font-weight:bold;"&gt;'%d is %spositive%n'&lt;/span&gt;, value, test(value) ? &lt;span style="color:#008000;font-weight:bold;"&gt;''&lt;/span&gt; : &lt;span style="color:#008000;font-weight:bold;"&gt;'not '&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="visibility"&gt;Default visibility&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Methods and classes are public by default in groovy:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; org.denis&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; GroovyTestClass {&lt;br /&gt;  def test() { println &lt;span style="color:#008000;font-weight:bold;"&gt;'test'&lt;/span&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;projects/java/test/target$ javap org.denis.GroovyTestClass&lt;br /&gt;Compiled from "GroovyTestClass.groovy"&lt;br /&gt;public class org.denis.GroovyTestClass extends java.lang.Object implements groovy.lang.GroovyObject{&lt;br /&gt;    public static final java.lang.Class $ownClass;&lt;br /&gt;    public static java.lang.Long __timeStamp;&lt;br /&gt;    public static java.lang.Long __timeStamp__239_neverHappen1271752231139;&lt;br /&gt;    public org.denis.GroovyTestClass();&lt;br /&gt;    public java.lang.Object test();&lt;br /&gt;    protected groovy.lang.MetaClass $getStaticMetaClass();&lt;br /&gt;    public groovy.lang.MetaClass getMetaClass();&lt;br /&gt;    public void setMetaClass(groovy.lang.MetaClass);&lt;br /&gt;    public java.lang.Object invokeMethod(java.lang.String, java.lang.Object);&lt;br /&gt;    public java.lang.Object getProperty(java.lang.String);&lt;br /&gt;    public void setProperty(java.lang.String, java.lang.Object);&lt;br /&gt;    static {};&lt;br /&gt;    public void super$1$wait();&lt;br /&gt;    public java.lang.String super$1$toString();&lt;br /&gt;    public void super$1$wait(long);&lt;br /&gt;    public void super$1$wait(long, int);&lt;br /&gt;    public void super$1$notify();&lt;br /&gt;    public void super$1$notifyAll();&lt;br /&gt;    public java.lang.Class super$1$getClass();&lt;br /&gt;    public java.lang.Object super$1$clone();&lt;br /&gt;    public boolean super$1$equals(java.lang.Object);&lt;br /&gt;    public int super$1$hashCode();&lt;br /&gt;    public void super$1$finalize();&lt;br /&gt;    static java.lang.Class class$(java.lang.String);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;You can see that either &lt;span style="font-style:italic;"&gt;GroovyTestClass&lt;/span&gt; or &lt;span style="font-style:italic;"&gt;GroovyTestClass.test()&lt;/span&gt; visibility is &lt;span style="font-style:italic;"&gt;public&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="safe-navigation-operator"&gt;Safe navigation operator&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Groovy offers convenient operator &lt;span style="font-style:italic;"&gt;'?.'&lt;/span&gt; - it is used with object references for checking that it's not null, i.e. it returns &lt;span style="font-style:italic;"&gt;null&lt;/span&gt; if it's applied to null or proceeds to the target method instead:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; Address {&lt;br /&gt;  def street&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; User {&lt;br /&gt;  def name&lt;br /&gt;  def address&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;user1 = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; User(name: &lt;span style="color:#008000;font-weight:bold;"&gt;'Guy'&lt;/span&gt;, address: &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Address(street: &lt;span style="color:#008000;font-weight:bold;"&gt;'Reg Lights District'&lt;/span&gt;))&lt;br /&gt;user2 = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; User()&lt;br /&gt;&lt;br /&gt;println &lt;span style="color:#008000;font-weight:bold;"&gt;'Processing user1'&lt;/span&gt;&lt;br /&gt;println user1.address.street&lt;br /&gt;println user1.name&lt;br /&gt;&lt;br /&gt;println &lt;span style="color:#008000;font-weight:bold;"&gt;'Processing user2 with ?.'&lt;/span&gt;&lt;br /&gt;println user2?.address?.street&lt;br /&gt;println user2?.name&lt;br /&gt;&lt;br /&gt;println &lt;span style="color:#008000;font-weight:bold;"&gt;'Processing user2 without ?.'&lt;/span&gt;&lt;br /&gt;println user2.address.street&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Processing user1&lt;br /&gt;Reg Lights District&lt;br /&gt;Guy&lt;br /&gt;Processing user2 with ?.&lt;br /&gt;null&lt;br /&gt;null&lt;br /&gt;Processing user2 without ?.&lt;br /&gt;Caught: java.lang.NullPointerException: Cannot get property 'street' on null object&lt;br /&gt; at GroovyTest.run(GroovyTest.groovy:22)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="boolean-evaluation"&gt;Boolean evaluation&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Groovy provides special rules for using objects of various types at boolean context:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def test(value, description) {&lt;br /&gt;  evaluationResult = value ? &lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt; : &lt;span style="color:#000080;font-weight:bold;"&gt;false&lt;/span&gt;;&lt;br /&gt;  printf &lt;span style="color:#008000;font-weight:bold;"&gt;"%s '%s' evaluates to %b%n"&lt;/span&gt;, description, value, evaluationResult&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;test(&lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;, &lt;span style="color:#008000;font-weight:bold;"&gt;'boolean value'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#000080;font-weight:bold;"&gt;false&lt;/span&gt;, &lt;span style="color:#008000;font-weight:bold;"&gt;'boolean value'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#000080;font-weight:bold;"&gt;null&lt;/span&gt;, &lt;span style="color:#008000;font-weight:bold;"&gt;'null reference'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Object(), &lt;span style="color:#008000;font-weight:bold;"&gt;'non-null reference'&lt;/span&gt;)&lt;br /&gt;test([], &lt;span style="color:#008000;font-weight:bold;"&gt;'empty list'&lt;/span&gt;)&lt;br /&gt;test([1], &lt;span style="color:#008000;font-weight:bold;"&gt;'non-empty list'&lt;/span&gt;)&lt;br /&gt;test([:], &lt;span style="color:#008000;font-weight:bold;"&gt;'empty map'&lt;/span&gt;)&lt;br /&gt;test([1: 2], &lt;span style="color:#008000;font-weight:bold;"&gt;'non-empty map'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#008000;font-weight:bold;"&gt;''&lt;/span&gt;, &lt;span style="color:#008000;font-weight:bold;"&gt;'empty &lt;span style="color:#000080;font-weight:bold;"&gt;char&lt;/span&gt; sequence'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;, &lt;span style="color:#008000;font-weight:bold;"&gt;'non-empty &lt;span style="color:#000080;font-weight:bold;"&gt;char&lt;/span&gt; sequence'&lt;/span&gt;)&lt;br /&gt;test([].iterator(), &lt;span style="color:#008000;font-weight:bold;"&gt;'empty iterator'&lt;/span&gt;)&lt;br /&gt;test([1].iterator(), &lt;span style="color:#008000;font-weight:bold;"&gt;'non-empty iterator'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Properties().elements(), &lt;span style="color:#008000;font-weight:bold;"&gt;'empty enumeration'&lt;/span&gt;)&lt;br /&gt;test(System.properties.elements(), &lt;span style="color:#008000;font-weight:bold;"&gt;'non-empty enumeration'&lt;/span&gt;)&lt;br /&gt;test([1].iterator(), &lt;span style="color:#008000;font-weight:bold;"&gt;'non-empty iterator'&lt;/span&gt;)&lt;br /&gt;test(0.01, &lt;span style="color:#008000;font-weight:bold;"&gt;'none-zero number &lt;span style="color:#000080;font-weight:bold;"&gt;double&lt;/span&gt; value'&lt;/span&gt;)&lt;br /&gt;test(0, &lt;span style="color:#008000;font-weight:bold;"&gt;'zero number &lt;span style="color:#000080;font-weight:bold;"&gt;double&lt;/span&gt; value'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#008000;font-weight:bold;"&gt;'test'&lt;/span&gt; =~ /es/, &lt;span style="color:#008000;font-weight:bold;"&gt;'matcher with at least one match'&lt;/span&gt;)&lt;br /&gt;test(&lt;span style="color:#008000;font-weight:bold;"&gt;'test'&lt;/span&gt; =~ /se/, &lt;span style="color:#008000;font-weight:bold;"&gt;'matcher with no match'&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;boolean value 'true' evaluates to true&lt;br /&gt;boolean value 'false' evaluates to false&lt;br /&gt;null reference 'null' evaluates to false&lt;br /&gt;non-null reference 'java.lang.Object@51e67ac' evaluates to true&lt;br /&gt;empty list '[]' evaluates to false&lt;br /&gt;non-empty list '[1]' evaluates to true&lt;br /&gt;empty map '{}' evaluates to false&lt;br /&gt;non-empty map &lt;span style="color:#0000ff;font-weight:bold;"&gt;'{1=&lt;/span&gt;2}' evaluates to true&lt;br /&gt;empty char sequence '' evaluates to false&lt;br /&gt;non-empty char sequence 'xxx' evaluates to true&lt;br /&gt;empty iterator 'java.util.AbstractList$Itr@1d2c5431' evaluates to false&lt;br /&gt;non-empty iterator 'java.util.AbstractList$Itr@494b6bed' evaluates to true&lt;br /&gt;empty enumeration 'java.util.Hashtable$EmptyEnumerator@24ebf068' evaluates to false&lt;br /&gt;non-empty enumeration 'java.util.Hashtable$Enumerator@2a313170' evaluates to true&lt;br /&gt;non-empty iterator 'java.util.AbstractList$Itr@3a4c5b4' evaluates to true&lt;br /&gt;none-zero number double value '0.01' evaluates to true&lt;br /&gt;zero number double value '0' evaluates to false&lt;br /&gt;matcher with at least one match &lt;span style="color:#0000ff;font-weight:bold;"&gt;'java.util.regex.Matcher[pattern=&lt;/span&gt;es &lt;span style="color:#0000ff;font-weight:bold;"&gt;region=&lt;/span&gt;0,4 &lt;span style="color:#0000ff;font-weight:bold;"&gt;lastmatch=&lt;/span&gt;es]' evaluates to true&lt;br /&gt;matcher with no match &lt;span style="color:#0000ff;font-weight:bold;"&gt;'java.util.regex.Matcher[pattern=&lt;/span&gt;se &lt;span style="color:#0000ff;font-weight:bold;"&gt;region=&lt;/span&gt;0,4 &lt;span style="color:#0000ff;font-weight:bold;"&gt;lastmatch=&lt;/span&gt;]' evaluates to false&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="elvis-operator"&gt;Elvis operator&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;There is a short form of ternary operator - &lt;span style="font-style:italic;"&gt;'?:'&lt;/span&gt;. It works as follows - use left operand if it evaluates to &lt;span style="font-style:italic;"&gt;true&lt;/span&gt;; use right operand otherwise:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;println([]?: &lt;span style="color:#008000;font-weight:bold;"&gt;'empty array'&lt;/span&gt;)&lt;br /&gt;println(null?: &lt;span style="color:#008000;font-weight:bold;"&gt;'null reference'&lt;/span&gt;)&lt;br /&gt;println(&lt;span style="color:#008000;font-weight:bold;"&gt;''&lt;/span&gt;?: &lt;span style="color:#008000;font-weight:bold;"&gt;'empty &lt;span style="color:#000080;font-weight:bold;"&gt;char&lt;/span&gt; sequence'&lt;/span&gt;)&lt;br /&gt;println([1]?: &lt;span style="color:#008000;font-weight:bold;"&gt;'empty array'&lt;/span&gt;)&lt;br /&gt;println(&lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Object()?: &lt;span style="color:#008000;font-weight:bold;"&gt;'null reference'&lt;/span&gt;)&lt;br /&gt;println(&lt;span style="color:#008000;font-weight:bold;"&gt;'xxx'&lt;/span&gt;?: &lt;span style="color:#008000;font-weight:bold;"&gt;'empty &lt;span style="color:#000080;font-weight:bold;"&gt;char&lt;/span&gt; sequence'&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;empty array&lt;br /&gt;null reference&lt;br /&gt;empty char sequence&lt;br /&gt;[1]&lt;br /&gt;java.lang.Object@1408a92&lt;br /&gt;xxx&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="exception"&gt;Exception handling&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Groovy doesn't require to handle checked exceptions. Another feature is that it's possible to use more concise syntax for catching all &lt;span style="font-style:italic;"&gt;Exceptions&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; Test {&lt;br /&gt;&lt;br /&gt;  def test() {&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;// Not obliged to declare the exception at method signature&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;throw&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IOException()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;test = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Test()&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;try&lt;/span&gt; {&lt;br /&gt;  test.test()&lt;br /&gt;} &lt;span style="color:#000080;font-weight:bold;"&gt;catch&lt;/span&gt; (ex) { &lt;span style="color:#808080;font-style:italic;"&gt;// Only Exception are handled here, all Errors and Throwable are popped up to the stack&lt;br /&gt;&lt;/span&gt;  println &lt;span style="color:#008000;font-weight:bold;"&gt;'Exception is caught: '&lt;/span&gt; + ex&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-6756617285143856625?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/6756617285143856625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/6756617285143856625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/6756617285143856625'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/groovy-features-part-1.html' title='Exploring Groovy, part 1 - common stuff'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-9043029438135526611</id><published>2010-04-13T22:30:00.000+04:00</published><updated>2010-04-14T21:09:00.826+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='society'/><title type='text'>Apache is hacked</title><content type='html'>I read that &lt;a href="https://blogs.apache.org/infra/entry/apache_org_04_09_2010"&gt;Apache was hacked recently&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Couple of comments for that:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Really respect the way Apache team processed that - shared the information and provided detailed attack description. It's really cool that the guys don't afraid to face the music;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I don't have enough experience in 'hacking stuff' but used attack algorithm seems rather elegant, nice job :)&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-9043029438135526611?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/9043029438135526611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/apache-is-hacked.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/9043029438135526611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/9043029438135526611'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/apache-is-hacked.html' title='Apache is hacked'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2635408992995990914</id><published>2010-04-05T23:29:00.003+04:00</published><updated>2010-04-05T23:38:40.648+04:00</updated><title type='text'>Jet fuel</title><content type='html'>Today was my first day at new job - &lt;a href="http://www.jetbrains.com/"&gt;JetBrains&lt;/a&gt; company, &lt;a href="http://www.jetbrains.com/idea/index.html"&gt;IntelliJ IDEA&lt;/a&gt; project.&lt;br /&gt;&lt;br /&gt;I've been IDEA user for more than five years and really enjoy it. It's ... interesting to be a part of the team that makes this product :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2635408992995990914?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2635408992995990914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/jet-fuel.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2635408992995990914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2635408992995990914'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/jet-fuel.html' title='Jet fuel'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2071308120962301557</id><published>2010-04-01T21:34:00.008+04:00</published><updated>2010-04-08T11:06:48.892+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pets'/><title type='text'>Kittens</title><content type='html'>My kittens get bigger. They look like a real cats now :)&lt;br /&gt;&lt;br /&gt;Photos inside&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Ta3ZxVutI/AAAAAAAAAJ8/QozWALIxDlo/s1600/IMG_2206.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Ta3ZxVutI/AAAAAAAAAJ8/QozWALIxDlo/s320/IMG_2206.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455225693998004946" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S7TbG72yXDI/AAAAAAAAAKE/IdLGYYK0-K4/s1600/IMG_2209.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S7TbG72yXDI/AAAAAAAAAKE/IdLGYYK0-K4/s320/IMG_2209.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455225960845696050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7TcRrjYqLI/AAAAAAAAAKM/5Qwho9YiEKY/s1600/IMG_2211.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7TcRrjYqLI/AAAAAAAAAKM/5Qwho9YiEKY/s320/IMG_2211.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455227244959541426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S7TcRxqNy5I/AAAAAAAAAKU/a9i9wTn3VXc/s1600/IMG_2213.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S7TcRxqNy5I/AAAAAAAAAKU/a9i9wTn3VXc/s320/IMG_2213.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455227246598802322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S7TcSJCPMQI/AAAAAAAAAKc/GbtQMjyHjOg/s1600/IMG_2221.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S7TcSJCPMQI/AAAAAAAAAKc/GbtQMjyHjOg/s320/IMG_2221.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455227252873572610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S7TcSh8aSKI/AAAAAAAAAKk/-adITBl2APw/s1600/IMG_2225.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S7TcSh8aSKI/AAAAAAAAAKk/-adITBl2APw/s320/IMG_2225.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455227259560020130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S7TcS6PKvxI/AAAAAAAAAKs/Lc5l6ZRJlxY/s1600/IMG_2232.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S7TcS6PKvxI/AAAAAAAAAKs/Lc5l6ZRJlxY/s320/IMG_2232.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455227266081144594" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Tdp7KnXQI/AAAAAAAAALE/rQdXp4xv0xc/s1600/IMG_2237.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Tdp7KnXQI/AAAAAAAAALE/rQdXp4xv0xc/s320/IMG_2237.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455228760979102978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S7Tdv6cMJnI/AAAAAAAAALM/_AUKYvWrDqU/s1600/IMG_2239.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S7Tdv6cMJnI/AAAAAAAAALM/_AUKYvWrDqU/s320/IMG_2239.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455228863863596658" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Td0qfoALI/AAAAAAAAALU/z7AyDA6kkHo/s1600/IMG_2240.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Td0qfoALI/AAAAAAAAALU/z7AyDA6kkHo/s320/IMG_2240.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5455228945482383538" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2071308120962301557?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2071308120962301557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/kittens.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2071308120962301557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2071308120962301557'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/04/kittens.html' title='Kittens'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_wBtqK4BXFZc/S7Ta3ZxVutI/AAAAAAAAAJ8/QozWALIxDlo/s72-c/IMG_2206.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-3181788131796078781</id><published>2010-03-23T19:38:00.003+03:00</published><updated>2010-03-23T21:46:30.056+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Compound iterators in Scala - present and future</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html#introduction"&gt;Introduction&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html#iterators"&gt;Traits and Iterator trait&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html#compound"&gt;Compound iterators&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html#problem"&gt;Problem with compound iterators&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html#solution"&gt;Solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="introduction"&gt;Introduction&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;This article is about another step made by java guy to the world of &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. It's not that hard to learn new programing language syntax but it's just a half of the deal. There is a large library as well and collections is its integral part. So, I started with them and want to share already obtained knowledge.&lt;br /&gt;&lt;br /&gt;P.S. Significant result of checking Scala iterators is my first Scala enhancement request - &lt;a href="https://lampsvn.epfl.ch/trac/scala/ticket/3205"&gt;Ticket #3205: Optimize performance of compound iterator created via Iterator.++()&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="iterators"&gt;Traits and Iterator trait&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Scala has a notion of &lt;a href="http://www.scala-lang.org/node/126"&gt;traits&lt;/a&gt;. Basically speaking, &lt;span style="font-style:italic;"&gt;'trait'&lt;/span&gt; is a combination of &lt;span style="font-style:italic;"&gt;'abstract class'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'interface'&lt;/span&gt; in terms of java. Here are the main trait features from my point of view:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;trait may contain either abstract or concrete methods (similar to abstract classes in java);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;single class may extend multiple traits (like multiple interfaces inheritance in java);&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;That means that it's possible to define either abstract methods or concrete methods that are based on them. Scala &lt;a href="http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/Iterator.html"&gt;Iterator&lt;/a&gt; trait is a classic example of such approach. It defines abstract methods &lt;span style="font-style:italic;"&gt;'hasNext()'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'next()'&lt;/span&gt; and couple of dozens other methods that are based on them.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="compound"&gt;Compound iterators&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;One of concrete methods of &lt;span style="font-style:italic;"&gt;Iterator&lt;/span&gt; trait is &lt;a href="http://www.scala-lang.org/docu/files/api/scala/Iterator.html#%2B%2B%28%3D%3EIterator%5BB%5D%29"&gt;++()&lt;/a&gt;. It does the following:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Receives lazily evaluated iterator;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Produces iterator that combines both current and given iterators;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;object ScalaTest {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; MyIterator(val value: Int) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Iterator[Int] {&lt;br /&gt;&lt;br /&gt;    println(&lt;span style="color:#000080;font-weight:bold;"&gt;this&lt;/span&gt; + &lt;span style="color:#008000;font-weight:bold;"&gt;" is being constructed"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;    var empty = false&lt;br /&gt;&lt;br /&gt;    def hasNext = !empty&lt;br /&gt;    def next() = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (empty) Iterator.empty.next&lt;br /&gt;                 &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; {empty = &lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;; value}&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"Creating compound iterator"&lt;/span&gt;)&lt;br /&gt;    val i = MyIterator(1) ++ MyIterator(2) ++ MyIterator(3)&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"Created compound iterator, starting iteration..."&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (i.hasNext) println(i.next)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We get the following output from example above:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Creating compound iterator&lt;br /&gt;non-empty iterator is being constructed&lt;br /&gt;Created compound iterator, starting iteration...&lt;br /&gt;1&lt;br /&gt;non-empty iterator is being constructed&lt;br /&gt;2&lt;br /&gt;non-empty iterator is being constructed&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That shows two things:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style:italic;"&gt;'Iterator.++()'&lt;/span&gt; method really glues iterators together;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;all iterators starting from the second are evaluated lazily (that is done because &lt;span style="font-style:italic;"&gt;'Iterator.++()'&lt;/span&gt; receives its parameter &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; as described at &lt;a href="http://denis-zhdanov.blogspot.com/2010/03/working-with-by-name-arguments-in-scala.html"&gt;previous post&lt;/a&gt;);&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="problem"&gt;Problem with compound iterators&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;'Iterator.++()'&lt;/span&gt; works fine from the first sight, however, important problem is hidden there.&lt;br /&gt;&lt;br /&gt;Current implementation looks as follows:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;  def ++[B &amp;gt;: A](that: =&amp;gt; Iterator[B]): Iterator[B] = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Iterator[B] {&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;// optimize a little bit to prevent n log n behavior.&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var cur : Iterator[B] = self &lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;// this was unnecessarily looping forever on x ++ x&lt;br /&gt;&lt;/span&gt;    def hasNext = cur.hasNext || ((cur eq self) &amp;&amp; {&lt;br /&gt;      val it = that&lt;br /&gt;      it.hasNext &amp;&amp; {&lt;br /&gt;        cur = it&lt;br /&gt;        true&lt;br /&gt;      }&lt;br /&gt;    })&lt;br /&gt;    def next() = { hasNext; cur.next() }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Let's modify our example a little in order to highlight a problem:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;object ScalaTest {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; MyIterator(val value: Int) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Iterator[Int] {&lt;br /&gt;&lt;br /&gt;    var empty = false&lt;br /&gt;&lt;br /&gt;    def hasNext = {Thread.dumpStack; !empty}&lt;br /&gt;    def next() = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (empty) Iterator.empty.next&lt;br /&gt;                 &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; {empty = &lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;; value}&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"Creating compound iterator"&lt;/span&gt;)&lt;br /&gt;    val i = MyIterator(1) ++ MyIterator(2) ++ MyIterator(3)&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"Created compound iterator, starting iteration..."&lt;/span&gt;)&lt;br /&gt;    i.next&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I.e. we dump current stack on &lt;span style="font-style:italic;"&gt;'hasNext()'&lt;/span&gt; call on our iterator. Here is the output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;Creating compound iterator&lt;br /&gt;java.lang.Exception: Stack trace&lt;br /&gt; at java.lang.Thread.dumpStack(Thread.java:1206)&lt;br /&gt; at net.scalatest.ScalaTest$MyIterator.hasNext(ScalaTest.scala:13)&lt;br /&gt; at scala.collection.Iterator$$anon$20.hasNext(Iterator.scala:340)&lt;br /&gt; at scala.collection.Iterator$$anon$20.hasNext(Iterator.scala:340)&lt;br /&gt; at scala.collection.Iterator$$anon$20.next(Iterator.scala:347)&lt;br /&gt; at net.scalatest.ScalaTest$.main(ScalaTest.scala:22)&lt;br /&gt; at net.scalatest.ScalaTest.main(ScalaTest.scala)&lt;br /&gt;java.lang.Exception: Stack trace&lt;br /&gt; at java.lang.Thread.dumpStack(Thread.java:1206)&lt;br /&gt; at net.scalatest.ScalaTest$MyIterator.hasNext(ScalaTest.scala:13)&lt;br /&gt; at scala.collection.Iterator$$anon$20.hasNext(Iterator.scala:340)&lt;br /&gt; at scala.collection.Iterator$$anon$20.next(Iterator.scala:347)&lt;br /&gt; at scala.collection.Iterator$$anon$20.next(Iterator.scala:347)&lt;br /&gt; at net.scalatest.ScalaTest$.main(ScalaTest.scala:22)&lt;br /&gt; at net.scalatest.ScalaTest.main(ScalaTest.scala)&lt;br /&gt;Created compound iterator, starting iteration...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Two things to highlight:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style:italic;"&gt;'hasNext()'&lt;/span&gt; is called two times though we only called &lt;span style="font-style:italic;"&gt;'next()'&lt;/span&gt; on compound iterator;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;every call to &lt;span style="font-style:italic;"&gt;'hasNext()'&lt;/span&gt; is preceded by nested calls to &lt;span style="font-style:italic;"&gt;'hasNext()'&lt;/span&gt; on compound iterator objects;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Such behavior doesn't surprise if we check current implementation. That is a real performance bottleneck in case of large number of glued iterators.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="solution"&gt;Solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;I created alternative &lt;span style="font-style:italic;"&gt;'Iterator.++()'&lt;/span&gt; implementation that addresses problems mentioned above:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;    def ++[B &amp;gt;: A](that: =&amp;gt; Iterator[B]) : Iterator[B] = {&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; Node[T](val current: () =&amp;gt; Iterator[T]) {&lt;br /&gt;        var next: Option[Node[T]] = None&lt;br /&gt;        def append[U &amp;gt;: T](i: =&amp;gt; Iterator[U]) : Node[U] = {&lt;br /&gt;          def doAppend(to: Node[U], from: Option[Node[T]]) : Node[U] = {&lt;br /&gt;            from match {&lt;br /&gt;              &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; to&lt;br /&gt;              &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(n) =&amp;gt; {val node: Node[U] = Node(n.current); to.next = Some(node); doAppend(node, n.next)}&lt;br /&gt;            }&lt;br /&gt;          }&lt;br /&gt;          val result: Node[U] = Node(current)&lt;br /&gt;          lazy val it = i&lt;br /&gt;          doAppend(result, next).next = Some(Node(() =&amp;gt; it))&lt;br /&gt;          result&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; CombinedIterator[T](var head: Node[T]) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Iterator[T] {&lt;br /&gt;&lt;br /&gt;        var checkNext = true&lt;br /&gt;&lt;br /&gt;        def hasNext = {&lt;br /&gt;          checkNext = false&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (head.current().hasNext) true&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; head.next match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; false&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {head = x; hasNext}&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        def next() = {&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (checkNext) hasNext&lt;br /&gt;          checkNext = true&lt;br /&gt;          head.current().next&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        override def ++[B &amp;gt;: T](that: =&amp;gt; Iterator[B]) = {&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; CombinedIterator(head.append(that))&lt;br /&gt;        }&lt;br /&gt;      }      &lt;br /&gt;&lt;br /&gt;      val node: Node[B]= Node(() =&amp;gt; self)&lt;br /&gt;      lazy val t = that&lt;br /&gt;      node.next = Some(Node(() =&amp;gt; t))&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; CombinedIterator(node)&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;The main idea is to avoid nested calls by building list of glued iterators on compound iterator instantiation. Also we don't call &lt;span style="font-style:italic;"&gt;'hasNext()'&lt;/span&gt; from &lt;span style="font-style:italic;"&gt;'next()'&lt;/span&gt; if it's not necessary.&lt;br /&gt;&lt;br /&gt;I offered the code above to Scala team, let's see if they like it - &lt;a href="https://lampsvn.epfl.ch/trac/scala/ticket/3205"&gt;Ticket #3205: Optimize performance of compound iterator created via Iterator.++()&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a simple driver program that shows performance difference between current Scala implementation and the one above:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;object CollectionProcessing {&lt;br /&gt;  trait MyIterator[+A] {self =&amp;gt;&lt;br /&gt;    def hasNext: Boolean&lt;br /&gt;&lt;br /&gt;    def next(): A&lt;br /&gt;&lt;br /&gt;    def ++[B &amp;gt;: A](that: =&amp;gt; MyIterator[B]): MyIterator[B] = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; MyIterator[B] {&lt;br /&gt;      &lt;span style="color:#808080;font-style:italic;"&gt;// optimize a little bit to prevent n log n behavior.&lt;br /&gt;&lt;/span&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var cur: MyIterator[B] = self&lt;br /&gt;      &lt;span style="color:#808080;font-style:italic;"&gt;// this was unnecessarily looping forever on x ++ x&lt;br /&gt;&lt;/span&gt;      def hasNext = {&lt;br /&gt;        cur.hasNext || ((cur eq self) &amp;&amp; {&lt;br /&gt;          val it = that&lt;br /&gt;          it.hasNext &amp;&amp; {&lt;br /&gt;            cur = it&lt;br /&gt;            true&lt;br /&gt;          }&lt;br /&gt;        })&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      def next() = {hasNext; cur.next()}&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def +++[B &amp;gt;: A](that: =&amp;gt; MyIterator[B]) : MyIterator[B] = {&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; Node[T](val current: () =&amp;gt; MyIterator[T]) {&lt;br /&gt;        var next: Option[Node[T]] = None&lt;br /&gt;        def append[U &amp;gt;: T](i: =&amp;gt; MyIterator[U]) : Node[U] = {&lt;br /&gt;          def doAppend(to: Node[U], from: Option[Node[T]]) : Node[U] = {&lt;br /&gt;            from match {&lt;br /&gt;              &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; to&lt;br /&gt;              &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(n) =&amp;gt; {val node: Node[U] = Node(n.current); to.next = Some(node); doAppend(node, n.next)}&lt;br /&gt;            }&lt;br /&gt;          }&lt;br /&gt;          val result: Node[U] = Node(current)&lt;br /&gt;          lazy val it = i&lt;br /&gt;          doAppend(result, next).next = Some(Node(() =&amp;gt; it))&lt;br /&gt;          result&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; CombinedIterator[T](var head: Node[T]) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; MyIterator[T] {&lt;br /&gt;&lt;br /&gt;        var checkNext = true&lt;br /&gt;&lt;br /&gt;        def hasNext = {&lt;br /&gt;          checkNext = false&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (head.current().hasNext) true&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; head.next match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; false&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {head = x; hasNext}&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        def next() = {&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (checkNext) hasNext&lt;br /&gt;          checkNext = true&lt;br /&gt;          head.current().next&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        override def +++[B &amp;gt;: T](that: =&amp;gt; MyIterator[B]) = {&lt;br /&gt;          &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; CombinedIterator(head.append(that))&lt;br /&gt;        }&lt;br /&gt;      }      &lt;br /&gt;&lt;br /&gt;      val node: Node[B]= Node(() =&amp;gt; self)&lt;br /&gt;      lazy val t = that&lt;br /&gt;      node.next = Some(Node(() =&amp;gt; t))&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; CombinedIterator(node)&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    var sum1 = 0L&lt;br /&gt;    var sum2 = 0L&lt;br /&gt;    var start = 0L&lt;br /&gt;    val ElementsPerIterator = 150&lt;br /&gt;    val IteratorsNumber = ElementsPerIterator&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (&lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;) {&lt;br /&gt;      sum1 = 0L&lt;br /&gt;      sum2 = 0L&lt;br /&gt;      val (standard, extended) = createInput(ElementsPerIterator, IteratorsNumber)&lt;br /&gt;      start = System.currentTimeMillis&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (standard.hasNext) {&lt;br /&gt;        sum1 += standard.next&lt;br /&gt;      }&lt;br /&gt;      println(&lt;span style="color:#008000;font-weight:bold;"&gt;"iteration standard: "&lt;/span&gt; + (System.currentTimeMillis - start) + &lt;span style="color:#008000;font-weight:bold;"&gt;" ms"&lt;/span&gt;)&lt;br /&gt;      &lt;br /&gt;      start = System.currentTimeMillis&lt;br /&gt;      &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (extended.hasNext) {&lt;br /&gt;        sum2 += extended.next&lt;br /&gt;      }&lt;br /&gt;      println(&lt;span style="color:#008000;font-weight:bold;"&gt;"iteration custom: "&lt;/span&gt; + (System.currentTimeMillis - start) + &lt;span style="color:#008000;font-weight:bold;"&gt;" ms"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;      require(sum1 == sum2)&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def createInput(elementsPerIterator: Int, iteratorsNumber: Int) = {&lt;br /&gt;    val random = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Random&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; IteratorImpl(var current: Int) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; MyIterator[Int] {&lt;br /&gt;      var remains = elementsPerIterator&lt;br /&gt;&lt;br /&gt;      def next() = {&lt;br /&gt;        remains -= 1&lt;br /&gt;        current += 1&lt;br /&gt;        current&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      def hasNext = remains &amp;gt; 0&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val base = random.nextInt&lt;br /&gt;    var standard: MyIterator[Int] = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;    var custom: MyIterator[Int] = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;    var remains = iteratorsNumber - 1&lt;br /&gt;    var timeStandard = 0L&lt;br /&gt;    var timeCustom = 0L&lt;br /&gt;    var startTime = 0L&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (remains &amp;gt; 0) {&lt;br /&gt;      val base = random.nextInt&lt;br /&gt;      startTime = System.currentTimeMillis&lt;br /&gt;      standard ++= &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;      timeStandard += System.currentTimeMillis - startTime&lt;br /&gt;      startTime = System.currentTimeMillis&lt;br /&gt;      custom +++= &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;      timeCustom += System.currentTimeMillis - startTime&lt;br /&gt;      remains -= 1&lt;br /&gt;    }&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"\nconstruction standard: "&lt;/span&gt; + timeStandard + &lt;span style="color:#008000;font-weight:bold;"&gt;" ms"&lt;/span&gt;)&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"construction custom: "&lt;/span&gt; + timeCustom + &lt;span style="color:#008000;font-weight:bold;"&gt;" ms"&lt;/span&gt;)&lt;br /&gt;    (standard, custom)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It shows about 700 times performance boost on my machine when we iterate 150 iterators of 150 elements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-3181788131796078781?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/3181788131796078781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3181788131796078781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3181788131796078781'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/compound-iterators-in-scala-present-and.html' title='Compound iterators in Scala - present and future'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-7539570056269305416</id><published>2010-03-22T19:59:00.003+03:00</published><updated>2010-03-22T22:03:07.450+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Working with by-name arguments in Scala</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/working-with-by-name-arguments-in-scala.html#preview"&gt;Preview&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/working-with-by-name-arguments-in-scala.html#task"&gt;Task&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/working-with-by-name-arguments-in-scala.html#solution"&gt;Solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="preview"&gt;Preview&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I talked about &lt;a href="http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html"&gt;various ways to deliver method parameters in Scala&lt;/a&gt; recently. We'll continue that by checking one important use-case that can arise during &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; parameters usage.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Task&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Let's consider the situation when we have a method with &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; argument and want to store that argument for future use.&lt;br /&gt;&lt;br /&gt;First implementation may look like below:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;object ScalaTest {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; DataHolder(var data: Int) {&lt;br /&gt;    def test() = {&lt;br /&gt;      println(data)&lt;br /&gt;      data += 1&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; Storage(i: () =&amp;gt; DataHolder)&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    val storage = wrap({println(&lt;span style="color:#008000;font-weight:bold;"&gt;"evaluation"&lt;/span&gt;); &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; DataHolder(1)})&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"after storages construction"&lt;/span&gt;)&lt;br /&gt;    storage.i().test&lt;br /&gt;    storage.i().test&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def wrap(holder: =&amp;gt; DataHolder) : Storage = {&lt;br /&gt;    Storage(() =&amp;gt; holder)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We were expecting to grab &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; parameter of &lt;span style="font-style:italic;"&gt;'wrap()'&lt;/span&gt; method and reuse it later. Also it was expected to be evaluated lazily. However, the thing is that we grab not desired &lt;span style="font-style:italic;"&gt;DataHolder&lt;/span&gt; reference but whole block &lt;span style="font-style:italic;"&gt;'{println("evaluation"); new DataHolder(1)}'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;We get the following output from example above:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;after storages construction&lt;br /&gt;evaluation&lt;br /&gt;1&lt;br /&gt;evaluation&lt;br /&gt;1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I.e. the argument is evaluated lazily but DataHolder object is recreated every time &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; argument is used.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="solution"&gt;Solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Scala allows to do the following trick for achieving desired result - it's possible to assign by-name parameter to &lt;span style="font-style:italic;"&gt;'lazy val'&lt;/span&gt;. Such construction does exactly what we need - lazily evaluates given parameter and remembers it:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;object ScalaTest {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; DataHolder(var data: Int) {&lt;br /&gt;    def test() = {&lt;br /&gt;      println(data)&lt;br /&gt;      data += 1&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; Storage(i: () =&amp;gt; DataHolder)&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    val storage1 = wrap1({println(&lt;span style="color:#008000;font-weight:bold;"&gt;"evaluation1"&lt;/span&gt;); &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; DataHolder(1)})&lt;br /&gt;    val storage2 = wrap2({println(&lt;span style="color:#008000;font-weight:bold;"&gt;"evaluation2"&lt;/span&gt;); &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; DataHolder(1)})&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"after storages construction"&lt;/span&gt;)&lt;br /&gt;    storage1.i().test&lt;br /&gt;    storage1.i().test&lt;br /&gt;    storage2.i().test&lt;br /&gt;    storage2.i().test&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def wrap1(holder: =&amp;gt; DataHolder) : Storage = {&lt;br /&gt;    Storage(() =&amp;gt; holder)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def wrap2[T](holder: =&amp;gt; DataHolder): Storage = {&lt;br /&gt;    lazy val h = holder&lt;br /&gt;    Storage(() =&amp;gt; h)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;after storages construction&lt;br /&gt;evaluation1&lt;br /&gt;1&lt;br /&gt;evaluation1&lt;br /&gt;1&lt;br /&gt;evaluation2&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-7539570056269305416?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/7539570056269305416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/working-with-by-name-arguments-in-scala.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7539570056269305416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7539570056269305416'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/working-with-by-name-arguments-in-scala.html' title='Working with by-name arguments in Scala'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-5852960277450042966</id><published>2010-03-21T21:43:00.005+03:00</published><updated>2010-03-21T23:10:46.369+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala method arguments processing - Iterator.++() doesn't work problem</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html#preview"&gt;Preview&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html#overview"&gt;Overview&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html#error"&gt;Broken compound iterator&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html#explanation"&gt;Explanation&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="preview"&gt;Preview&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I want to talk about available modes of method arguments delivery in Scala and couple of common pitfalls with that. That information is useful for all developers new to Scala, especially to the one without functional programming background (my case).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="overview"&gt;Overview&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Basically, there are three ways to deliver single method parameter in Scala. All of them are explained at &lt;a href="http://scala.sygneca.com/faqs/language#what-s-the-difference-between-a-lazy-argument-a-no-arg-function-argument-and-a-lazy-value"&gt;Scala wiki&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;normal (call-by-value)&lt;/span&gt; - argument is evaluated before method body execution;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;by-name&lt;/span&gt; - argument is lazily evaluated every time it's used;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;no-args function&lt;/span&gt; - argument is delivered as a no-args function that returns target value;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Here is an example that illustrates the above:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.scalatest&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Mar 21, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ArgumentDelivery {&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    testDefault({println(&lt;span style="color:#008000;font-weight:bold;"&gt;"testDefault() argument"&lt;/span&gt;); 1})&lt;br /&gt;    println&lt;br /&gt;    testByName({println(&lt;span style="color:#008000;font-weight:bold;"&gt;"testByName() argument"&lt;/span&gt;); 2})&lt;br /&gt;    println&lt;br /&gt;    testByFunction(() =&amp;gt; {println(&lt;span style="color:#008000;font-weight:bold;"&gt;"testByFunction() argument"&lt;/span&gt;); 3})&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def testDefault(i: Int) {&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"testDefault() body"&lt;/span&gt;)&lt;br /&gt;    var x = i&lt;br /&gt;    var y = i&lt;br /&gt;    println(x + &lt;span style="color:#008000;font-weight:bold;"&gt;" "&lt;/span&gt; + y)&lt;br /&gt;  }&lt;br /&gt;  def testByName(i: =&amp;gt; Int) = {&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"testByName() body"&lt;/span&gt;)&lt;br /&gt;    var x = i&lt;br /&gt;    var y = i&lt;br /&gt;    println(x + &lt;span style="color:#008000;font-weight:bold;"&gt;" "&lt;/span&gt; + y)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def testByFunction(i: () =&amp;gt; Int) = {&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"testByFunction() body"&lt;/span&gt;)&lt;br /&gt;    var x = i&lt;br /&gt;    var y = i&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"x: "&lt;/span&gt; + x)&lt;br /&gt;    println(&lt;span style="color:#008000;font-weight:bold;"&gt;"y(): "&lt;/span&gt; + y())&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;We get the following ouput from example above:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;testDefault() argument&lt;br /&gt;testDefault() body&lt;br /&gt;1 1&lt;br /&gt;&lt;br /&gt;testByName() body&lt;br /&gt;testByName() argument&lt;br /&gt;testByName() argument&lt;br /&gt;2 2&lt;br /&gt;&lt;br /&gt;testByFunction() body&lt;br /&gt;x: &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;function0&lt;/span&gt;&amp;gt;&lt;br /&gt;testByFunction() argument&lt;br /&gt;y(): 3&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;We can see that the difference between &lt;span style="font-style:italic;"&gt;'by-value'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt;/&lt;span style="font-style:italic;"&gt;'by-function'&lt;/span&gt; modes is that method argument is evaluated lazily at last two cases. The difference between &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'by-function'&lt;/span&gt; argument is that &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; argument re-evaluated every time it is used within the method; we need to explicitly put braces in order to evaluate &lt;span style="font-style:italic;"&gt;'by-function'&lt;/span&gt; and it's simple usage just creates an alias to the function.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="error"&gt;Broken compound iterator&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;We got a little theory above, let's see it in action. Scala defines standard &lt;span style="font-style:italic;"&gt;Iterator&lt;/span&gt; trait that is similar to java iterators. It's essense is shown below:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;trait Iterator[+A] { self =&amp;gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#808080;font-style:italic;"&gt;/** Tests whether this iterator can provide another element.&lt;br /&gt;   *  &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@return&lt;/span&gt;  `true` if a subsequent call to `next` will yield an element,&lt;br /&gt;   *           `false` otherwise.&lt;br /&gt;   */&lt;/span&gt;&lt;br /&gt;  def hasNext: Boolean&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#808080;font-style:italic;"&gt;/** Produces the next element of this iterator.&lt;br /&gt;   *  &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@return&lt;/span&gt;  the next element of this iterator, if `hasNext` is `true`,&lt;br /&gt;   *           undefined behavior otherwise.&lt;br /&gt;   */&lt;/span&gt;&lt;br /&gt;  def next(): A&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#808080;font-style:italic;"&gt;// ...&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;br /&gt;&lt;br /&gt;Scala &lt;span style="font-style:italic;"&gt;Iterator&lt;/span&gt; also provides convenient methods like the one that allows to build &lt;span style="font-style:italic;"&gt;Iterator&lt;/span&gt; object from another two iterators. It's signature is defined as follows:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def ++[B &amp;gt;: A](that: =&amp;gt; Iterator[B]): Iterator[B]&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can see that &lt;span style="font-style:italic;"&gt;++&lt;/span&gt; method takes another iterator as &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; argument. Here is a little artificial example that shows the problem that may arise with that:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.scalatest&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Mar 9, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ScalaTest {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; IteratorImpl(val base: Int) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Iterator[Int] {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var empty = false&lt;br /&gt;&lt;br /&gt;    def next() = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (empty) Iterator.empty.next&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; {empty = &lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;; base}&lt;br /&gt;&lt;br /&gt;    def hasNext = !empty&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    val i = create()&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (i.hasNext) print(i.next + &lt;span style="color:#008000;font-weight:bold;"&gt;" "&lt;/span&gt;)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def create() = {&lt;br /&gt;    var base = 1&lt;br /&gt;    var i: Iterator[Int] = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;    base = 2&lt;br /&gt;    i ++= &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;    base = 3&lt;br /&gt;    i ++= &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(base)&lt;br /&gt;    i&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;I was expecting to get &lt;span style="font-style:italic;"&gt;'1 2 3'&lt;/span&gt; as an output but, surprisingly got &lt;span style="font-style:italic;"&gt;'1 3 3'&lt;/span&gt; instead.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="explanation"&gt;Explanation&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;We know that 'by-name' arguments are lazily evaluated. So, &lt;span style="font-style:italic;"&gt;'new IteratorImpl(base)'&lt;/span&gt; expression is evaluated not during &lt;span style="font-style:italic;"&gt;'i ++= new IteratorImpl(base)'&lt;/span&gt; execution but later, during printing iterator elements at &lt;span style="font-style:italic;"&gt;main()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The thing is that our &lt;span style="font-style:italic;"&gt;'by-name'&lt;/span&gt; argument is actually a closure, i.e. it's a block of code that keeps reference to its outer context. That means that the closure &lt;span style="font-style:italic;"&gt;'new IteratorImpl(base)'&lt;/span&gt; doesn't evaluate &lt;span style="font-style:italic;"&gt;'base'&lt;/span&gt; at the moment of creation. Instead, it evaluates it to the current &lt;span style="font-style:italic;"&gt;'base'&lt;/span&gt; value at the moment of evaluation.&lt;br /&gt;&lt;br /&gt;That exactly explains example behavior - &lt;span style="font-style:italic;"&gt;'new IteratorImpl(base)'&lt;/span&gt; refers to the last &lt;span style="font-style:italic;"&gt;'base'&lt;/span&gt; value (3) either for the second or third members of compound iterator.&lt;br /&gt;&lt;br /&gt;We can fix the problem by binding new iterators construction closure to immutable variable:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.scalatest&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Mar 9, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ScalaTest {&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; IteratorImpl(val base: Int) &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Iterator[Int] {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var empty = false&lt;br /&gt;&lt;br /&gt;    def next() = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (empty) Iterator.empty.next&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; {empty = &lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;; base}&lt;br /&gt;&lt;br /&gt;    def hasNext = !empty&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    val i = create()&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (i.hasNext) print(i.next + &lt;span style="color:#008000;font-weight:bold;"&gt;" "&lt;/span&gt;)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def create() = {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(1) ++ &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(2) ++ &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; IteratorImpl(3)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It's clear that we can easily fix this simple example but note that real-world situation may be much more complex and it may be hard to understand what went wrong.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-5852960277450042966?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/5852960277450042966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5852960277450042966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5852960277450042966'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/scala-method-arguments-processing.html' title='Scala method arguments processing - Iterator.++() doesn&apos;t work problem'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-4761969993038582150</id><published>2010-03-16T15:45:00.002+03:00</published><updated>2010-03-16T15:48:10.252+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='society'/><title type='text'>Developers inhabitant is discovered</title><content type='html'>From today Scala mailing list:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;Hi everyone,&lt;br /&gt;&lt;br /&gt;I've noticed a big trend in the Java community (as a whole, not a specific group) that they tend to not be on the Internet in the droves that they used to be a few years ago. It is not uncommon to see Hibernate, Spring, etc. forums virtually dead, and most posts have only a handful of views over 7 days.&lt;br /&gt;&lt;br /&gt;I'm curious - what has happened? Where are the developers? Are they using other technologies? Are they so stable nobody cares but they still use them? Is the industry so slow that there's a small % of us left?&lt;br /&gt;&lt;br /&gt;Would appreciate some credible insight. Thanks!&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;I'd see that as: The products are more mature and there's more and higher quality documentation&lt;br /&gt;&lt;br /&gt;I mean, why spend time waiting for a response if I can google the answer in 10 seconds?&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;Dammit he found us. Where to next guys?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The best!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-4761969993038582150?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/4761969993038582150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/developers-inhabitant-is-discovered.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4761969993038582150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4761969993038582150'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/developers-inhabitant-is-discovered.html' title='Developers inhabitant is discovered'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-6511156925442878210</id><published>2010-03-11T18:40:00.017+03:00</published><updated>2010-03-11T19:55:28.178+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pets'/><title type='text'>Kittens</title><content type='html'>I have a cat of rather interesting breed - &lt;a href="http://en.wikipedia.org/wiki/Kurilian_Bobtail"&gt;Kurilian Bobtail&lt;/a&gt;. There are really many distinctions between she and other cats and she give me a lot of joy but I want to talk about different thing here. My cat gave life to four kittens about month ago and now they look like a real kittens (used to be strange tadpoles at first :) ). Just want to post couple of their photos here.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pregnant mommy:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kUoAnA6jI/AAAAAAAAAHw/hS8TsxVitzQ/s1600-h/lu.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kUoAnA6jI/AAAAAAAAAHw/hS8TsxVitzQ/s320/lu.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447407901872286258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First day:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kWUUB9lgI/AAAAAAAAAH4/Pbp733XlhKg/s1600-h/first-day1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 253px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kWUUB9lgI/AAAAAAAAAH4/Pbp733XlhKg/s320/first-day1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447409762511459842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Second day:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kY24vjBKI/AAAAAAAAAIA/ZQy5m00IBmA/s1600-h/second-day.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 294px; height: 320px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kY24vjBKI/AAAAAAAAAIA/ZQy5m00IBmA/s320/second-day.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447412555505140898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Funny dream:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kZi1nTWZI/AAAAAAAAAII/saCXRRf5pDw/s1600-h/sleeping.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kZi1nTWZI/AAAAAAAAAII/saCXRRf5pDw/s320/sleeping.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447413310579497362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Lair:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S5kaLVkCMvI/AAAAAAAAAIQ/rFCDSmViqa8/s1600-h/lair.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S5kaLVkCMvI/AAAAAAAAAIQ/rFCDSmViqa8/s320/lair.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447414006350492402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sleepy kingdom:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kavAbJk_I/AAAAAAAAAIY/kq3zvWBbUTA/s1600-h/sleepy-kingdom.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kavAbJk_I/AAAAAAAAAIY/kq3zvWBbUTA/s320/sleepy-kingdom.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447414619151373298" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Relax:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kbI3ADowI/AAAAAAAAAIg/qtRVUZWHyGk/s1600-h/relax1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5kbI3ADowI/AAAAAAAAAIg/qtRVUZWHyGk/s320/relax1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447415063298417410" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kbdDDIxAI/AAAAAAAAAIo/es_ENkyj3vU/s1600-h/relax2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kbdDDIxAI/AAAAAAAAAIo/es_ENkyj3vU/s320/relax2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447415410129945602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kbyUTY6xI/AAAAAAAAAIw/l1FxYaaOYps/s1600-h/relax3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kbyUTY6xI/AAAAAAAAAIw/l1FxYaaOYps/s320/relax3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447415775538768658" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kcHN6IO7I/AAAAAAAAAI4/xco7BuMprJI/s1600-h/relax4.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kcHN6IO7I/AAAAAAAAAI4/xco7BuMprJI/s320/relax4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447416134599457714" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Teamwork:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kcfr8PIKI/AAAAAAAAAJA/7p0mVUeVOH4/s1600-h/teamwork.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kcfr8PIKI/AAAAAAAAAJA/7p0mVUeVOH4/s320/teamwork.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447416554978222242" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Black bro:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kdGgruUhI/AAAAAAAAAJI/zYYN4Od0Uqo/s1600-h/black1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kdGgruUhI/AAAAAAAAAJI/zYYN4Od0Uqo/s320/black1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447417221971071506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kdV8QZjoI/AAAAAAAAAJQ/s-BnITv8mYY/s1600-h/black2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kdV8QZjoI/AAAAAAAAAJQ/s-BnITv8mYY/s320/black2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447417487070695042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ginger:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kdxx2ONtI/AAAAAAAAAJY/LhNL-67H_tk/s1600-h/ginger.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kdxx2ONtI/AAAAAAAAAJY/LhNL-67H_tk/s320/ginger.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447417965312882386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Blonde:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S5kfb8PMKxI/AAAAAAAAAJg/0mk_3hjx-kc/s1600-h/blonde.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 251px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S5kfb8PMKxI/AAAAAAAAAJg/0mk_3hjx-kc/s320/blonde.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447419789168093970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Grey:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kgcwM2_9I/AAAAAAAAAJo/a6suibrg-fQ/s1600-h/grey.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 193px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5kgcwM2_9I/AAAAAAAAAJo/a6suibrg-fQ/s320/grey.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447420902628589522" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-6511156925442878210?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/6511156925442878210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/kittens.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/6511156925442878210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/6511156925442878210'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/kittens.html' title='Kittens'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wBtqK4BXFZc/S5kUoAnA6jI/AAAAAAAAAHw/hS8TsxVitzQ/s72-c/lu.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-5997693425352116611</id><published>2010-03-05T20:09:00.008+03:00</published><updated>2010-03-05T21:33:47.492+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><title type='text'>UML class diagrams editor</title><content type='html'>Want to share results of my long search for a cool UML editors to use either under Windows or Linux.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/uml-class-diagrams-editor.html#nclass"&gt;NClass&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/uml-class-diagrams-editor.html#umlet"&gt;UMLet&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/uml-class-diagrams-editor.html#fujaba"&gt;Fujaba&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/03/uml-class-diagrams-editor.html#violet"&gt;Violet&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="nclass"&gt;NClass&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;a href="http://nclass.sourceforge.net/"&gt;NClass&lt;/a&gt; is the best free editor for class diagrams. It's main benefits are simplicity, intuitiveness and eye-pleasing view:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5E8ERB16CI/AAAAAAAAAHI/qdp_i0tb0rg/s1600-h/nclass-test.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 172px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5E8ERB16CI/AAAAAAAAAHI/qdp_i0tb0rg/s320/nclass-test.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5445199468455913506"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It runs under Linux without any problem using &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt;. Moreover, Mono team &lt;a href="http://www.mono-project.com/Winforms_Samples"&gt;uses NClass&lt;/a&gt; as one of examples of porting pure WinForms applications to Linux.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="umlet"&gt;UMLet&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;a href="http://www.umlet.com/"&gt;UMLet&lt;/a&gt; is a simple java-based UML editor that allows to build not only class diagrams but use-case, activity, sequence etc. Screenshots may be found at official site, e.g. this one:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5FIhctVSgI/AAAAAAAAAHQ/ycp6flFY7M0/s1600-h/umlet-test.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 249px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S5FIhctVSgI/AAAAAAAAAHQ/ycp6flFY7M0/s320/umlet-test.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5445213163946854914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="fujaba"&gt;Fujaba&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;a href="http://www.fujaba.de/"&gt;Fujaba&lt;/a&gt; is not pure UML editor but MDA tool. I used it before &lt;span style="font-style:italic;"&gt;NClass&lt;/span&gt; as a class diagram editor because it is wrote in java and provides nice icons for fields and methods (very similar to the one from &lt;span style="font-style:italic;"&gt;NClass&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5FJcPDJLzI/AAAAAAAAAHY/TJORlm0I1yc/s1600-h/fujaba.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 198px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5FJcPDJLzI/AAAAAAAAAHY/TJORlm0I1yc/s320/fujaba.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5445214173892521778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="violet"&gt;Violet&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;a href="http://www.horstmann.com/violet/"&gt;Violet&lt;/a&gt; is created by Cay Horstmann and I have a lot of respect to that man because I started my java developer carrer from his &lt;a href="http://www.amazon.com/Core-Java-TM-I-Fundamentals-8th/dp/0132354764/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1267812914&amp;sr=1-1"&gt;Core Java&lt;/a&gt; book and it was a good start. &lt;span style="font-style:italic;"&gt;Violet&lt;/span&gt; was very promising but unfortunately I realized that I can't go with it. The reason is that it just doesn't allow to do necessary things. E.g. you can't define your own way of transition representation:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5FNGatAc6I/AAAAAAAAAHg/1wI3U5h1os4/s1600-h/violet-test.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S5FNGatAc6I/AAAAAAAAAHg/1wI3U5h1os4/s320/violet-test.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5445218197110289314" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But I should admit that &lt;span style="font-style:italic;"&gt;Violet&lt;/span&gt; provides nice GUI and is really easy to use. It may worth to spend time and contribute to it in order to solve existing problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-5997693425352116611?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/5997693425352116611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/uml-class-diagrams-editor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5997693425352116611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5997693425352116611'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/03/uml-class-diagrams-editor.html' title='UML class diagrams editor'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wBtqK4BXFZc/S5E8ERB16CI/AAAAAAAAAHI/qdp_i0tb0rg/s72-c/nclass-test.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-618179274295071301</id><published>2010-02-20T20:18:00.003+03:00</published><updated>2010-02-20T20:39:17.770+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='society'/><title type='text'>Shopping</title><content type='html'>Today my wife and me went to shop by car. Nothing special, just wanted to get some food and drinks. Half-way between the shop a home we saw a car that stood right on a road. When we came around it we saw a dense smoke coming from it. We stopped, I got a fire extinguisher and ran to the burning car. There were couple of other men there that tried to choke a fire by their extinguishers. Nothing helped - the fire just paused for a couple of seconds and raised even more. We started to throw snow from verge to the car and it made a little effect - there was no open fire but stinky black smoke still continued. Eventually firemen arrived and finished the business.&lt;br /&gt;&lt;br /&gt;Almost all cars that moved around didn't stop. I didn't think about that that time and realized the fact later. I understand that we live in a real world and its hardly possible to change people but ... just want to say that we stopped and tried to help. And couple of another men joined us. And I believe that all of the people that I consider to be my friends would stop.&lt;br /&gt;&lt;br /&gt;I'm sad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-618179274295071301?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/618179274295071301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/02/shopping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/618179274295071301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/618179274295071301'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/02/shopping.html' title='Shopping'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-5832724761857934818</id><published>2010-02-09T21:09:00.020+03:00</published><updated>2010-02-24T23:38:39.952+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='visualvm'/><category scheme='http://www.blogger.com/atom/ns#' term='profiling'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem10</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem10.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem10.html#brute-force-algo"&gt;Brute-force algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem10.html#improved-algo"&gt;Improved algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem10.html#profiling"&gt;Profiling algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.&lt;br /&gt;&lt;br /&gt;Find the sum of all the primes below two million.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="brute-force-algo"&gt;Brute-force algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;The most easiest solution is to use prime numbers generator developed during another tasks processing:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def timedExecute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Iterates elements of given collection and applies given function to them.&lt;br /&gt;     * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;     * Stops if the function returns &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value or all elements are processed&lt;br /&gt;     *&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; collection    collection which content should be checked&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; checker       function that should be applied to collection elements&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@returns&lt;/span&gt;             &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value if given function yields &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value for&lt;br /&gt;     *                      any element of the given collection; &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;None&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; otherwise&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def find[I, O] (collection: Iterable[I])(checker: I =&amp;gt; Option[O]) : Option[O] = {&lt;br /&gt;        var result : Option[O] = None&lt;br /&gt;        collection.dropWhile {&lt;br /&gt;            checker(_) match {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {result = Some(x); false}&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; true&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def gcd(i: Long, j: Long) : Long = {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j &amp;lt;= 0) i&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; gcd(j, i % j)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P10.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p10&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Feb 9, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P10 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    val Limit = 2000000L&lt;br /&gt;&lt;br /&gt;    timedExecute {&lt;br /&gt;        val result = (0L /: getPrimeNumbers.takeWhile(_ &amp;lt; Limit))(_ + _)&lt;br /&gt;        println(result)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It may be seen that the program takes a while to process.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="improved-algo"&gt;Improved algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;We can optimize prime numbers discovery via ancient Eratosthen sieve algorithm - &lt;span style="font-style:italic;"&gt;'ProjectEulerUtil.getPrimes()'&lt;/span&gt; (main algorithm concepts are defined at source code level):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;&lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; collection.{SortedSet, BitSet}&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; collection.immutable.TreeSet&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimes() : Iterator[Long] = {&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#808080;font-style:italic;"&gt;// General idea is to process numbers by blocks of fixed size and find all prime numbers from them.&lt;br /&gt;&lt;/span&gt;        &lt;span style="color:#808080;font-style:italic;"&gt;// This constant defines block size.&lt;br /&gt;&lt;/span&gt;        val BlockSize = 1000&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;         * Allows to retrieve bitset of size defined by &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'BlockSize'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; constant. That bitset is assumed to&lt;br /&gt;         * contain numbers that are not prime. Please note that we use an optimization here - there is no point&lt;br /&gt;         * to process even numbers because all of them except &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'2'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; are guaranteed to be not primes.&lt;br /&gt;         * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;         * Returned bitset is assumed to hold information about odd numbers only then - every target number is&lt;br /&gt;         * calculated by the following formula &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'2 * i + 1'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; where &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'i'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; is a target number&lt;br /&gt;         * contained at bitset.&lt;br /&gt;         * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;         * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;Example:&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; consider that returned bitset contains numbers &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;4, 7, 10&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;. That means that it&lt;br /&gt;         * provides information that numbers &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;9, 15, 21&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; are not prime.&lt;br /&gt;         *&lt;br /&gt;         *&lt;br /&gt;         * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; primes        prime numbers that are already known and that are not greater than given threshold&lt;br /&gt;         * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; threshold     value that defines how many numbers are already processed&lt;br /&gt;         * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@return&lt;/span&gt;              bitset that holds numbers that are known to be non-prime&lt;br /&gt;         */&lt;/span&gt;&lt;br /&gt;        def getPrimesBitSet(primes: SortedSet[Long], threshold: Long) : BitSet = {&lt;br /&gt;            val sieve = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; scala.collection.mutable.BitSet(BlockSize)&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;             * Marks &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'sieve'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; bitset with the given number and all of its odd multiplies.&lt;br /&gt;             * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             * Example: &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'3'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; is given as a &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; - the method stores information&lt;br /&gt;             * about &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;3, 3 * 3, 3 * 5, 3 * 9&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; numbers at the bitset. Please note that bitset is assumed&lt;br /&gt;             * to contain only odd numbers where target number is calculated by formula &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'2 * i + 1'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;br /&gt;             * where &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'i'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; is a number stored at bitset. That explains main concepts of marking algorithm:&lt;br /&gt;             * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;start with the square of the base number&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          We do that in assumption that all numbers that are multiplications of &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          and number lower than &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; are processed during marking that&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'lower'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; number. So, our task is to calculate resulting formula for square of&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; number calculation:&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *              base = 2i + 1&lt;br /&gt;             *              base&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt; = 4i&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt; + 4i + 1 = 2j + 1&lt;br /&gt;             *              2j = 4i * (i + 1)&lt;br /&gt;             *              j = 2i * (i + 1)&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;add all odd multiplies of 'base' number to the bitset&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          Our task is to find &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'k'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; that solves the following equation:&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *              2 * (i + k) + 1 = 3 * (2i + 1)&lt;br /&gt;             *              2k = 6i - 2i + 3 - 2&lt;br /&gt;             *              k = 2i + 1&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          That means that we can found the first number to store at bitset and defines every next odd&lt;br /&gt;             *          multiply to store at bitset by summarizing current multiply with &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; number;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;br /&gt;             * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;br /&gt;             *&lt;br /&gt;             * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; base      number to apply to the &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'sieve'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; bitset&lt;br /&gt;             */&lt;/span&gt;&lt;br /&gt;            def mark(base: Long) {&lt;br /&gt;                val baseIndex = (base - 1) / 2&lt;br /&gt;                val j = (threshold / 2) - baseIndex;&lt;br /&gt;                val firstIndex = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (base &amp;gt; threshold) 2 * baseIndex * (baseIndex + 1)&lt;br /&gt;                                 &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j % base == 0) 0L&lt;br /&gt;                                 &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; base - (j % base)&lt;br /&gt;                getNaturalNumbers(firstIndex, base).takeWhile(_ &amp;lt; BlockSize).foreach(sieve += _.toInt)&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#808080;font-style:italic;"&gt;// Mark known primes.&lt;br /&gt;&lt;/span&gt;            val crosslimit = sqrt(2 * threshold + BlockSize)&lt;br /&gt;            primes.takeWhile(_ &amp;lt;= crosslimit).foreach(mark)&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#808080;font-style:italic;"&gt;// Sieve primes from the new block.&lt;br /&gt;&lt;/span&gt;            val start = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (threshold == 0) 1&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; 0&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; (i &amp;lt;- start until BlockSize; &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (!sieve.contains(i))) {&lt;br /&gt;                mark(threshold + (i * 2) + 1);&lt;br /&gt;                sieve -= i&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            sieve&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        def getPrimesFromBitSet(primes: BitSet, threshold: Long) : Seq[Long] = {&lt;br /&gt;            val start = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (threshold == 0) 1&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; 0&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; (i &amp;lt;- start until BlockSize; &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; !primes.contains(i)) yield threshold + 2 * i + 1&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Iterator[Long]() {            &lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var iterations = 0&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var allPrimes = TreeSet[Long]()&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var i = List(2L).elements&lt;br /&gt;&lt;br /&gt;            def hasNext = true&lt;br /&gt;            def next() = {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (!i.hasNext) iteration()&lt;br /&gt;                i.next&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; def iteration() {&lt;br /&gt;                val threshold = iterations * BlockSize * 2&lt;br /&gt;                val primes = getPrimesFromBitSet(getPrimesBitSet(allPrimes, threshold), threshold)&lt;br /&gt;                allPrimes ++= primes&lt;br /&gt;                iterations += 1&lt;br /&gt;                i = primes.elements&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def timedExecute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Iterates elements of given collection and applies given function to them.&lt;br /&gt;     * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;     * Stops if the function returns &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value or all elements are processed&lt;br /&gt;     *&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; collection    collection which content should be checked&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; checker       function that should be applied to collection elements&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@returns&lt;/span&gt;             &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value if given function yields &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value for&lt;br /&gt;     *                      any element of the given collection; &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;None&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; otherwise&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def find[I, O] (collection: Iterable[I])(checker: I =&amp;gt; Option[O]) : Option[O] = {&lt;br /&gt;        var result : Option[O] = None&lt;br /&gt;        collection.dropWhile {&lt;br /&gt;            checker(_) match {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {result = Some(x); false}&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; true&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def gcd(i: Long, j: Long) : Long = {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j &amp;lt;= 0) i&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; gcd(j, i % j)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="profiling"&gt;Profiling algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;We implemented general idea of prime numbers sieve. Let's check if its implementation can be improved.&lt;br /&gt;&lt;br /&gt;I use &lt;a href="https://visualvm.dev.java.net/"&gt;visualvm&lt;/a&gt; for that. It's not as feature-rich as JProfiler or YourKit profilers but it provides basic functionality and is free. I think experience with such a tool is very useful for every java developer.&lt;br /&gt;&lt;br /&gt;Let's rewrite our start class in order to run forether:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P10.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p10&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Feb 9, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P10 {&lt;br /&gt;&lt;br /&gt;    val Limit = 2000000L&lt;br /&gt;&lt;br /&gt;    def main(args: Array[String]) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (&lt;span style="color:#000080;font-weight:bold;"&gt;true&lt;/span&gt;) {&lt;br /&gt;            timedExecute {&lt;br /&gt;                val result2 = (0L /: getPrimes.takeWhile(_ &amp;lt; Limit))(_ + _)&lt;br /&gt;                println(result2)&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Start profiling session:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S314X9u3qiI/AAAAAAAAAGQ/QrLWVLZUXac/s1600-h/visualvm-cpu-profiling.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S314X9u3qiI/AAAAAAAAAGQ/QrLWVLZUXac/s320/visualvm-cpu-profiling.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439636278036900386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Check profiling results:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S316M7f4orI/AAAAAAAAAGY/HoxsiHnD_HE/s1600-h/visualvm-p10-cpu1.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S316M7f4orI/AAAAAAAAAGY/HoxsiHnD_HE/s320/visualvm-p10-cpu1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439638287481873074" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's rather surprising to see that &lt;span style="font-style:italic;"&gt;'TreeSet.$plus$plus'&lt;/span&gt; takes more time than actual primes filtering.&lt;br /&gt;&lt;br /&gt;We can expand that processing a little:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S318BOSXqJI/AAAAAAAAAGg/_RY4olRtQg4/s1600-h/visualvm-p10-cpu3.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S318BOSXqJI/AAAAAAAAAGg/_RY4olRtQg4/s320/visualvm-p10-cpu3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439640285390284946" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S318s9YX1aI/AAAAAAAAAGo/sw9cS2rES8I/s1600-h/visualvm-p10-cpu4.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S318s9YX1aI/AAAAAAAAAGo/sw9cS2rES8I/s320/visualvm-p10-cpu4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439641036766303650" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;Dozens of recursive &lt;span style="font-style:italic;"&gt;'upd()'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'lookup()'&lt;/span&gt; look very suspicious. I'm definitely going to check standard Scala collections implementation.&lt;br /&gt;&lt;br /&gt;Anyway, profiling shows that there is performance problem with storing parsed prime numbers at Scala's &lt;span style="font-style:italic;"&gt;TreeSet&lt;/span&gt;. I used it in order to process prime numbers from smallest to greatest. However, it's clear that they are already discovered at that order and we can use simple list instead of &lt;span style="font-style:italic;"&gt;TreeSet&lt;/span&gt;. So, we can change &lt;span style="font-style:italic;"&gt;TreeSet&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;ArrayBuffer&lt;/span&gt; at &lt;span style="font-style:italic;"&gt;ProjectEulerUtil&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;def getPrimes() : Iterator[Long] = {&lt;br /&gt;&lt;br /&gt;    def getPrimesBitSet(primes: &lt;span style="font-weight:bold;"&gt;Seq&lt;/span&gt;[Long], threshold: Long) : BitSet = {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Iterator[Long]() {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var allPrimes = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;ArrayBuffer&lt;/span&gt;[Long]()&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;br /&gt;&lt;br /&gt;If we run the program we see that it's executed approximately twice as fast as before. Check the change via profiler:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S4WIUcKxZSI/AAAAAAAAAG4/Fg7w8MARdqw/s1600-h/visualvm-p10-cpu5.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S4WIUcKxZSI/AAAAAAAAAG4/Fg7w8MARdqw/s320/visualvm-p10-cpu5.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5441905609487246626" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Much better but we can see that significant amount of time is still spent to &lt;span style="font-style:italic;"&gt;'ArrayBuffer$plus$plus$eq processing'&lt;/span&gt;. If we expand its processing and check source code we see that the reason is that &lt;span style="font-style:italic;"&gt;++=&lt;/span&gt; method adds all elements of the given collection one-by-one that implies unnecessary processing. We can use ArrayBuffer[Seq[Long]] then:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; collection.{BitSet}&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; collection.mutable.{ArrayBuffer}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimes() : Iterator[Long] = {&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#808080;font-style:italic;"&gt;// General idea is to process numbers by blocks of fixed size and find all prime numbers from them.&lt;br /&gt;&lt;/span&gt;        &lt;span style="color:#808080;font-style:italic;"&gt;// This constant defines block size.&lt;br /&gt;&lt;/span&gt;        val BlockSize = 1000&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;         * Allows to retrieve bitset of size defined by &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'BlockSize'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; constant. That bitset is assumed to&lt;br /&gt;         * contain numbers that are not prime. Please note that we use an optimization here - there is no point&lt;br /&gt;         * to process even numbers because all of them except &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'2'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; are guaranteed to be not primes.&lt;br /&gt;         * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;         * Returned bitset is assumed to hold information about odd numbers only then - every target number is&lt;br /&gt;         * calculated by the following formula &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'2 * i + 1'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; where &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'i'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; is a target number&lt;br /&gt;         * contained at bitset.&lt;br /&gt;         * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;         * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;Example:&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; consider that returned bitset contains numbers &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;4, 7, 10&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;. That means that it&lt;br /&gt;         * provides information that numbers &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;9, 15, 21&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; are not prime.&lt;br /&gt;         *&lt;br /&gt;         *&lt;br /&gt;         * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; primes        prime numbers that are already known and that are not greater than given threshold&lt;br /&gt;         * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; threshold     value that defines how many numbers are already processed&lt;br /&gt;         * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@return&lt;/span&gt;              bitset that holds numbers that are known to be non-prime&lt;br /&gt;         */&lt;/span&gt;&lt;br /&gt;        def getPrimesBitSet(primes: Seq[Seq[Long]], threshold: Long) : BitSet = {&lt;br /&gt;            val sieve = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; scala.collection.mutable.BitSet(BlockSize)&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;             * Marks &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'sieve'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; bitset with the given number and all of its odd multiplies.&lt;br /&gt;             * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             * Example: &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'3'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; is given as a &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; - the method stores information&lt;br /&gt;             * about &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;3, 3 * 3, 3 * 5, 3 * 9&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; numbers at the bitset. Please note that bitset is assumed&lt;br /&gt;             * to contain only odd numbers where target number is calculated by formula &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'2 * i + 1'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;br /&gt;             * where &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'i'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; is a number stored at bitset. That explains main concepts of marking algorithm:&lt;br /&gt;             * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;start with the square of the base number&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          We do that in assumption that all numbers that are multiplications of &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          and number lower than &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; are processed during marking that&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'lower'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; number. So, our task is to calculate resulting formula for square of&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; number calculation:&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *              base = 2i + 1&lt;br /&gt;             *              base&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt; = 4i&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt; + 4i + 1 = 2j + 1&lt;br /&gt;             *              2j = 4i * (i + 1)&lt;br /&gt;             *              j = 2i * (i + 1)&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;add all odd multiplies of 'base' number to the bitset&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          Our task is to find &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'k'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; that solves the following equation:&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *              2 * (i + k) + 1 = 3 * (2i + 1)&lt;br /&gt;             *              2k = 6i - 2i + 3 - 2&lt;br /&gt;             *              k = 2i + 1&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;             *          That means that we can found the first number to store at bitset and defines every next odd&lt;br /&gt;             *          multiply to store at bitset by summarizing current multiply with &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'base'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; number;&lt;br /&gt;             *     &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;br /&gt;             * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;br /&gt;             *&lt;br /&gt;             * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; base      number to apply to the &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;'sieve'&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; bitset&lt;br /&gt;             */&lt;/span&gt;&lt;br /&gt;            def mark(base: Long) {&lt;br /&gt;                val baseIndex = (base - 1) / 2&lt;br /&gt;                val j = (threshold / 2) - baseIndex;&lt;br /&gt;                val firstIndex = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (base &amp;gt; threshold) 2 * baseIndex * (baseIndex + 1)&lt;br /&gt;                                 &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j % base == 0) 0L&lt;br /&gt;                                 &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; base - (j % base)&lt;br /&gt;                getNaturalNumbers(firstIndex, base).takeWhile(_ &amp;lt; BlockSize).foreach(sieve += _.toInt)&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#808080;font-style:italic;"&gt;// Mark known primes.&lt;br /&gt;&lt;/span&gt;            val crosslimit = sqrt(2 * threshold + BlockSize)&lt;br /&gt;            primes.takeWhile {&lt;br /&gt;                var stop = false&lt;br /&gt;                subprimes =&amp;gt; {&lt;br /&gt;                    subprimes.takeWhile(prime =&amp;gt; {mark(prime);stop = prime &amp;gt; crosslimit; !stop})&lt;br /&gt;                    !stop&lt;br /&gt;                }&lt;br /&gt;                !stop&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#808080;font-style:italic;"&gt;// Sieve primes from the new block.&lt;br /&gt;&lt;/span&gt;            val start = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (threshold == 0) 1&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; 0&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; (i &amp;lt;- start until BlockSize; &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (!sieve.contains(i))) {&lt;br /&gt;                mark(threshold + (i * 2) + 1);&lt;br /&gt;                sieve -= i&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            sieve&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        def getPrimesFromBitSet(primes: BitSet, threshold: Long) : Seq[Long] = {&lt;br /&gt;            var i = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (threshold == 0) 1&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; 0&lt;br /&gt;            val result = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; ArrayBuffer[Long]&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (i &amp;lt; BlockSize) {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (!primes.contains(i)) {&lt;br /&gt;                    result += threshold + 2 * i + 1&lt;br /&gt;                }&lt;br /&gt;                i += 1&lt;br /&gt;            }&lt;br /&gt;            result&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;//            val result = for (i &amp;lt;- start until BlockSize; if !primes.contains(i)) yield threshold + 2 * i + 1&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;font-style:italic;"&gt;//            result force&lt;br /&gt;&lt;/span&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Iterator[Long]() {&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var iterations = 0&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var allPrimes = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; ArrayBuffer[Seq[Long]]()&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; var i = List(2L).elements&lt;br /&gt;&lt;br /&gt;            def hasNext = true&lt;br /&gt;            def next() = {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (!i.hasNext) iteration()&lt;br /&gt;                i.next&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;private&lt;/span&gt; def iteration() {&lt;br /&gt;                val threshold = iterations * BlockSize * 2&lt;br /&gt;                val primes = getPrimesFromBitSet(getPrimesBitSet(allPrimes, threshold), threshold)&lt;br /&gt;                allPrimes += primes&lt;br /&gt;                iterations += 1&lt;br /&gt;                i = primes.elements&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def timedExecute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Iterates elements of given collection and applies given function to them.&lt;br /&gt;     * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;     * Stops if the function returns &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value or all elements are processed&lt;br /&gt;     *&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; collection    collection which content should be checked&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; checker       function that should be applied to collection elements&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@returns&lt;/span&gt;             &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value if given function yields &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value for&lt;br /&gt;     *                      any element of the given collection; &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;None&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; otherwise&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def find[I, O] (collection: Iterable[I])(checker: I =&amp;gt; Option[O]) : Option[O] = {&lt;br /&gt;        var result : Option[O] = None&lt;br /&gt;        collection.dropWhile {&lt;br /&gt;            checker(_) match {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {result = Some(x); false}&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; true&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def gcd(i: Long, j: Long) : Long = {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j &amp;lt;= 0) i&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; gcd(j, i % j)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;I got about 20% performance improvement. Profiling confirms that:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S4WMdsoNEvI/AAAAAAAAAHA/bgvwOqIRImc/s1600-h/visualvm-p10-cpu6.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 216px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S4WMdsoNEvI/AAAAAAAAAHA/bgvwOqIRImc/s320/visualvm-p10-cpu6.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5441910166570996466" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We can see that most of the time is spent to internal Scala processing but I think we won't dig deeper this time and improve the implementation even more. I'm going to return to this after Scala internals review.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-5832724761857934818?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/5832724761857934818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5832724761857934818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/5832724761857934818'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem10.html' title='ProjectEuler - problem10'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wBtqK4BXFZc/S314X9u3qiI/AAAAAAAAAGQ/QrLWVLZUXac/s72-c/visualvm-cpu-profiling.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-3623659206647086093</id><published>2010-02-07T10:06:00.013+03:00</published><updated>2010-02-09T19:38:29.292+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem9</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#brute-force-algo"&gt;Brute-force algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#brute-force-impl"&gt;Brute-force solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#formula"&gt;Primitive Pythagorean triples formula&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#revised-algo"&gt;Revised algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#revised-impl"&gt;Revised solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;A Pythagorean triplet is a set of three natural numbers, a &lt; b &lt; c, for which,&lt;br /&gt;a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = c&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;For example, 3&lt;sup&gt;2&lt;/sup&gt; + 4&lt;sup&gt;2&lt;/sup&gt; = 9 + 16 = 25 = 5&lt;sup&gt;2&lt;/sup&gt;.&lt;br /&gt;&lt;br /&gt;There exists exactly one Pythagorean triplet for which a + b + c = 1000.&lt;br /&gt;Find the product abc.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="brute-force-algo"&gt;Brute-force algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Let's perform simple analysis for our data constraints:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a &lt; b &lt; c&lt;br /&gt;a &lt; b &lt; 1000 - a - b&lt;br /&gt;&lt;br /&gt;a &lt; 1000 - a - b&lt;br /&gt;2a &lt; 1000 - b&lt;br /&gt;a &lt; b ==&gt; 2a &lt; 1000 - a&lt;br /&gt;3a &lt; 1000&lt;br /&gt;a &lt; 1000 / 3&lt;br /&gt;&lt;br /&gt;b &lt; 1000 - a - b&lt;br /&gt;2b &lt; 1000 - a&lt;br /&gt;b &lt; (1000 - a) / 2&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;We just constrained our parameters and can iterate all of their available values in order to find such (a; b) pair that conforms to equation below:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = (1000 - a - b)&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="brute-force-impl"&gt;Brute-force solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;We introduce utility method &lt;span style="font-style:italic;"&gt;find()&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.java&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def timedExecute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Iterates elements of given collection and applies given function to them.&lt;br /&gt;     * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;     * Stops if the function returns &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value or all elements are processed&lt;br /&gt;     *&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; collection    collection which content should be checked&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; checker       function that should be applied to collection elements&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@returns&lt;/span&gt;             &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value if given function yields &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value for&lt;br /&gt;     *                      any element of the given collection; &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;None&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; otherwise&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def find[I, O] (collection: Iterable[I])(checker: I =&amp;gt; Option[O]) : Option[O] = {&lt;br /&gt;        var result : Option[O] = None&lt;br /&gt;        collection.dropWhile {&lt;br /&gt;            checker(_) match {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {result = Some(x); false}&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; true&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This class iterates all possible combinations using arguments restrictions produced before:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P9.scala&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p9&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Feb 8, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P9 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    val TripleSum = 1000&lt;br /&gt;&lt;br /&gt;    timedExecute {&lt;br /&gt;        val result = find(1 to TripleSum / 3) {&lt;br /&gt;            i =&amp;gt;&lt;br /&gt;                find((i + 1) to ((TripleSum - i) / 2)) {&lt;br /&gt;                    j =&amp;gt;&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i * i + j * j == (TripleSum - i - j) * (TripleSum - i - j)) Some(j)&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; None&lt;br /&gt;                } match {&lt;br /&gt;                    &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; Some(i, x)&lt;br /&gt;                    &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; None&lt;br /&gt;                }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        result match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; println(x._1 * x._2 * (TripleSum - x._1 - x._2))&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="formula"&gt;Primitive Pythagorean triples formula&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Let's perform more analysis for our problem in order to provide more scalable solution.&lt;br /&gt;&lt;br /&gt;There are ancient formulas for primitive Pythagorean triple calculations (primitive Pythagorean Triple is a (a; b; c) triple where a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = c&lt;sup&gt;2&lt;/sup&gt; and gcd(a, b, c) = 1:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a = m&lt;sup&gt;2&lt;/sup&gt; - n&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;b = 2mn&lt;br /&gt;c = m&lt;sup&gt;2&lt;/sup&gt; + n&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;m &gt; n &gt; 0&lt;br /&gt;only one of m, n is even&lt;br /&gt;gcd(m, n) = 1&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The most interesting here it is to deduce that:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;We can conclude that &lt;span style="font-style:italic;"&gt;gcd(a, b) = gcd(a, c) = gcd(b, c) = 1&lt;/span&gt;. Let's assume that gcd(a, b) = d &gt; 1. We get the following then:&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a = d * x&lt;br /&gt;b = d * y&lt;br /&gt;&lt;br /&gt;a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = (dx)&lt;sup&gt;2&lt;/sup&gt; + (dy)&lt;sup&gt;2&lt;/sup&gt; = d&lt;sup&gt;2&lt;/sup&gt;(x&lt;sup&gt;2&lt;/sup&gt; + y&lt;sup&gt;2&lt;/sup&gt;)&lt;br /&gt;&lt;br /&gt;a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = c&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;==&gt; c&lt;sup&gt;2&lt;/sup&gt; = d&lt;sup&gt;2&lt;/sup&gt;(x&lt;sup&gt;2&lt;/sup&gt; + y&lt;sup&gt;2&lt;/sup&gt;)&lt;br /&gt;==&gt; c is divisible by d that contradicts to our invariant that gcd(a, b, c) = 1&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;We can prove that &lt;span style="font-style:italic;"&gt;gcd(a, c) = 1&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;gcd(b, c) = 1&lt;/span&gt; at the same manner;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Lets observe a, b and c parity.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;suppose a, b and c are all odd. We get the following then:&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;(2x + 1)&lt;sup&gt;2&lt;/sup&gt; + (2y + 1)&lt;sup&gt;2&lt;/sup&gt; = (2z + 1)&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;4x&lt;sup&gt;2&lt;/sup&gt; + 4x + 1 + 4y&lt;sup&gt;2&lt;/sup&gt; + 4y + 1 = 4z&lt;sup&gt;2&lt;/sup&gt; + 4z + 1&lt;br /&gt;4 * (x&lt;sup&gt;2&lt;/sup&gt; + x + y&lt;sup&gt;2&lt;/sup&gt; + y - z&lt;sup&gt;2&lt;/sup&gt; - z + 1) = 3&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;That's not possible because 3 is not divisible by 4;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;let's assume that a and b are odd and c is even:&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;4x&lt;sup&gt;2&lt;/sup&gt; + 4x + 1 + 4y&lt;sup&gt;2&lt;/sup&gt; + 4y + 1 = 4z&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;4 * (x&lt;sup&gt;2&lt;/sup&gt; + x + y&lt;sup&gt;2&lt;/sup&gt; + y - z&lt;sup&gt;2&lt;/sup&gt; + 1) = 2&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;2 is not divisible by 4, hence, such use-case is also illegal;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;we remember that gcd(a, b, c) = 1, so, it's not possible for all a, b and c to be even;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Conclusion: only one of a, b is even and another is odd. Let's say that b is even and a, c are odd;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Let's play around with our equation:&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = c&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;b&lt;sup&gt;2&lt;/sup&gt; = c&lt;sup&gt;2&lt;/sup&gt; - a&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;b&lt;sup&gt;2&lt;/sup&gt; = (c - a)(c + a)&lt;br /&gt;(b / 2)&lt;sup&gt;2&lt;/sup&gt; = (c - a) / 2 * (c + a) / 2&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;We already proved that b is even and a, c are odd, hence, (b / 2), (c - a) / 2 and (c + a) / 2 are all whole numbers. It's clear that they are positive too;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;let's define d = gcd((c - a) / 2, (c + a) / 2). It's implied that d is a divisor for the sum of the mentioned numbers (c) and difference (a). But we know that gcd(a, c) = 1 ==&gt; d = 1;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;That gives us the product of two whole numbers, (c - a) / 2 and (c + a) / 2, whose greatest common divisor is 1, and whose product is a square. The only way that can happen is if each of them is a square itself. This means that there are positive whole numbers m and n such that the below is correct:&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;m&lt;sup&gt;2&lt;/sup&gt; = (c + a) / 2&lt;br /&gt;n&lt;sup&gt;2&lt;/sup&gt; = (c - a) / 2&lt;br /&gt;b / 2 = m * n&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Final observations for m and n defined above:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;m &gt; n&lt;/li&gt;&lt;br /&gt;&lt;li&gt;n &gt; 0 because c &gt; a&lt;/li&gt;&lt;br /&gt;&lt;li&gt;gcd(m&lt;sup&gt;2&lt;/sup&gt;, n&lt;sup&gt;2&lt;/sup&gt;) = 1 ==&gt; gcd(m, n) = 1&lt;/li&gt;&lt;br /&gt;&lt;li&gt;m and n can't be both odd because m&lt;sup&gt;2&lt;/sup&gt; - n&lt;sup&gt;2&lt;/sup&gt; = a would be even and we know that it's odd;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;m and n can't be both even because gcd(m, n) = 1&lt;/li&gt;&lt;br /&gt;&lt;li&gt;conclusion - one of m, n is even and another one is odd;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;We can solve the system above and get target formulas for primitive pythagorean triplets calculation;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Phew...&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="revised-algo"&gt;Revised algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Let's apply primitive Pythagorean triples calculation formulas deduced above to our solution.&lt;br /&gt;&lt;br /&gt;It's clear that we can multiply all members of primitive Pythagorean triple to the same number d and get Pythagorean triple again. I.e. formulas for all Pythagorean triples looks like the one below:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a = d (m&lt;sup&gt;2&lt;/sup&gt; - n&lt;sup&gt;2&lt;/sup&gt;)&lt;br /&gt;b = 2dmn&lt;br /&gt;c = d (m&lt;sup&gt;2&lt;/sup&gt; + n&lt;sup&gt;2&lt;/sup&gt;)&lt;br /&gt;a + b + c = 2m&lt;sup&gt;2&lt;/sup&gt; + 2mn = 2m(m + n) = 1000&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I.e. we can rewrite our constraint for triple members sum as follows:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;a + b + c = d * (2m&lt;sup&gt;2&lt;/sup&gt; + 2mn) = 2dm * (m + n) = 1000&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;That means that we need to find m as a 1000 / 2 divisor that is more than 1 and odd divisor k = m + n of 1000 / 2m. We can see that m &lt; k &lt; 2m and gcd(m, k) = 1.&lt;br /&gt;&lt;br /&gt;So, we can find m and k, calculate n = k - m and d = 1000 / 2mk&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="revised-impl"&gt;Revised solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def timedExecute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Iterates elements of given collection and applies given function to them.&lt;br /&gt;     * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;     * Stops if the function returns &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value or all elements are processed&lt;br /&gt;     *&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; collection    collection which content should be checked&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@param&lt;/span&gt; checker       function that should be applied to collection elements&lt;br /&gt;     * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@returns&lt;/span&gt;             &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value if given function yields &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;Some&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; value for&lt;br /&gt;     *                      any element of the given collection; &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;None&lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt; otherwise&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def find[I, O] (collection: Iterable[I])(checker: I =&amp;gt; Option[O]) : Option[O] = {&lt;br /&gt;        var result : Option[O] = None&lt;br /&gt;        collection.dropWhile {&lt;br /&gt;            checker(_) match {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {result = Some(x); false}&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; true&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def gcd(i: Long, j: Long) : Long = {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j &amp;lt;= 0) i&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; gcd(j, i % j)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P9.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p9&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Feb 8, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P9 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    val TripleSum = 1000&lt;br /&gt;    val TripleSumHalf = TripleSum / 2&lt;br /&gt;    val limit = sqrt(TripleSumHalf)&lt;br /&gt;&lt;br /&gt;    def reduce(i: Int, divisor: Int) : Int = {&lt;br /&gt;        i % divisor match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; 0 =&amp;gt; reduce(i / divisor, divisor)&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; _ =&amp;gt; i&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    timedExecute {&lt;br /&gt;        val result = find(2 to limit) {&lt;br /&gt;            i =&amp;gt;&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (TripleSumHalf % i == 0) {&lt;br /&gt;                    val k = &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i % 2 == 0) i + 1&lt;br /&gt;                            &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; i + 2&lt;br /&gt;&lt;br /&gt;                    val reduced = reduce(TripleSumHalf / i, 2)&lt;br /&gt;                    find(k to min(2 * i, reduced)) {&lt;br /&gt;                        j =&amp;gt;&lt;br /&gt;                            &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (reduced % j == 0 &amp;&amp; gcd(i, j) == 1) Some(j)&lt;br /&gt;                            &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; None&lt;br /&gt;                    } match {&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; Some(i, x)&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; None&lt;br /&gt;                    }&lt;br /&gt;                } &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; None&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        result match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {&lt;br /&gt;                val m = x._1&lt;br /&gt;                val k = x._2&lt;br /&gt;                val d = TripleSumHalf / m / k&lt;br /&gt;                val n = k - m&lt;br /&gt;                val a = d * (m * m - n * n)&lt;br /&gt;                val b = 2 * d * m * n&lt;br /&gt;                val c = d * (m * m + n * n)&lt;br /&gt;                println(a * b * c)&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-3623659206647086093?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/3623659206647086093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3623659206647086093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3623659206647086093'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/02/projecteuler-problem9.html' title='ProjectEuler - problem9'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-1472868341975967064</id><published>2010-01-31T12:40:00.004+03:00</published><updated>2010-01-31T13:24:51.627+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem8</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem8.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem8.html#algorithm"&gt;Algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem8.html#solution"&gt;Problem solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;Find the greatest product of five consecutive digits in the 1000-digit number.&lt;br /&gt;&lt;br /&gt;73167176531330624919225119674426574742355349194934&lt;br /&gt;96983520312774506326239578318016984801869478851843&lt;br /&gt;85861560789112949495459501737958331952853208805511&lt;br /&gt;12540698747158523863050715693290963295227443043557&lt;br /&gt;66896648950445244523161731856403098711121722383113&lt;br /&gt;62229893423380308135336276614282806444486645238749&lt;br /&gt;30358907296290491560440772390713810515859307960866&lt;br /&gt;70172427121883998797908792274921901699720888093776&lt;br /&gt;65727333001053367881220235421809751254540594752243&lt;br /&gt;52584907711670556013604839586446706324415722155397&lt;br /&gt;53697817977846174064955149290862569321978468622482&lt;br /&gt;83972241375657056057490261407972968652414535100474&lt;br /&gt;82166370484403199890008895243450658541227588666881&lt;br /&gt;16427171479924442928230863465674813919123162824586&lt;br /&gt;17866458359124566529476545682848912883142607690042&lt;br /&gt;24219022671055626321111109370544217506941658960408&lt;br /&gt;07198403850962455444362981230987879927244284909188&lt;br /&gt;84580156166097919133875499200524063689912560717606&lt;br /&gt;05886116467109405077541002256983155200055935729725&lt;br /&gt;71636269561882670428252483600823257530420752963450&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="algorithm"&gt;Algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;This is rather simple problem that doesn't require any mathematical studies. I.e. all we need is to iterate all combinations of number products and choose the max of them.&lt;br /&gt;&lt;br /&gt;There are four main product types - five numbers in a row, five numbers in column, five numbers on right diagonal, five numbers on left diagonal.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="solution"&gt;Problem solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P8.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p8&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; 31.01.2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;object P8 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    val ProductSize = 5&lt;br /&gt;    val NumbersInRow = 50&lt;br /&gt;    val NumbersInColumn = 20&lt;br /&gt;    val input = &lt;span style="color:#008000;font-weight:bold;"&gt;""&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"|73167176531330624919225119674426574742355349194934&lt;br /&gt;                   |96983520312774506326239578318016984801869478851843&lt;br /&gt;                   |85861560789112949495459501737958331952853208805511&lt;br /&gt;                   |12540698747158523863050715693290963295227443043557&lt;br /&gt;                   |66896648950445244523161731856403098711121722383113&lt;br /&gt;                   |62229893423380308135336276614282806444486645238749&lt;br /&gt;                   |30358907296290491560440772390713810515859307960866&lt;br /&gt;                   |70172427121883998797908792274921901699720888093776&lt;br /&gt;                   |65727333001053367881220235421809751254540594752243&lt;br /&gt;                   |52584907711670556013604839586446706324415722155397&lt;br /&gt;                   |53697817977846174064955149290862569321978468622482&lt;br /&gt;                   |83972241375657056057490261407972968652414535100474&lt;br /&gt;                   |82166370484403199890008895243450658541227588666881&lt;br /&gt;                   |16427171479924442928230863465674813919123162824586&lt;br /&gt;                   |17866458359124566529476545682848912883142607690042&lt;br /&gt;                   |24219022671055626321111109370544217506941658960408&lt;br /&gt;                   |07198403850962455444362981230987879927244284909188&lt;br /&gt;                   |84580156166097919133875499200524063689912560717606&lt;br /&gt;                   |05886116467109405077541002256983155200055935729725&lt;br /&gt;                   |71636269561882670428252483600823257530420752963450"&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;""&lt;/span&gt;.stripMargin&lt;br /&gt;&lt;br /&gt;    val data = (&lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Array[Int](0) /: input.lines)(_ ++ _.map(_.asDigit))&lt;br /&gt;&lt;br /&gt;    def build(startIndex: Int, nextElementIndexStep: (Int) =&amp;gt; Option[Int]): Option[Int] = {&lt;br /&gt;        def build(index: Int, current: Option[Int], iterationsLeft: Int): Option[Int] = {&lt;br /&gt;            current match {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(value) =&amp;gt; {&lt;br /&gt;                    &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (iterationsLeft &amp;lt;= 0) {&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; current&lt;br /&gt;                    }&lt;br /&gt;                    nextElementIndexStep(index) match {&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(nextIndex) =&amp;gt; build(nextIndex, Some(value * data(nextIndex)), iterationsLeft - 1)&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; None&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt; current&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        build(startIndex, Some(data(startIndex)), ProductSize - 1)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val horizontal = (i: Int) =&amp;gt; {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i % NumbersInRow &amp;gt;= NumbersInRow - 1) None&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; Some(i + 1)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val vertical = (i: Int) =&amp;gt; {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i / NumbersInRow &amp;gt;= NumbersInColumn - 1) None&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; Some(i + NumbersInRow)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val rightHorizontal = (i: Int) =&amp;gt; {&lt;br /&gt;        (horizontal(i), vertical(i)) match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; (Some(x), Some(y)) =&amp;gt; Some(y + 1)&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; _ =&amp;gt; None&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val leftHorizontal = (i: Int) =&amp;gt; {&lt;br /&gt;        vertical(i) match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; {&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i % NumbersInRow &amp;gt; 0) Some(x - 1)&lt;br /&gt;                &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; None&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; _ =&amp;gt; None&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    var result = 0&lt;br /&gt;    val formulas = List(horizontal, vertical, rightHorizontal, leftHorizontal)&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; (&lt;br /&gt;        i &amp;lt;- 0 until data.length;&lt;br /&gt;        formula &amp;lt;- formulas&lt;br /&gt;    ) {&lt;br /&gt;        build(i, formula) match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(x) =&amp;gt; result = result max x&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; None =&amp;gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    println(result)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;Here are the main principles that are used at the implementation:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;convert input string to the numbers array;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define utility function that calculates product based on its first number index at the data array - &lt;span style="font-style:italic;"&gt;'build()'&lt;/span&gt; method;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define four rules for product elements index definitions - &lt;span style="font-style:italic;"&gt;'horizontal()'&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;'vertical()'&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;'rightHorizontal()'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'leftHorizontal()'&lt;/span&gt; functions;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;calculate all possible products for all array indices and find the greatest;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;It's possible to improve the algorithm at following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;stop product calculation as soon as zero is detected as a one of its elements (since resulting product is zero);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;optimize processing in order to use subsequent product calculation results, e.g. we can iterate row by row for 'horizontal' rule calculation and use the following algorithm:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Calculate first five row numbers product;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Divide product from the previous step to the first element and multiply result to the 6-th element;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Divide product from the previous step to the second number and multiply it to the 7-th element;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Etc;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-1472868341975967064?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/1472868341975967064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem8.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/1472868341975967064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/1472868341975967064'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem8.html' title='ProjectEuler - problem8'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-3236470708263002973</id><published>2010-01-26T18:28:00.003+03:00</published><updated>2010-01-26T18:34:15.345+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem7</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem7.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem7.html#solution"&gt;Problem solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6&lt;sup&gt;th&lt;/sup&gt; prime is 13.&lt;br /&gt;&lt;br /&gt;What is the 10001&lt;sup&gt;st&lt;/sup&gt; prime number?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="solution"&gt;Problem solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;It's really easy to solve the task using sieve-based prime numbers generator &lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#prime-generator"&gt;introduced during problem5 processing&lt;/a&gt;. Here is the solution:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P7.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p7&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 25, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P7 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    timedExecute {&lt;br /&gt;        println(getPrimeNumbers.take(10001).last)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; collection.mutable.ListBuffer&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def timedExecute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-3236470708263002973?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/3236470708263002973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3236470708263002973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/3236470708263002973'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem7.html' title='ProjectEuler - problem7'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2670604140223507700</id><published>2010-01-24T12:59:00.008+03:00</published><updated>2010-01-25T01:30:14.521+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem4</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem4.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem4.html#algorithm"&gt;Algorithm&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem4.html#implementation"&gt;Implementation&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem4.html#internal"&gt;Under the covers&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.&lt;br /&gt;&lt;br /&gt;Find the largest palindrome made from the product of two 3-digit numbers.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="algorithm"&gt;Algorithm&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I used the following algorithm for solving the problem:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;implement sub-routine that allows to answer if given number is palindrome;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;iterate all candidate products of three-digits numbers, filter all palindroms from them and find the greatest;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;We define a loop to iterate all candidate three-digits numbers and an inner loop to iterate all interested three-digits numbers in order to process their product. We can apply couple of optimizations here:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;iterate numbers in descending order - it's clear that the larger numbers produce larger products;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;use current outer loop value as a starting point for the inner loop in order to avoid duplicate processing like &lt;span style="font-style:italic;"&gt;'123 * 456'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'456 * 123'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;stop inner loop processing as soon as product value is less than or equal to the max product value known at the moment - there is no point in continuing since the product values decrease during inner loop processing;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;stop outer loop processing as soon as current value is less that or equal to the square root of the currently known max product value - that is implied from the two previous points because max inner loop iterable value is equal to the current outer loop variable value and the products of inner and outer loop variables are decreased during inner loop processing;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;We can provide one more optimization here - suppose our resulting palindrome (&lt;span style="font-style:italic;"&gt;P&lt;/span&gt;) is written as &lt;span style="font-style:italic;"&gt;'abccba'&lt;/span&gt; number. We can observe the following then:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;P = 100000 * a + 10000 * b + 1000 * c + 100* c + 10 * b + a&lt;br /&gt;P = 100001 * a + 10010 * b + 1100 * c&lt;br /&gt;P = 11* (9091 * a  910 * b  100 * c&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;That means that resulting palindrome is divisible by 11, hence, at least one of the target three-digits numbers is divisible by 11. That produces the following optimization:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;we use step &lt;span style="font-style:italic;"&gt;'11'&lt;/span&gt; at inner loop if current outer loop variable is not divisible by &lt;span style="font-style:italic;"&gt;11&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="implementation"&gt;Implementation&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Here is a Scala implementation of the algorithm mentioned above. Note that we use varios palindrome checks and either optimized or non-optimized algorithms here:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P4.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p4&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil.getNaturalNumbers&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math.sqrt&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 20, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P4 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    def isPalindrome1(i: Long) = {&lt;br /&gt;        i.toString == i.toString.reverse.mkString&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def isPalindrome2(i: Long) = {&lt;br /&gt;        var buffer = i&lt;br /&gt;        var reversed = 0L&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (buffer &amp;gt; 0) {&lt;br /&gt;            reversed = (reversed * 10) + (buffer % 10)&lt;br /&gt;            buffer /= 10&lt;br /&gt;        }&lt;br /&gt;        i == reversed&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def isPalindrome3(i: Long) = {&lt;br /&gt;        lazy val reversedDigits: Stream[(Long, Long)] =&lt;br /&gt;            Stream.cons((i % 10, i / 10), reversedDigits.map(t =&amp;gt; (t._2 % 10, t._2 / 10)))&lt;br /&gt;&lt;br /&gt;        i == (reversedDigits.takeWhile(t =&amp;gt; t._1 &amp;gt; 0 || t._2 &amp;gt; 0) :\ (0L, 1L)) {&lt;br /&gt;            (t, p) =&amp;gt; (t._1 * p._2 + p._1, p._2 * 10)&lt;br /&gt;        }._1&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def isPalindrome4(i: Long) = {&lt;br /&gt;        def reverse(j: Long, result: Long) : Long = {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j &amp;lt;= 0) result&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; reverse(j / 10, result * 10 + j % 10)&lt;br /&gt;        }&lt;br /&gt;        i == reverse(i, 0)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val resultSet = scala.collection.mutable.Set.empty[Long]&lt;br /&gt;&lt;br /&gt;    def solve(isPalindrome: Long =&amp;gt; Boolean, innerSeqGenerator: (Long) =&amp;gt; Range) = {&lt;br /&gt;        var result = 0L&lt;br /&gt;        var bound = 0.0&lt;br /&gt;&lt;br /&gt;        def continueIteration(i: Long): Boolean = {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i &amp;lt;= bound) false&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; {&lt;br /&gt;                innerSeqGenerator(i).map(i * _).dropWhile {&lt;br /&gt;                    j =&amp;gt; j &amp;gt; result &amp;&amp; !isPalindrome(j)&lt;br /&gt;                }.firstOption match {&lt;br /&gt;                    &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; Some(candidate) =&amp;gt;&lt;br /&gt;                        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (isPalindrome(candidate) &amp;&amp; candidate &amp;gt; result) {&lt;br /&gt;                            result = candidate&lt;br /&gt;                            bound = sqrt(result)&lt;br /&gt;                        }&lt;br /&gt;                    &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; _ =&amp;gt;&lt;br /&gt;                }&lt;br /&gt;                true&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Range.Inclusive(999, 100, -1).takeWhile(continueIteration( _)).last&lt;br /&gt;        resultSet += result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def usualInnerRangeGenerator(i: Long) = {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Range.Inclusive(i.toInt, 100, -1)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def optimizedInnerRangeGenerator(i: Long) = {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i % 11 == 0) &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Range.Inclusive(i.toInt, 100, -1)&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Range.Inclusive(getNaturalNumbers(i - 1, -1).dropWhile(_ % 11 != 0).head.toInt, 100, -11)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; ((algoName, seqGenerator) &amp;lt;- List(&lt;br /&gt;        (&lt;span style="color:#008000;font-weight:bold;"&gt;"usual"&lt;/span&gt;, usualInnerRangeGenerator _), (&lt;span style="color:#008000;font-weight:bold;"&gt;"optimized"&lt;/span&gt;, optimizedInnerRangeGenerator _))&lt;br /&gt;    ) {&lt;br /&gt;        println(algoName + &lt;span style="color:#008000;font-weight:bold;"&gt;" algorithm:"&lt;/span&gt;)&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; ((checkName, check) &amp;lt;- List(&lt;br /&gt;            (&lt;span style="color:#008000;font-weight:bold;"&gt;"string-based"&lt;/span&gt;, isPalindrome1 _), (&lt;span style="color:#008000;font-weight:bold;"&gt;"imperative"&lt;/span&gt;, isPalindrome2 _),&lt;br /&gt;            (&lt;span style="color:#008000;font-weight:bold;"&gt;"fold-tuple"&lt;/span&gt;, isPalindrome3 _), (&lt;span style="color:#008000;font-weight:bold;"&gt;"recursive"&lt;/span&gt;, isPalindrome4 _))&lt;br /&gt;        ) {&lt;br /&gt;            print(&lt;span style="color:#008000;font-weight:bold;"&gt;"\t"&lt;/span&gt; + checkName + &lt;span style="color:#008000;font-weight:bold;"&gt;" check: avg time = "&lt;/span&gt;)&lt;br /&gt;            val start = System.nanoTime&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; (i &amp;lt;- 0 to 100) {&lt;br /&gt;                solve(check, seqGenerator)&lt;br /&gt;            }&lt;br /&gt;            println((System.nanoTime - start) / 1000000000d / 100 + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds"&lt;/span&gt;)            &lt;br /&gt;        }&lt;br /&gt;        println&lt;br /&gt;    }&lt;br /&gt;    println (&lt;span style="color:#008000;font-weight:bold;"&gt;"result: "&lt;/span&gt; + resultSet)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; collection.mutable.ListBuffer&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def execute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="internal"&gt;Under the covers&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I want to talk here about various implementations of &lt;span style="font-style:italic;"&gt;'isPalindrome'&lt;/span&gt; checks. Let's briefly enumerate them:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;isPalindrome1&lt;/span&gt; - uses standard API for converting given number to string, reversing its characters and checking reversed version against initial;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;isPalindrome2&lt;/span&gt; - performs examination without unnecessary string/character processing. Written in imperative way;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;isPalindrome3&lt;/span&gt; - uses scala Stream folding in order to achieve the desired result. It was some kind of challenge for me to write it, so, don't consider it to be a real-life approach. It's the worst implementation because the code is hard to understand and a lot of objects are created during processing;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;isPalindrome4&lt;/span&gt; - classic functional style-based recursive implementation;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;If we run the example we see that imperative check performs approximately the same as recursive check. It's interesting to understand the reason of that. We can check generated java byte code for those methods:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;imperative check&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt; 0 lload_1&lt;br /&gt; 1 lstore_3&lt;br /&gt; 2 lconst_0&lt;br /&gt; 3 lstore 5&lt;br /&gt; 5 lload_3&lt;br /&gt; 6 lconst_0&lt;br /&gt; 7 lcmp&lt;br /&gt; 8 ifle 34 (+26)&lt;br /&gt;11 lload 5&lt;br /&gt;13 ldc2_w #109 &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;10&lt;/span&gt;&amp;gt;&lt;br /&gt;16 lmul&lt;br /&gt;17 lload_3&lt;br /&gt;18 ldc2_w #109 &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;10&lt;/span&gt;&amp;gt;&lt;br /&gt;21 lrem&lt;br /&gt;22 ladd&lt;br /&gt;23 lstore 5&lt;br /&gt;25 lload_3&lt;br /&gt;26 ldc2_w #109 &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;10&lt;/span&gt;&amp;gt;&lt;br /&gt;29 ldiv&lt;br /&gt;30 lstore_3&lt;br /&gt;31 goto 5 (-26)&lt;br /&gt;34 lload_1&lt;br /&gt;35 lload 5&lt;br /&gt;37 lcmp&lt;br /&gt;38 ifne 45 (+7)&lt;br /&gt;41 iconst_1&lt;br /&gt;42 goto 46 (+4)&lt;br /&gt;45 iconst_0&lt;br /&gt;46 ireturn&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;&lt;span style="font-style:italic;"&gt;recursive check (reverse() function):&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt; 0 lload_1&lt;br /&gt; 1 lconst_0&lt;br /&gt; 2 lcmp&lt;br /&gt; 3 ifgt 8 (+5)&lt;br /&gt; 6 lload_3&lt;br /&gt; 7 lreturn&lt;br /&gt; 8 lload_1&lt;br /&gt; 9 ldc2_w #109 &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;10&lt;/span&gt;&amp;gt;&lt;br /&gt;12 ldiv&lt;br /&gt;13 lload_3&lt;br /&gt;14 ldc2_w #109 &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;10&lt;/span&gt;&amp;gt;&lt;br /&gt;17 lmul&lt;br /&gt;18 lload_1&lt;br /&gt;19 ldc2_w #109 &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;10&lt;/span&gt;&amp;gt;&lt;br /&gt;22 lrem&lt;br /&gt;23 ladd&lt;br /&gt;24 lstore_3&lt;br /&gt;25 lstore_1&lt;br /&gt;26 goto 0 (-26)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can see that scala compiler transformed tail-recursive &lt;span style="font-style:italic;"&gt;'reverse()'&lt;/span&gt; into a loop, i.e. its byte code instructions are almost the same as the one generated for imperative approach. That shows that writing the code in functional style doesn't imply that it performs worse than the one written in imperative style. That's cool!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2670604140223507700?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2670604140223507700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem4.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2670604140223507700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2670604140223507700'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem4.html' title='ProjectEuler - problem4'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-6884880651483198831</id><published>2010-01-19T22:45:00.004+03:00</published><updated>2010-01-19T23:07:30.508+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem3</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem3.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem3.html#generator"&gt;Optimized prime numbers generator&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem3.html#solution"&gt;Solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;The prime factors of 13195 are 5, 7, 13 and 29.&lt;br /&gt;&lt;br /&gt;What is the largest prime factor of the number 600851475143 ?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="generator"&gt;Optimized prime numbers generator&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I optimized a little prime numbers generator &lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#prime-generator"&gt;introduced during problem5 solving&lt;/a&gt;. The general idea is that there is an only even prime number - '2', hence, we need to check only odd numbers if they are prime.&lt;br /&gt;&lt;br /&gt;Here is the optimized approach:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long, step: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + step))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3, 2) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def execute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You can see that we increment all prime number candidates by two starting from '3' now.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="solution"&gt;Solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;We follow the same idea that was used during &lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html"&gt;problem5 solving&lt;/a&gt; - any number may be represented as a multiplication of different numbers of prime factors. That means that if particular number N is divisible by two prime numbers P&lt;sub&gt;1&lt;/sub&gt; and P&lt;sub&gt;2&lt;/sub&gt; and P&lt;sub&gt;1&lt;/sub&gt; is less than &lt;span style="font-style:italic;"&gt;sqrt(N)&lt;/span&gt; then P&lt;sub&gt;2&lt;/sub&gt; is greater than &lt;span style="font-style:italic;"&gt;sqrt(N)&lt;/span&gt;. Implication: if particular number N is not divisible by prime numbers less than &lt;span style="font-style:italic;"&gt;srqt(N)&lt;/span&gt; than 'N' is prime.&lt;br /&gt;&lt;br /&gt;We use the idea above for solving the problem. Solution is to iterate prime numbers and reducing target number by dividing it by all of them that produce no reminder. That process is stopped as soon as we reach sqrt of the current reminder:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P3.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p3&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 19, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P3 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    var target = 600851475143L&lt;br /&gt;    var bound = sqrt(target)&lt;br /&gt;&lt;br /&gt;    def updateTarget(prime: Long) {&lt;br /&gt;        target /= prime&lt;br /&gt;        bound = sqrt(target)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def process(prime: Long) : Boolean = {&lt;br /&gt;        target % prime match {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; 0 =&amp;gt; {updateTarget(prime); process(prime)}&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;case&lt;/span&gt; _ =&amp;gt; prime &amp;lt;= bound&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    getPrimeNumbers.takeWhile(process _).last &lt;span style="color:#808080;font-style:italic;"&gt;// necessary to call because Stream elements are calculated lazily&lt;br /&gt;&lt;/span&gt;    println(target)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-6884880651483198831?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/6884880651483198831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/6884880651483198831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/6884880651483198831'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem3.html' title='ProjectEuler - problem3'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-167734133524816620</id><published>2010-01-17T14:37:00.025+03:00</published><updated>2010-01-17T15:36:30.999+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mtgo'/><title type='text'>MTGO Zendicar block - Vampires deck</title><content type='html'>I like to play &lt;a href="http://en.wikipedia.org/wiki/Magic:the_gathering"&gt;Magic: The Gathering (MTG)&lt;/a&gt; from time to time. It's nice to play it with friends using paper cards and possible to play with digital cards online - &lt;a href="http://www.wizards.com/Magic/Digital/MagicOnline.aspx"&gt;Magic: The Gathering Online (MTGO)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There was a big gap since I played MTGO last time, so, I created a new deck to use within the &lt;a href="http://wizards.custhelp.com/cgi-bin/wizards.cfg/php/enduser/std_adp.php?p_faqid=1969"&gt;ZEN Block&lt;/a&gt; format tournaments. Today was a first victory with it.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The basic idea is to use a vampire creatures and spells because there are some cool abilities and spells related to them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Creature&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1L5rSW0k3I/AAAAAAAAAEY/1eb3FXrxOuc/s1600-h/bloodghast.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1L5rSW0k3I/AAAAAAAAAEY/1eb3FXrxOuc/s320/bloodghast.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427675022992118642" /&gt;&lt;/a&gt; - it's really cool because of ability to return to the battlefield from the graveyard every time you play a new land;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L6OSr_h2I/AAAAAAAAAEg/dEQT0OHgchY/s1600-h/gatekeeper-of-malakir.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L6OSr_h2I/AAAAAAAAAEg/dEQT0OHgchY/s320/gatekeeper-of-malakir.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427675624376338274" /&gt;&lt;/a&gt; - forces opponent to sacrifice a creature, hence, may be used to destroy creatures with shroud and activate abilities triggered on moving creature to graveyard from the battlefield;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S1L8LIxqVqI/AAAAAAAAAEo/E5dk1qaYsPo/s1600-h/malakir-bloodwitch.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S1L8LIxqVqI/AAAAAAAAAEo/E5dk1qaYsPo/s320/malakir-bloodwitch.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427677769199408802" /&gt;&lt;/a&gt; - flying, protection from white and nice ability to drain life from foe (that's one of the features of vampires-based deck I was talking before - more vampires you have more life is drained);&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L9Fspmy8I/AAAAAAAAAEw/_Wjn66adjW4/s1600-h/vampire-hexmage.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L9Fspmy8I/AAAAAAAAAEw/_Wjn66adjW4/s320/vampire-hexmage.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427678775261711298" /&gt;&lt;/a&gt; - cheap price, first strike and ability to remove all counters from the target creature. Note that the last may be used to destroy planeswalkers. Very mighty!&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L9lf1_RVI/AAAAAAAAAE4/OyFJuCz3830/s1600-h/vampire-nighthawk.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L9lf1_RVI/AAAAAAAAAE4/OyFJuCz3830/s320/vampire-nighthawk.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427679321579799890" /&gt;&lt;/a&gt; - really, really cool guy. Flying, deathtouch, lifelink and life equal to three (means that it can resist popular black spells that hit target creature to 2 damage);&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L-a4LxUSI/AAAAAAAAAFA/xXj7Ja7C0g4/s1600-h/blood-seeker.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L-a4LxUSI/AAAAAAAAAFA/xXj7Ja7C0g4/s320/blood-seeker.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427680238646677794" /&gt;&lt;/a&gt; - it's only features are that it's a vampire, cheap price and ability to hit opponent every time he or she enters new creature to the game. However, that's not so impressing. I'm going to drop that card from the deck;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Spells&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L--DooccI/AAAAAAAAAFI/by9tm7HhZyk/s1600-h/feast-of-blood.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1L--DooccI/AAAAAAAAAFI/by9tm7HhZyk/s320/feast-of-blood.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427680843015942594" /&gt;&lt;/a&gt; - very strong spell because it's cheap, can be applied against black creatures and you get a life from it appliance;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S1L_aAb74gI/AAAAAAAAAFQ/1kEKpGMY4sg/s1600-h/vampires-bite.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S1L_aAb74gI/AAAAAAAAAFQ/1kEKpGMY4sg/s320/vampires-bite.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427681323193721346" /&gt;&lt;/a&gt; - instant creature enhancer with convenient ability to grant life link for additional mana;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1MAGwnRmCI/AAAAAAAAAFY/QPpCd87ymj0/s1600-h/disfigure.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1MAGwnRmCI/AAAAAAAAAFY/QPpCd87ymj0/s320/disfigure.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427682092040427554" /&gt;&lt;/a&gt; - nice to use to kill enemy creatures;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S1MAawgvKgI/AAAAAAAAAFg/7WCl-RFhEb0/s1600-h/bloodchief-ascension.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S1MAawgvKgI/AAAAAAAAAFg/7WCl-RFhEb0/s320/bloodchief-ascension.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427682435610388994" /&gt;&lt;/a&gt; - very strong enhancement that may hit opponent a lot;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S1MAyOK20YI/AAAAAAAAAFo/Fjb2jRJqucA/s1600-h/needlebute-trap.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S1MAyOK20YI/AAAAAAAAAFo/Fjb2jRJqucA/s320/needlebute-trap.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427682838708670850" /&gt;&lt;/a&gt; - haven't had a chance to use it at a tournament game but believe that it's very powerful. I put it to the sideboard at the moment in order to include to the main deck if I see that the foe uses a cards that brings him or her life;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1MBU0aQhiI/AAAAAAAAAFw/oGAou99RDYQ/s1600-h/mind-sludge.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S1MBU0aQhiI/AAAAAAAAAFw/oGAou99RDYQ/s320/mind-sludge.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427683433089369634" /&gt;&lt;/a&gt; - this spell lives at sideboard at the moment. I'm planning to use it against blue control decks;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Support&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wBtqK4BXFZc/S1MB7K8lnhI/AAAAAAAAAF4/IEEzGeM8MNE/s1600-h/blade-of-the-bloodchief.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://3.bp.blogspot.com/_wBtqK4BXFZc/S1MB7K8lnhI/AAAAAAAAAF4/IEEzGeM8MNE/s320/blade-of-the-bloodchief.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427684091973967378" /&gt;&lt;/a&gt; - it's very nice to have your vampires characteristics improved a lot. I have couple of such blades at the deck;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1MCRQ87IaI/AAAAAAAAAGA/RbN6RjhKsyA/s1600-h/soul-stair-expedition.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1MCRQ87IaI/AAAAAAAAAGA/RbN6RjhKsyA/s320/soul-stair-expedition.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427684471543112098" /&gt;&lt;/a&gt; - it's nice to return your vampires from the graveyard;&lt;br /&gt;&lt;br /&gt;&lt;div style="clear:left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1MCmt9qQyI/AAAAAAAAAGI/p_ttWfu0aC4/s1600-h/sorin-markov.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 224px; height: 320px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S1MCmt9qQyI/AAAAAAAAAGI/p_ttWfu0aC4/s320/sorin-markov.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5427684840108081954" /&gt;&lt;/a&gt; - haven't had a chance to try his abilities over than &lt;span style="font-style:italic;"&gt;'two damage to target creature or player...'&lt;/span&gt; but believe that another skills are also cool;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-167734133524816620?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/167734133524816620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/mtgo-zendicar-block-vampires-deck.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/167734133524816620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/167734133524816620'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/mtgo-zendicar-block-vampires-deck.html' title='MTGO Zendicar block - Vampires deck'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wBtqK4BXFZc/S1L5rSW0k3I/AAAAAAAAAEY/1eb3FXrxOuc/s72-c/bloodghast.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-778309713770285215</id><published>2010-01-15T14:39:00.010+03:00</published><updated>2010-01-15T19:05:46.486+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='idea'/><category scheme='http://www.blogger.com/atom/ns#' term='jni'/><title type='text'>Jni dll and IDE</title><content type='html'>I got a wierd problem today - my java application uses native &lt;span style="font-style:italic;"&gt;'*.dll'&lt;/span&gt; and it failed to load it with the reason &lt;span style="font-style:italic;"&gt;'Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\projects\ddelink\dll\jWinAPI.dll: Can't find dependent libraries'&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;The wierd part is that the application worked fine if I launched the same IDEA-compiled &lt;span style="font-style:italic;"&gt;'*.class'&lt;/span&gt; files from the same IDEA output location. I checked that values of the &lt;span style="font-style:italic;"&gt;'java.library.path'&lt;/span&gt; jvm property and &lt;span style="font-style:italic;"&gt;'PATH'&lt;/span&gt; env variable were the same in both cases (launching application from IDE and from command-line).&lt;br /&gt;&lt;br /&gt;Eventually the problem was solved by explicitly adding &lt;span style="font-style:italic;"&gt;JNI '*.dll'&lt;/span&gt; files location to the &lt;span style="font-style:italic;"&gt;'PATH'&lt;/span&gt; env variable.&lt;br /&gt;&lt;br /&gt;Conclusion: it seems that jvm process launched from command-line is smart enough to use &lt;span style="font-style:italic;"&gt;jni *.dll&lt;/span&gt; files provided with the jre but it fails to do that in case of launch from IDE (that's true at least for IDEA).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-778309713770285215?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/778309713770285215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/jni-dll-and-ide.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/778309713770285215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/778309713770285215'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/jni-dll-and-ide.html' title='Jni dll and IDE'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-2134759265403041267</id><published>2010-01-12T22:20:00.020+03:00</published><updated>2010-01-14T11:27:09.159+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='ioc'/><title type='text'>Spring xsd loading algorithm</title><content type='html'>People often complain that spring tries to open network connection during application context initialization in order to load &lt;span style="font-style: italic;"&gt;'*.xsd'&lt;/span&gt; file(s). That shouldn't occur under normal circumstances, however, that is a case especially during application server participation. I'm going to briefly describe low-level details of &lt;span style="font-style: italic;"&gt;'*.xsd'&lt;/span&gt; loading algorithm used by spring.&lt;br/&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;'*.xsd'&lt;/span&gt; is necessary for describing the rules of spring xml context construction. E.g. the following simple spring xml config snippet defines three spring schemas - &lt;span style="font-style: italic;"&gt;'beans'&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;'aop'&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;'context'&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px inset; padding: 2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="background-color: white; height: 100%; margin: 0pt; overflow: auto; padding: 6px;"&gt;&lt;span style="color: blue; font-weight: bold;"&gt;&amp;lt;?xml&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;version=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"1.0"&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;encoding=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"UTF-8"&lt;/span&gt;&lt;span style="color: blue; font-weight: bold;"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;xmlns=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;xmlns:xsi=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;xmlns:context=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"http://www.springframework.org/schema/context"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;xmlns:aop=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"http://www.springframework.org/schema/aop"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"&lt;br /&gt;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&lt;/span&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;context:component-scan&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;base-package=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"com.spring.example.aop"&lt;/span&gt;/&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;id=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"methodInterceptor"&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;class=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"com.spring.example.aop.AopMethodInterceptor"&lt;/span&gt;/&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;id=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"pojoAspect"&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;class=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"com.spring.example.aop.PojoAspect"&lt;/span&gt;/&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;aop:advisor&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;advice-ref=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"methodInterceptor"&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;pointcut=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"execution(* com.spring.example.aop.AopService.*(..))"&lt;/span&gt;/&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;/aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;aop:aspect&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;ref=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"pojoAspect"&lt;/span&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;aop:before&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;method=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"pojoAdvice"&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;pointcut=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;"execution(* com.spring.example.aop.AopService.*(..))"&lt;/span&gt;/&lt;span style="color: navy; font-weight: bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;/aop:aspect&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;/aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;&amp;lt;/beans&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Let's see what happens when we instantiate spring context with such config:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Spring shoud parse the &lt;span style="font-style: italic;"&gt;'*.xml'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Spring defines custom &lt;a href="http://java.sun.com/javase/6/docs/api/org/xml/sax/EntityResolver.html"&gt;EntityResolver&lt;/a&gt; for the xml parser - &lt;a href="https://fisheye.springsource.org/browse/spring-framework/trunk/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/DelegatingEntityResolver.java?r=HEAD"&gt;DelegatingEntityResolver&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;'DelegatingEntityResolver.resolveEntity()'&lt;/span&gt; calls &lt;a href="https://fisheye.springsource.org/browse/spring-framework/trunk/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java?r=HEAD"&gt;PluggableSchemaResolver&lt;/a&gt;.resolveEntity();&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;'PluggableSchemaResolver.resolveEntity()'&lt;/span&gt; calls &lt;span style="font-style: italic;"&gt;'PluggableSchemaResolver.getSchemaMappings()'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;'PluggableSchemaResolver.getSchemaMappings()'&lt;/span&gt; tries to load properties from all resources named &lt;span style="font-style: italic;"&gt;'META-INF/spring.schemas'&lt;/span&gt; (&lt;span style="font-style: italic;"&gt;'PluggableSchemaResolver.DEFAULT_SCHEMA_MAPPINGS_LOCATION'&lt;/span&gt;) found at classpath during calling to &lt;a href="https://fisheye.springsource.org/browse/spring-framework/trunk/org.springframework.core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.java?r=HEAD"&gt;PropertiesLoaderUtils&lt;/a&gt;.loadAllProperties();&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;'PluggableSchemaResolver.resolveEntity()'&lt;/span&gt; tries to resolve target shema against classpath using the data from loaded properties;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;And here is a &lt;span style="font-style: italic;"&gt;'PropertiesLoaderUtils.loadAllProperties()'&lt;/span&gt; code:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; Properties loadAllProperties(String resourceName, ClassLoader classLoader) &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; IOException {&lt;br /&gt;    Assert.notNull(resourceName, &lt;span style="color:#008000;font-weight:bold;"&gt;"Resource name must not be null"&lt;/span&gt;);&lt;br /&gt;    ClassLoader clToUse = classLoader;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (clToUse == &lt;span style="color:#000080;font-weight:bold;"&gt;null&lt;/span&gt;) {&lt;br /&gt;        clToUse = ClassUtils.getDefaultClassLoader();&lt;br /&gt;    }&lt;br /&gt;    Properties properties = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; Properties();&lt;br /&gt;    Enumeration urls = clToUse.getResources(resourceName);&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (urls.hasMoreElements()) {&lt;br /&gt;        URL url = (URL) urls.nextElement();&lt;br /&gt;        InputStream is = &lt;span style="color:#000080;font-weight:bold;"&gt;null&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;try&lt;/span&gt; {&lt;br /&gt;            URLConnection con = url.openConnection();&lt;br /&gt;            con.setUseCaches(&lt;span style="color:#000080;font-weight:bold;"&gt;false&lt;/span&gt;);&lt;br /&gt;            is = con.getInputStream();&lt;br /&gt;            properties.load(is);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;finally&lt;/span&gt; {&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (is != &lt;span style="color:#000080;font-weight:bold;"&gt;null&lt;/span&gt;) {&lt;br /&gt;                is.close();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; properties;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Let's check the processing one more time on &lt;span style="font-style: italic;"&gt;'beans'&lt;/span&gt; schema example:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Our xml config defines &lt;span style="font-style: italic;"&gt;'beans'&lt;/span&gt; schema location as &lt;span style="font-style: italic;"&gt;'http://www.springframework.org/schema/beans/spring-beans-3.0.xsd'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;All contents of classpath resources named &lt;span style="font-style: italic;"&gt;'META-INF/spring.schemas'&lt;/span&gt; are loaded;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is &lt;span style="font-style: italic;"&gt;'META-INF/spring.schemas'&lt;/span&gt; file at &lt;span style="font-style: italic;"&gt;'spring-beans.jar'&lt;/span&gt;, it contains property &lt;span style="font-style: italic;"&gt;'http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd'&lt;/span&gt; among the others;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;'PluggableSchemaResolver'&lt;/span&gt; tries to load schema data from classpath resource defines as a target property value (&lt;span style="font-style: italic;"&gt;'org/springframework/beans/factory/xml/spring-beans-3.0.xsd'&lt;/span&gt;);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can see that there is &lt;span style="font-style: italic;"&gt;'org/springframework/beans/factory/xml/spring-beans-3.0.xsd'&lt;/span&gt; resource inside &lt;span style="font-style: italic;"&gt;'spring-beans.jar'&lt;/span&gt;. It's loaded and returned as a resolved xml entity;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;That's it - target &lt;span style="font-style: italic;"&gt;'*.xsd'&lt;/span&gt; file is loaded from classpath. Spring tries to load it from the web if it can't be loaded from classpath.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note:&lt;/span&gt; spring uses the same technique for loading namespace handlers necessary for correct context instantiation - see &lt;a href="https://fisheye.springsource.org/browse/spring-framework/trunk/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/DefaultNamespaceHandlerResolver.java?r=HEAD"&gt;DefaultNamespaceHandlerResolver&lt;/a&gt;. That's the reason why you should define custom schema definition and handler at &lt;span style="font-style: italic;"&gt;'META-INF/spring.schemas'&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;'META-INF/spring.handlers'&lt;/span&gt; files as &lt;a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/extensible-xml.html#extensible-xml-registration"&gt;described at the reference&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-2134759265403041267?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/2134759265403041267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/spring-xsd-loading-algorithm.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2134759265403041267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/2134759265403041267'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/spring-xsd-loading-algorithm.html' title='Spring xsd loading algorithm'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-8030875751422763259</id><published>2010-01-12T08:53:00.008+03:00</published><updated>2010-01-13T20:57:09.164+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem5</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#solution-paper"&gt;Solution (pen and paper)&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#prime-generator"&gt;Prime numbers generator&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#solution-program"&gt;Solution (program)&lt;/a&gt;;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="" name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.&lt;br /&gt;&lt;br /&gt;What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="solution-paper"&gt;Solution (pen and paper)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;The task can be easily solved analytically - we know that every non-prime number may be represented as a multiplication of prime number factors (prime factorization). E.g. we can check that the least common multiple for the natural numbers less or equal to ten (as provided at the problem definition). We can derive prime factorization for all numbers from &lt;span style="font-style: italic;"&gt;[1; 10]&lt;/span&gt; range:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;1 = 1&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;2 = 2&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;3 = 3&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;4 = 2&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;5 = 5&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;6 = 2&lt;sup&gt;1&lt;/sup&gt; * 3&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;7 = 7&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;8 = 2&lt;sup&gt;3&lt;/sup&gt;&lt;br /&gt;9 = 3&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;10 = 2&lt;sup&gt;1&lt;/sup&gt; * 5&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can conclude that the least common multiple for that numbers is a multiplication of all prime numbers less or equal to ten with max factor occurred at the prime factorizations, i.e.&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;2&lt;sup&gt;3&lt;/sup&gt; * 3&lt;sup&gt;2&lt;/sup&gt; * 5&lt;sup&gt;1&lt;/sup&gt; * 7&lt;sup&gt;1&lt;/sup&gt; = 2520&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can follow the same principle for calculating least common multiple for the numbers less or equal to 20:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;1 = 1&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;2 = 2&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;3 = 3&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;4 = 2&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;5 = 5&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;6 = 2&lt;sup&gt;1&lt;/sup&gt; * 3&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;7 = 7&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;8 = 2&lt;sup&gt;3&lt;/sup&gt;&lt;br /&gt;9 = 3&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;10 = 2&lt;sup&gt;1&lt;/sup&gt; * 5&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;11 = 11&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;12 = 2&lt;sup&gt;2&lt;/sup&gt; * 3&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;13 = 13&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;14 = 2&lt;sup&gt;1&lt;/sup&gt; * 7&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;15 = 3&lt;sup&gt;1&lt;/sup&gt; * 5&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;16 = 2&lt;sup&gt;4&lt;/sup&gt;&lt;br /&gt;17 = 17&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;18 = 2&lt;sup&gt;1&lt;/sup&gt; * 3&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;19 = 19&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;20 = 2&lt;sup&gt;2&lt;/sup&gt; * 5&lt;sup&gt;1&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;result = 2&lt;sup&gt;4&lt;/sup&gt; * 3&lt;sup&gt;2&lt;/sup&gt; * 5&lt;sup&gt;1&lt;/sup&gt; * 7&lt;sup&gt;1&lt;/sup&gt; * 11&lt;sup&gt;1&lt;/sup&gt; * 13&lt;sup&gt;1&lt;/sup&gt; * 17&lt;sup&gt;1&lt;/sup&gt; * 19&lt;sup&gt;1&lt;/sup&gt; = 232792560&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="" name="prime-generator"&gt;Prime numbers generator&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Let's create a program that solves the same task. We'll need prime numbers generator for that. Scala allows to create the one via very natural and convenient syntax:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getNaturalNumbers(from: Long) : Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(from, result map(_ + 1))&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getPrimeNumbers(): Stream[Long] = {&lt;br /&gt;        lazy val result: Stream[Long] = Stream.cons(2, getNaturalNumbers(3) filter {&lt;br /&gt;            n =&amp;gt; result.takeWhile(p =&amp;gt; p * p &amp;lt;= n).forall(n % _ != 0)&lt;br /&gt;        })&lt;br /&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def execute(f: =&amp;gt; Any) = {&lt;br /&gt;        println()&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"--------------------&amp;gt; Starting &amp;lt;---------------------"&lt;/span&gt;)&lt;br /&gt;        val start = System.nanoTime&lt;br /&gt;        f&lt;br /&gt;        println(&lt;span style="color:#008000;font-weight:bold;"&gt;"------------------&amp;gt; Executed in "&lt;/span&gt; + ((System.nanoTime - start) / 1000000000d) + &lt;span style="color:#008000;font-weight:bold;"&gt;" seconds &amp;lt;-------------------"&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;We are interested in &lt;span style="font-style: italic;"&gt;'getNaturalNumbers()'&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;'getPrimeNumbers()'&lt;/span&gt; methods here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getNaturalNumbers()&lt;/span&gt;&lt;br /&gt;The main interesting thing here is &lt;span style="font-style: italic;"&gt;'Stream.cons(from, result map(_ + 1))'&lt;/span&gt;. What do we do here - define an infinite list of lazily calculated eight-byte values where the first value is the one given as a method parameter (&lt;span style="font-style: italic;"&gt;'from'&lt;/span&gt;) and any subsequent value is calculated as a previous value plus one (&lt;span style="font-style: italic;"&gt;'result map(_ + 1)'&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getPrimeNumbers()&lt;/span&gt;&lt;br /&gt;Things get little more complicated here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;define a prime numbers stream with first element &lt;span style="font-style: italic;"&gt;'2'&lt;/span&gt; (&lt;span style="font-style: italic;"&gt;'Stream.cons(2, ...)'&lt;/span&gt;);&lt;/li&gt;&lt;li&gt;any subsequent prime number candidate is retrieved from the stream of natural numbers and prime number criteria is that it's not divisible to already discovered prime numbers (&lt;span style="font-style: italic;"&gt;'filter(n =&amp;gt; takeWhile(...).forall(n % _ != 0))'&lt;/span&gt;);&lt;/li&gt;&lt;li&gt;we check if prime number candidate is really prime number by examining if it is divisible by the already discovered prime numbers that are less or equal to the square root of the candidate (&lt;span style="font-style: italic;"&gt;'result.takeWhile(p =&amp;gt; p * p &amp;lt;= n)'&lt;/span&gt;). This is optimization in comparison with the approach when we check all discovered prime numbers (&lt;span style="font-style: italic;"&gt;'result.takeWhile(p =&amp;gt; p &amp;lt; n)'&lt;/span&gt;). The rationale is that any number that is divisible by the prime number greater that &lt;span style="font-style: italic;"&gt;sqrt(candidate)&lt;/span&gt; is also divisible by the prime number less than &lt;span style="font-style: italic;"&gt;sqrt(candidate)&lt;/span&gt;. Hence, we can be sure that the number is prime if it is not divisible by prime numbers less or equal to the &lt;span style="font-style: italic;"&gt;sqrt(number)&lt;/span&gt;;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="" name="solution-program"&gt;Solution (program)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;So, our task is to find out max prime number factors for all prime numbers less than or equal to the target bound and perform multiplication of prime numbers at that factors. Rephrasing, the task is to check all prime numbers less than or equal to the target bound number and find max &lt;span style="font-style: italic;"&gt;'n'&lt;/span&gt; from the following inequality:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;prime&lt;sup&gt;n&lt;/sup&gt; &amp;lt;= targetBound &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We can derive the following formula for &lt;span style="font-style: italic;"&gt;'n'&lt;/span&gt; than:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;n &amp;lt;= floor(log&lt;sub&gt;prime&lt;/sub&gt;(targetBound)) = floor(ln(targetBound) / ln(prime))&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It's clear that all prime numbers from &lt;span style="font-style: italic;"&gt;(sqrt(bound); bound]&lt;/span&gt; have max factor equal to one, so, our program performs logarithm-involved processing for all prime numbers less than or equal to &lt;span style="font-style: italic;"&gt;sqrt(bound)&lt;/span&gt; and simple multiplication for other prime numbers:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;P5.scala&lt;/span&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p5&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil._&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 10, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P5 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    execute {&lt;br /&gt;        val targetBound = 20&lt;br /&gt;        val bound = sqrt(targetBound)&lt;br /&gt;&lt;br /&gt;        val partialResult = (1L /: getPrimeNumbers.takeWhile(_ &amp;lt;= bound)) {&lt;br /&gt;            (i, j) =&amp;gt; i * pow(j, floor(log(targetBound) / log(j))).toLong&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        val result = (partialResult /: getPrimeNumbers().dropWhile(_ &amp;lt;= bound).takeWhile(_ &amp;lt;= targetBound))(_ * _)&lt;br /&gt;        println(result)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-8030875751422763259?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/8030875751422763259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8030875751422763259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/8030875751422763259'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem5.html' title='ProjectEuler - problem5'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-7761724563240161641</id><published>2010-01-09T22:51:00.009+03:00</published><updated>2010-01-13T20:49:02.184+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem6</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html#bf-imperative"&gt;Brute force (imperative style)&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html#bf-functional"&gt;Brute force (functional style)&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html#optimization"&gt;Algorithm optimization&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html#final"&gt;Final version&lt;/a&gt;;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5682856111471502603&amp;amp;postID=7761724563240161641" name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;The sum of the squares of the first ten natural numbers is,&lt;br /&gt;1&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;2&lt;/sup&gt; + ... + 10&lt;sup&gt;2&lt;/sup&gt; = 385&lt;br /&gt;&lt;br /&gt;The square of the sum of the first ten natural numbers is,&lt;br /&gt;(1 + 2 + ... + 10)&lt;sup&gt;2&lt;/sup&gt; = 55&lt;sup&gt;2&lt;/sup&gt; = 3025&lt;br /&gt;&lt;br /&gt;Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.&lt;br /&gt;&lt;br /&gt;Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.&lt;br /&gt;&lt;/blockquote&gt;&lt;h4&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5682856111471502603&amp;amp;postID=7761724563240161641" name="bf-imperative"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5682856111471502603&amp;amp;postID=7761724563240161641" name="bf-imperative"&gt;Brute force (imperative style)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;ArithmeticProgression.scala&lt;/span&gt;&lt;br /&gt;&lt;div style="border: 1px inset; padding: 2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="background-color: white; height: 100%; margin: 0pt; overflow: auto; padding: 6px;"&gt;&lt;span style="color: navy; font-weight: bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color: grey; font-style: italic;"&gt;/**&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;case&lt;/span&gt; &lt;span style="color: navy; font-weight: bold;"&gt;class&lt;/span&gt; ArithmeticProgression(val base: Long, val step: Long) {&lt;br /&gt;&lt;br /&gt;    def element(index: Long) = base + index * step&lt;br /&gt;&lt;br /&gt;    def sumByElementsCount(elementsNumber: Long) = (base + element(elementsNumber - 1)) * elementsNumber / 2&lt;br /&gt;&lt;br /&gt;    def sumByLastFloorElement(element: Long) = sumByElementsCount(1 + (element - base) / step)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;P3.scala&lt;/span&gt;&lt;br /&gt;&lt;div style="border: 1px inset; padding: 2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="background-color: white; height: 100%; margin: 0pt; overflow: auto; padding: 6px;"&gt;&lt;span style="color: navy; font-weight: bold;"&gt;package&lt;/span&gt; net.projecteuler.p3&lt;br /&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ArithmeticProgression&lt;br /&gt;&lt;br /&gt;&lt;span style="color: grey; font-style: italic;"&gt;/**&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@since&lt;/span&gt; Jan 9, 2010&lt;br /&gt;*/&lt;/span&gt;&lt;br /&gt;object P3 &lt;span style="color: navy; font-weight: bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    val i = ArithmeticProgression(1, 1).sumByLastFloorElement(100)&lt;br /&gt;    var j = 0L&lt;br /&gt;    &lt;span style="color: navy; font-weight: bold;"&gt;for&lt;/span&gt; (k &amp;lt;- 1 to 100) j += k * k&lt;br /&gt;    println(i * i - j)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5682856111471502603&amp;amp;postID=7761724563240161641" name="bf-functional"&gt;Brute force (functional style)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;div style="border: 1px inset; padding: 2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="background-color: white; height: 100%; margin: 0pt; overflow: auto; padding: 6px;"&gt;&lt;span style="color: navy; font-weight: bold;"&gt;package&lt;/span&gt; net.projecteuler.p3&lt;br /&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ArithmeticProgression&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;br /&gt;&lt;span style="color: grey; font-style: italic;"&gt;/**&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@since&lt;/span&gt; Jan 9, 2010&lt;br /&gt;*/&lt;/span&gt;&lt;br /&gt;object P3 &lt;span style="color: navy; font-weight: bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    val squareOfSum = pow(ArithmeticProgression(1, 1).sumByLastFloorElement(100), 2)&lt;br /&gt;    val sumOfSquares = (0.0 /: (1 to 100))(_ + pow(_, 2))&lt;br /&gt;    println(squareOfSum - sumOfSquares)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5682856111471502603&amp;amp;postID=7761724563240161641" name="optimization"&gt;Algorithm optimization&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;You see that square of sum is calculated in constant time using the formula of arithmetic progression sum. However, we still have linear complexity for the part that calculates sum of squares. We're going to work out a formula for that.&lt;br /&gt;&lt;br /&gt;Sum of cubes formula:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;(n + 1)&lt;sup&gt;3&lt;/sup&gt; = (n + 1) * (n + 1) * (n + 1) = (n + 1) * (n&lt;sup&gt;2&lt;/sup&gt; + 2n + 1) = n&lt;sup&gt;3&lt;/sup&gt; + 3 * n&lt;sup&gt;2&lt;/sup&gt; + 3 * n + 1&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Let's write down sequence of the equation above with parameters &lt;span style="font-style: italic;"&gt;n, (n - 1), (n -2), (n - 3), ..., 1&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;(n + 1)&lt;sup&gt;3&lt;/sup&gt; = n&lt;sup&gt;3&lt;/sup&gt; + 3 * n&lt;sup&gt;2&lt;/sup&gt; + 3 * n + 1&lt;br /&gt;n&lt;sup&gt;3&lt;/sup&gt; = (n - 1)&lt;sup&gt;3&lt;/sup&gt; + 3 * (n - 1)&lt;sup&gt;2&lt;/sup&gt; + 3 * (n - 1) + 1&lt;br /&gt;(n - 1)&lt;sup&gt;3&lt;/sup&gt; = (n - 2)&lt;sup&gt;3&lt;/sup&gt; + 3 * (n - 2)&lt;sup&gt;2&lt;/sup&gt; + 3 * (n - 2) + 1&lt;br /&gt;...&lt;br /&gt;2&lt;sup&gt;3&lt;/sup&gt; = 1&lt;sup&gt;3&lt;/sup&gt; + 3 * 1&lt;sup&gt;2&lt;/sup&gt; + 3 * 1 + 1&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Let's summarize left and right part of the equations above and drop identical members. We get the following then:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;(n + 1)&lt;sup&gt;3&lt;/sup&gt; = 1&lt;sup&gt;3&lt;/sup&gt; + 3 * (n&lt;sup&gt;2&lt;/sup&gt; + (n - 1)&lt;sup&gt;2&lt;/sup&gt; + ... + 1&lt;sup&gt;2&lt;/sup&gt;) + 3 * (n + (n - 1) + (n - 2) + ... + 1) + (1 + 1 + 1 + ... + 1)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can see that the second element of the right part of the equation above is our target sum &lt;span style="font-style: italic;"&gt;(n&lt;sup&gt;2&lt;/sup&gt; + (n - 1)&lt;sup&gt;2&lt;/sup&gt; + ... + 1&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt;. Define it as &lt;span style="font-style: italic;"&gt;S&lt;/span&gt;, apply arithmetic progression sum formula to the third element and rewrite the equation:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;3 * S = (n + 1)&lt;sup&gt;3&lt;/sup&gt; - 1 - 3 * n * (n + 1) / 2 - n = (n + 1) * ((n + 1)&lt;sup&gt;2&lt;/sup&gt; - 3/2 * n - 1) = (n + 1) (n&lt;sup&gt;2&lt;/sup&gt; + 2n + 1 - 3/2 * n - 1) = n * (n + 1) (n + 1/2) = n * (n + 1) * (2n + 1) / 2&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That produces the following formula for our target sum of squares:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;S = n * (n + 1) * (2n + 1) / 6&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5682856111471502603&amp;amp;postID=7761724563240161641" name="final"&gt;Final version&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;We can apply the formula deduced above and get the following solution that works with &lt;span style="font-style: italic;"&gt;O(1)&lt;/span&gt; complexity:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px inset; padding: 2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="background-color: white; height: 100%; margin: 0pt; overflow: auto; padding: 6px;"&gt;&lt;span style="color: navy; font-weight: bold;"&gt;package&lt;/span&gt; net.projecteuler.p3&lt;br /&gt;&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ArithmeticProgression&lt;br /&gt;&lt;span style="color: navy; font-weight: bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;br /&gt;&lt;span style="color: grey; font-style: italic;"&gt;/**&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt;* &lt;span style="color: grey; font-style: italic; font-weight: bold; text-decoration: underline;"&gt;@since&lt;/span&gt; Jan 9, 2010&lt;br /&gt;*/&lt;/span&gt;&lt;br /&gt;object P3 &lt;span style="color: navy; font-weight: bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    val elementsNumber = 100&lt;br /&gt;    val squareOfSum = pow(ArithmeticProgression(1, 1).sumByLastFloorElement(elementsNumber), 2)&lt;br /&gt;    val sumOfSquares = elementsNumber * (elementsNumber + 1) * (2 * elementsNumber + 1) / 6&lt;br /&gt;    println(squareOfSum - sumOfSquares)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-7761724563240161641?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/7761724563240161641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7761724563240161641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/7761724563240161641'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem6.html' title='ProjectEuler - problem6'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-532556208342336743</id><published>2010-01-08T21:17:00.016+03:00</published><updated>2010-01-15T12:51:14.534+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - problem2</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#task"&gt;Problem definition&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#bf-imperative"&gt;Brute force (imperative style)&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#bf-functional"&gt;Brute force (functional style)&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#bf-optimization"&gt;Brute force algorithm optimization&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#bf-optimized-imperative"&gt;Optimized brute fortce (imperative style)&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#bf-optimized-functional"&gt;Optimized brute fortce (functional style)&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#further-optimization"&gt;Further optimization&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#fib-sum"&gt;Target Fibonacci numbers sum formula&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#binet-formula"&gt;Binet's Formula&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#result"&gt;Resulting solution&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="task"&gt;Problem definition&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Find the sum of all the even-valued terms in the sequence which do not exceed four million.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="bf-imperative"&gt;Brute force (imperative style)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Here is a simple program written in imperative style that acts exactly the same as defined at the problem definition - iterates via Fibonacci numbers until the number over than four millions is reached and summarize even numbers:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p2&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 6, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P2 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    var i = 1L&lt;br /&gt;    var j = 2L&lt;br /&gt;    var t = j&lt;br /&gt;    var sum = 0L&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (t &amp;lt; 4000000) {&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (j % 2 == 0) sum = sum + j&lt;br /&gt;        t = i + j&lt;br /&gt;        i = j&lt;br /&gt;        j = t&lt;br /&gt;    }&lt;br /&gt;    println(sum)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="bf-functional"&gt;Brute force (functional style)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;We can rewrite the program above using functional style. It shows how cleaner the code is:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.scala&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.util&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * Holds utility methods for the ProjectEuler task classes and objects.&lt;br /&gt; *&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object ProjectEulerUtil {&lt;br /&gt;&lt;br /&gt;    def getFibonacciStream() : Stream[Long] = {&lt;br /&gt;        lazy val fib: Stream[Long] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(t =&amp;gt; t._1 + t._2)))&lt;br /&gt;        fib&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;P2.scala&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p2&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; net.projecteuler.util.ProjectEulerUtil&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 6, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P2 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    val fib = ProjectEulerUtil.getFibonacciStream()    &lt;br /&gt;    println(fib.filter(f =&amp;gt; f % 2 == 0).takeWhile(f =&amp;gt; f &amp;lt; 4000000).foldLeft(0L)(_ + _))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's point out what we did here:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;define Fibonacci sequence as &lt;a href="http://www.scala-lang.org/docu/files/api/scala/Stream.html"&gt;scala.Stream[Long]&lt;/a&gt;, i.e. as an unbound list of eight-byte elements that are calculated lazily (&lt;span style="font-style:italic;"&gt;ProjectEulerUtil.getFibonacciStream()&lt;/span&gt;);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;use helper object &lt;a href="http://www.scala-lang.org/docu/files/api/scala/Stream$object.cons$object.html"&gt;scala.Stream.cons&lt;/a&gt; that allows to build a &lt;span style="font-style:italic;"&gt;Stream&lt;/span&gt; instance for the given head element and tail &lt;span style="font-style:italic;"&gt;Stream&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define target Fibonacci stream with the help of &lt;span style="font-style:italic;"&gt;Stream.cons&lt;/span&gt; where the first element is zero (&lt;span style="font-style:italic;"&gt;'Stream.cons(0, ... /* tail Stream */'&lt;/span&gt;);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define that the second Fibonacci stream element is one (&lt;span style="font-style:italic;"&gt;'Stream.cons(0, Stream.cons(1, .../* tails Stream */))'&lt;/span&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define the rule for calculating Fibonacci numbers over than the first and the second - &lt;span style="font-style:italic;"&gt;'fib.zip(fib.tail).map(t =&gt; t._1 + t._2)'&lt;/span&gt;. Here &lt;span style="font-style:italic;"&gt;'fib.zip(fib.tail)'&lt;/span&gt; states that we assemble two number sequences together - &lt;span style="font-style:italic;"&gt;'0 1 1 2 3 ...'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'1 1 2 3 5 ...'&lt;/span&gt; in order to get sequence of pairs - &lt;span style="font-style:italic;"&gt;'(0, 1) (1, 1) (1, 2) (2, 3) (3, 5)' (feel free to check &lt;a href="http://www.scala-lang.org/docu/files/api/scala/Stream.html#zip%28Stream%5BB%5D%29"&gt;Stream.zip()&lt;/a&gt; method contract for more details about that). Than we define a rule that produces single element as a sum of the pair of number - &lt;span style="font-style:italic;"&gt;'map(t =&gt; t._1 + t._2)'&lt;/span&gt; (feel free to check &lt;a href="http://www.scala-lang.org/docu/files/api/scala/Stream.html#map%28%28A%29%3D%3EB%29"&gt;Stream.map()&lt;/a&gt; contract for more details about that)&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define a rule to skip odd Fibonacci elements - &lt;span style="font-style:italic;"&gt;'fib.filter(f =&gt; f % 2 == 0)'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;define a rule that we want to get Fibonacci numbers that don't exceed for millions - &lt;span style="font-style:italic;"&gt;'fib.takeWhile(f =&gt; f &lt; 4000000)'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;apply a function that summarize all given elements starting from the zero to the filtered Fibonacci numbers substream (even numbers that don't exceed for millions) - &lt;span style="font-style:italic;"&gt;'fib.foldLeft(0L)(_ + _)'&lt;/span&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="bf-optimization"&gt;Brute force algorithm optimization&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ok, we see that the problem is solved now but solution has a liniar complexity, i.e. the program takes much more time if we are asked to use not four millions as an upper bound but a bigger value. Let's check if the solution can be improved.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's write Fibonacci sequence start and analyze it:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;0 1 1 &lt;span style="color:red"&gt;2&lt;/span&gt; 3 5 &lt;span style="color:red"&gt;8&lt;/span&gt; 13 21 &lt;span style="color:red"&gt;34&lt;/span&gt; 55 89 &lt;span style="color:red"&gt;144&lt;/span&gt; ...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can drop the first sequence element (zero) because it doesn't affect net result and check that only every third number is even (it's easy to provide strict proof for that). So, we can optimize the algorithm by avoiding odd values calculation, i.e. we can calculate directly even values. I.e. our task is to work out a formula that allows to calculate &lt;span style="font-style:italic;"&gt;F&lt;sub&gt;n + 6&lt;/sub&gt;&lt;/span&gt; via &lt;span style="font-style:italic;"&gt;F&lt;sub&gt;n + 3&lt;/sub&gt;&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;F&lt;sub&gt;n&lt;/sub&gt;&lt;/span&gt; values (here &lt;span style="font-style:italic;"&gt;F&lt;sub&gt;n&lt;/sub&gt;&lt;/span&gt; is n-th Fibonacci sequence member):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = F&lt;sub&gt;n+5&lt;/sub&gt; + F&lt;sub&gt;n+4&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = (F&lt;sub&gt;n+4&lt;/sub&gt; + F&lt;sub&gt;n+3&lt;/sub&gt;) + (F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 2 * F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt; + F&lt;sub&gt;n+4&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 2 * F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt; + (F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 3 * F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 3 * F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+2&lt;/sub&gt; + (F&lt;sub&gt;n+1&lt;/sub&gt; + F&lt;sub&gt;n&lt;/sub&gt;)&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 3 * F&lt;sub&gt;n+3&lt;/sub&gt; + (F&lt;sub&gt;n+2&lt;/sub&gt; + F&lt;sub&gt;n+1&lt;/sub&gt;) + F&lt;sub&gt;n&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 3 * F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n+6&lt;/sub&gt; = 4 * F&lt;sub&gt;n+3&lt;/sub&gt; + F&lt;sub&gt;n&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="bf-optimized-imperative"&gt;Optimized brute fortce (imperative style)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Let's apply the formula produced above to our solution. Let's start with imperative approach at first:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p2&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 6, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P2 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    var i = 2L&lt;br /&gt;    var j = 8L&lt;br /&gt;    var t = j&lt;br /&gt;    var sum = 2L&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;while&lt;/span&gt; (t &amp;lt; 4000000) {&lt;br /&gt;        sum = sum + j&lt;br /&gt;        t = 4 * j + i&lt;br /&gt;        i = j&lt;br /&gt;        j = t&lt;br /&gt;    }&lt;br /&gt;    println(sum)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="bf-optimized-functional"&gt;Optimized brute fortce (functional style)&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Let's rewrite the same optimized brute force algorithm using functional style (note that we slightly modified our functional approach in order to exploit scala language syntax sugar):&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p2&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 6, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P2 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    lazy val fib: Stream[Long] = Stream.cons(2, Stream.cons(8, fib.zip(fib.tail).map(t =&amp;gt; t._1 + 4 * t._2)))&lt;br /&gt;    println((0L /: fib.filter(_ % 2 == 0).takeWhile(_ &amp;lt; 4000000))(_ + _))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="further-optimization"&gt;Further optimization&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;We optimized the algorithm but it still has an &lt;span style="font-style:italic;"&gt;O(n)&lt;/span&gt; complexity. Let's try to improve it further. Let's check our sequence one more time:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;0 1 1 &lt;span style="color:red"&gt;2&lt;/span&gt; 3 5 &lt;span style="color:red"&gt;8&lt;/span&gt; 13 21 &lt;span style="color:red"&gt;34&lt;/span&gt; 55 89 &lt;span style="color:red"&gt;144&lt;/span&gt; ...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We know that the main Fibonacci sequence characteristics is that &lt;span style="font-style:italic;"&gt;'F&lt;sub&gt;n&lt;/sub&gt; = F&lt;sub&gt;n - 1&lt;/sub&gt; + F&lt;sub&gt;n - 2&lt;/sub&gt;'&lt;/span&gt;, so, we can conclude that the sum of the target Fibonacci numbers (highlighted) is a half of the sum of all Fibonacci numbers - target numbers follow each other in two elements, that means that every target number is equal to the sum of the previous two numbers. Conclusion: we can calculate sum of all Fibonacci numbers stopping at the last even number that doesn't exceed four millions, divide it by two and get desired result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="fib-sum"&gt;Target Fibonacci numbers sum formula&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Our task is to work out a formula for Fibonacci numbers sum. Let's write down a following equations sequence:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;1&lt;/sub&gt; = F&lt;sub&gt;3&lt;/sub&gt; - F&lt;sub&gt;2&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;2&lt;/sub&gt; = F&lt;sub&gt;4&lt;/sub&gt; - F&lt;sub&gt;3&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;3&lt;/sub&gt; = F&lt;sub&gt;5&lt;/sub&gt; - F&lt;sub&gt;4&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n-1&lt;/sub&gt; = F&lt;sub&gt;n+1&lt;/sub&gt; - F&lt;sub&gt;n&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n&lt;/sub&gt; = F&lt;sub&gt;n+2&lt;/sub&gt; - F&lt;sub&gt;n+1&lt;/sub&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can summarize all parts of the equations above and get the following then:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;1&lt;/sub&gt; + F&lt;sub&gt;2&lt;/sub&gt; + F&lt;sub&gt;3&lt;/sub&gt; + ... + F&lt;sub&gt;n-1&lt;/sub&gt; + F&lt;sub&gt;n&lt;/sub&gt; = F&lt;sub&gt;n + 2&lt;/sub&gt; - F&lt;sub&gt;2&lt;/sub&gt; = F&lt;sub&gt;n+2&lt;/sub&gt; - 1&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="binet-formula"&gt;Binet's Formula&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Ok, we know that sum of n Fibonacci numbers may be calculated via (n + 2)-th member. That means that we need to know how to calculate any Fibonacci number by it's index. There is a special formula for that - Binet's Formula:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wBtqK4BXFZc/S0hLOL7O1CI/AAAAAAAAAEA/ZoVu5KpD5EY/s1600-h/318b29cab7fca85a354b6b61cffa1b47.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 52px;" src="http://1.bp.blogspot.com/_wBtqK4BXFZc/S0hLOL7O1CI/AAAAAAAAAEA/ZoVu5KpD5EY/s320/318b29cab7fca85a354b6b61cffa1b47.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5424668458259239970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wBtqK4BXFZc/S0hLePTjT3I/AAAAAAAAAEI/RPcPPsPG8Po/s1600-h/a89c8ea0d0ef36a31e2ed1ae03cac66c.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 100px; height: 44px;" src="http://2.bp.blogspot.com/_wBtqK4BXFZc/S0hLePTjT3I/AAAAAAAAAEI/RPcPPsPG8Po/s320/a89c8ea0d0ef36a31e2ed1ae03cac66c.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5424668734044458866" /&gt;&lt;/a&gt; is calculated as a root of the following equation - &lt;span style="font-style:italic;"&gt;'x&lt;sup&gt;2&lt;/sup&gt; = x + 1'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's prove the formula. We'll use &lt;a href="http://en.wikipedia.org/wiki/Math_induction_proof"&gt;Math induction&lt;/a&gt; for that:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Check that the formula holds true for the first and second Fibonacci numbers;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Proof that the formula is correct for the n-th number assuming that it's correct for the (n - 1)-th and (n - 2)-th numbers&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's define the following quantities in order to make the proof more readable:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;a = (1+sqrt[5])/2,&lt;br /&gt;&lt;br /&gt;b = (1-sqrt[5])/2 = -1/a&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We get the following then:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n&lt;/sub&gt; = F&lt;sub&gt;n-1&lt;/sub&gt; + F&lt;sub&gt;n-2&lt;/sub&gt; = (a&lt;sup&gt;n-1&lt;/sup&gt; - b&lt;sup&gt;n-1&lt;/sup&gt;) / (a - b) + (a&lt;sup&gt;n-2&lt;/sup&gt; - b&lt;sup&gt;n-2&lt;/sup&gt;) / (a - b) = (a&lt;sup&gt;n-1&lt;/sup&gt; + a&lt;sup&gt;n-2&lt;/sup&gt; - b&lt;sup&gt;n-1&lt;/sup&gt; - b&lt;sup&gt;n-2&lt;/sup&gt;) / (a - b) = (a&lt;sup&gt;n-2&lt;/sup&gt;(a + 1) - b&lt;sup&gt;n-2&lt;/sup&gt;(b + 1)) / (a - b)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We remember that &lt;span style="font-style:italic;"&gt;'a'&lt;/span&gt; is a root of &lt;span style="font-style:italic;"&gt;'x&lt;sup&gt;2&lt;/sup&gt; = x + 1'&lt;/span&gt; equation but &lt;span style="font-style:italic;"&gt;'b'&lt;/span&gt; is another root of the same equation, i.e. &lt;span style="font-style:italic;"&gt;'a + 1 = a&lt;sup&gt;2&lt;/sup&gt;'&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;'b + 1 = b&lt;sup&gt;2&lt;/sup&gt;'&lt;/span&gt;. We can apply that to the last equation and get the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid; padding:5px;background-color:#F3F5E9;"&gt;&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;n&lt;/sub&gt; = (a&lt;sup&gt;n&lt;/sup&gt; - b&lt;sup&gt;n&lt;/sup&gt;) / (a - b)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="result"&gt;Resulting solution&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;There is an important consequence from Binet's Formula - n-th Fibonacci number can be calculated by rounding the following expression result:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wBtqK4BXFZc/S0hbDXJoPyI/AAAAAAAAAEQ/swDBD13_z7E/s1600-h/3dd9f1ea1c12a625ee27381a4992b601.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 35px; height: 48px;" src="http://4.bp.blogspot.com/_wBtqK4BXFZc/S0hbDXJoPyI/AAAAAAAAAEQ/swDBD13_z7E/s320/3dd9f1ea1c12a625ee27381a4992b601.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5424685864479899426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also we remember that every three consequent numbers from our target sequence contain two odd numbers and one even number.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is resulting solution:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p2&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; Math._&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 6, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P2 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;&lt;br /&gt;    val Phi = 1.6180339887&lt;br /&gt;    val FiveSqrt = sqrt(5.0)&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Calculates n-th element of the target sequence.&lt;br /&gt;     * &lt;span style="background-color:#e2ffe2;"&gt;&amp;lt;p/&amp;gt;&lt;/span&gt;&lt;br /&gt;     * We use 'n + 1' inside because target sequence is not pure Fibonacci sequence&lt;br /&gt;     * ('1 2 3 5 ...' vs '0 1 1 2 3 4 ...').&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def nthElement(n: Long) = round(pow(Phi, n + 1) / FiveSqrt)&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt;     * Searches for the index of the target sequence element that is even and don't exceed given bound value.&lt;br /&gt;     */&lt;/span&gt;&lt;br /&gt;    def lastIndex(bound: Long) : Int = {&lt;br /&gt;        val i: Int = (log(bound * sqrt(5)) / log(Phi)) toInt&lt;br /&gt;        val result =&lt;br /&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (bound % 2 == 0 &amp;&amp; bound == nthElement(i - 1)) i - 1 &lt;span style="color:#808080;font-style:italic;"&gt;// Given bound is even sequence element&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;else&lt;/span&gt; (0 /: (i - 3 to i - 1).filter(nthElement(_) % 2 == 0))(_ + _) &lt;span style="color:#808080;font-style:italic;"&gt;// Check previous three elements&lt;br /&gt;&lt;/span&gt;        result&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    println((nthElement(lastIndex(4000000) + 2) - 1) / 2)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We do exactly the following here:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Provide ability to calculate n-th sequence element (&lt;span style="font-style:italic;"&gt;'nthElement()'&lt;/span&gt; method);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Provide ability to find index of the max sequence element that is even and less or equal to the given number (&lt;span style="font-style:italic;"&gt;'lastIndex()'&lt;/span&gt; method);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Calculate result via calculating total sequence elements sum and dividing it by two;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Resulting complexity is &lt;span style="font-style:italic;"&gt;O(1)&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-532556208342336743?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/532556208342336743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/532556208342336743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/532556208342336743'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/projecteuler-problem2.html' title='ProjectEuler - problem2'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_wBtqK4BXFZc/S0hLOL7O1CI/AAAAAAAAAEA/ZoVu5KpD5EY/s72-c/318b29cab7fca85a354b6b61cffa1b47.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-4182709495967623223</id><published>2010-01-05T23:45:00.004+03:00</published><updated>2010-01-15T12:53:59.741+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='aop'/><title type='text'>Spring1 and Spring2 AOP interoperability</title><content type='html'>&lt;h4&gt;Table of contents&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#rationale"&gt;rationale&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#source"&gt;Source code&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#AopService"&gt;AopService&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#AopMethodInterceptor"&gt;AopMethodInterceptor&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#PojoAspect"&gt;PojoAspect&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#spring-config.xml"&gt;spring-config.xml&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#SpringStart"&gt;SpringStart&lt;/a&gt;;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="rationale"&gt;Rationale&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I really don't understand the reasons but many developers still use spring1 aop style (explicit &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/aop/framework/ProxyFactoryBean.html"&gt;ProxyFactoryBean&lt;/a&gt; and various &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/aop/Advisor.html"&gt;Advisor&lt;/a&gt; implementations usage). I just want to point out that spring2 aop (aspectj-based) is completely interoperable with the spring1 aop style. I.e. it's possible to perform a graceful migration of old project to the new approach which is more concise and less verbose. I'm going to provide couple of examples of that.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="source"&gt;Source code&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Source code packaged as a maven2 project may be downloaded &lt;a href="http://dl.dropbox.com/u/1648086/example/spring/aop/aop-interoperability.tar.gz"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="AopService"&gt;AopService.java&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Target aop-advised service:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; com.spring.example.aop;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; org.springframework.stereotype.Component;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#808000;"&gt;@Component&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; AopService {&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; test() {&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"AopService.test()"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="AopMethodInterceptor"&gt;AopMethodInterceptor.java&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Spring1-based advice:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; com.spring.example.aop;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; org.aopalliance.intercept.MethodInterceptor;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; org.aopalliance.intercept.MethodInvocation;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; AopMethodInterceptor &lt;span style="color:#000080;font-weight:bold;"&gt;implements&lt;/span&gt; MethodInterceptor {&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#808000;"&gt;@Override&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; Object invoke(MethodInvocation invocation) &lt;span style="color:#000080;font-weight:bold;"&gt;throws&lt;/span&gt; Throwable {&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"AopMethodInterceptor.invoke()"&lt;/span&gt;);&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;return&lt;/span&gt; invocation.proceed();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;&lt;h4&gt;&lt;a name="PojoAspect"&gt;PojoAspect.java&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Pojo aspect:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; com.spring.example.aop;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; org.aopalliance.intercept.MethodInvocation;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; PojoAspect {&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; pojoAdvice() {&lt;br /&gt;        System.&lt;span style="color:#660e7a;font-style:italic;font-weight:bold;"&gt;out&lt;/span&gt;.println(&lt;span style="color:#008000;font-weight:bold;"&gt;"PojoAspect.pojoAdvice()"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="spring-config.xml"&gt;spring-config.xml&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#0000ff;font-weight:bold;"&gt;&amp;lt;?xml&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;version=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"1.0"&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;encoding=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"UTF-8"&lt;/span&gt;&lt;span style="color:#0000ff;font-weight:bold;"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;xmlns=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;font-weight:bold;"&gt;xmlns:xsi=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;font-weight:bold;"&gt;xmlns:context=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"http://www.springframework.org/schema/context"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;font-weight:bold;"&gt;xmlns:aop=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"http://www.springframework.org/schema/aop"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;font-weight:bold;"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"&lt;br /&gt;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&lt;/span&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;context:component-scan&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;base-package=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"com.spring.example.aop"&lt;/span&gt;/&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;id=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"methodInterceptor"&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;class=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"com.spring.example.aop.AopMethodInterceptor"&lt;/span&gt;/&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;id=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"pojoAspect"&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;class=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"com.spring.example.aop.PojoAspect"&lt;/span&gt;/&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;aop:advisor&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;advice-ref=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"methodInterceptor"&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;pointcut=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"execution(* com.spring.example.aop.AopService.*(..))"&lt;/span&gt;/&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;/aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;aop:aspect&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;ref=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"pojoAspect"&lt;/span&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;aop:before&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;method=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"pojoAdvice"&lt;/span&gt; &lt;span style="color:#0000ff;font-weight:bold;"&gt;pointcut=&lt;/span&gt;&lt;span style="color:#008000;font-weight:bold;"&gt;"execution(* com.spring.example.aop.AopService.*(..))"&lt;/span&gt;/&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;/aop:aspect&lt;/span&gt;&amp;gt;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;/aop:config&lt;/span&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;&amp;lt;/beans&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a name="SpringStart"&gt;SpringStart.java&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;Driver class:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; com.spring.example;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; org.springframework.context.support.ClassPathXmlApplicationContext;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;import&lt;/span&gt; com.spring.example.aop.AopService;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt; SpringStart {&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;public&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;static&lt;/span&gt; &lt;span style="color:#000080;font-weight:bold;"&gt;void&lt;/span&gt; main(String[] args) {&lt;br /&gt;        ClassPathXmlApplicationContext context = &lt;span style="color:#000080;font-weight:bold;"&gt;new&lt;/span&gt; ClassPathXmlApplicationContext(&lt;span style="color:#008000;font-weight:bold;"&gt;"spring-config.xml"&lt;/span&gt;);&lt;br /&gt;        context.getBean(AopService.&lt;span style="color:#000080;font-weight:bold;"&gt;class&lt;/span&gt;).test();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We get the following result if we run the example:&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="xml" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;AopMethodInterceptor.invoke()&lt;br /&gt;PojoAspect.pojoAdvice()&lt;br /&gt;AopService.test()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;I.e. all spring1-based aspects are successfully intergrated with aspectj + aop scheme configuration approach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5682856111471502603-4182709495967623223?l=denis-zhdanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://denis-zhdanov.blogspot.com/feeds/4182709495967623223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4182709495967623223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5682856111471502603/posts/default/4182709495967623223'/><link rel='alternate' type='text/html' href='http://denis-zhdanov.blogspot.com/2010/01/spring1-and-spring2-aop.html' title='Spring1 and Spring2 AOP interoperability'/><author><name>Denis Zhdanov</name><uri>http://www.blogger.com/profile/16234838916421473871</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_wBtqK4BXFZc/SgFpIUqjawI/AAAAAAAAAAM/GIa7zVMq2ms/s1600-R/IMG_3225.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5682856111471502603.post-5915307106098802843</id><published>2010-01-05T23:01:00.007+03:00</published><updated>2010-01-15T12:56:38.680+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projecteuler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ProjectEuler - introduction and problem1</title><content type='html'>I'm really interested in &lt;a href="http://www.scala-lang.org/"&gt;Scala programming language&lt;/a&gt; - functional/imperative language hybrid executed under JVM. I believe that you can get relevant knowledge with something only if you have a good experience with it, hence, I need to use Scala in order to get know it. &lt;br /&gt;&lt;br /&gt;I was pointed to the fun resource with various tasks that are interesting to solve - &lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt;. It looks like a perfect playground for Scala exploration, so, I'm starting series of posts that show how projecteuler tasks are solved using Scala.&lt;br /&gt;&lt;br /&gt;Here is the first task:&lt;br /&gt;&lt;blockquote style="background-color: #f3f5e9; border: 1px solid; padding: 5px;"&gt;&lt;br /&gt;If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.&lt;br /&gt;&lt;br /&gt;Find the sum of all the multiples of 3 or 5 below 1000.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Well, the task may be solved via simple brute-force approach:&lt;br /&gt;&lt;br /&gt;        &lt;div style="border:1px inset;padding:2%;"&gt;&lt;div class="view"&gt;&lt;pre class="java" style="height:100%;overflow:auto;background-color:white;margin:0;padding:6px;"&gt;&lt;br /&gt;&lt;span style="color:#000080;font-weight:bold;"&gt;package&lt;/span&gt; net.projecteuler.p1&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;font-style:italic;"&gt;/**&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@author&lt;/span&gt; Denis Zhdanov&lt;br /&gt; * &lt;span style="color:#808080;font-style:italic;text-decoration:underline;font-weight:bold;"&gt;@since&lt;/span&gt; Jan 5, 2010&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;object P1 &lt;span style="color:#000080;font-weight:bold;"&gt;extends&lt;/span&gt; Application {&lt;br /&gt;    var sum = 0L;&lt;br /&gt;    &lt;span style="color:#000080;font-weight:bold;"&gt;for&lt;/span&gt; (&lt;br /&gt;        i &amp;lt;- 1 until 1000&lt;br /&gt;        &lt;span style="color:#000080;font-weight:bold;"&gt;if&lt;/span&gt; (i % 3 == 0 || i % 5 == 0)&lt;br /&gt;    ) sum += i&lt;br /&gt;    println(sum)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;    &lt;br /&gt;It's easy to see that the answer is found quite quickly bu
