Coding in the small with Google Collections: Objects.equal and hashCode

Part 4 in a Series. Objects.equal(Object,Object) and Objects.hashCode(Object...) provide built-in null-handling, which makes implementing your own equals() and hashCode() methods easy. Before: public boolean equals(Object o) { if (o instanceof Order) { Order that = (Order)o; return (address != null ? address.equals(that.address) : that.address == null)…

Coding in the small with Google Collections: Comparators.max

Part 3 in a Series. Comparators.max takes two Comparables and returns the larger of the two. It improves upon the standard approach, which requires both a comparison and a ternary: Before: public Money calculateDeliveryCharge(Order order) { double distanceInKm = Geography.getDistance( storeAddress, order.getAddress()); Money perKm = pricePerKm.times(distanceInKm); _return…

Coding in the small with Google Collections: Iterables.getOnlyElement

Part 2 in a Series. Iterables.getOnlyElement makes sure your collection or iterable contains exactly one element, and returns that. If it contains 0 or 2+ elements, it throws a RuntimeException. This comes up often in unit tests: Before: public void testWorkSchedule() { workSchedule.scheduleUserOnDuty(jesse, mondayAt430pm, mondayAt1130pm); Set<…

Coding in the small with Google Collections: Preconditions

Part 1 in a Series. In this N-part series, I'll demonstrate my favourite APIs from the recently announced Google Collections project. I'll present before and after examples that show how you can use Google Collections to write more concise code. Preconditions provides methods for state validation. It makes input validation…

ListDeltas and the next generation of observable lists

Yesterday afternoon I had a great technical discussion with Joshua Bloch, a very highly respected API designer. We met to talk about something that's very close to my heart, observable lists. We explored this problem with a whiteboard and some code samples and came up with some interesting observations... 1.…

Seeking feedback: ListEvent, ListEventBuilder APIs

As of today, beansbinding does a very lightweight approach to observable lists. There's two interfaces, ObservableList.java and ObservableListListener.java. I'm refining a proposal for a more heavyweight approach. In addition to simplified List and Listener interfaces, I add a ListEvent interface and a ListEventBuilder class. Motivation for these interfaces:…

Use Shift+Enter for multiline text in Gmail Chat

My IM client at work is the Google Talk widget that's built-in to Gmail. It works okay, but it's annoying for typing code snippets into chats. Code snippets require multiple lines of text, but pressing Enter commits the message. How to send a multi-line message? Well today I accidentally discovered…

Properties should be stateless to avoid memory leaks

In the latest rev of beansbinding, the AbstractProperty class is stateful. This means that when you add a listener to an object, the property independently remembers both. For example, suppose your code uses databinding in a dialog: private static final Property<jtextfield,string> textFieldTextProperty = new BeanProperty&lt;…

Chaining Stateless Properties

In a recent post, I described how I implemented the observers for stateless properties. In this follow up I describe how to do observers for chained properties. What's a chained property? Suppose I'd like to bind a combo box to a customer's country. If the Customer bean has a getCountry(…

Implementing Observers with Stateless Properties

I've got a simplified Property interface and a mixin that makes the property observable: public interface Property&lt;B,V&gt; { V get(B bean); void set(B bean, V value); } public interface ObservableProperty&lt;B,V&gt; extends Property &lt;B,V&gt;…

Stop Writing Redundant Javadoc

I keep seeing this exact same Javadoc being written over and over again: /** * A pizza delivery. * * @author jessewilson */ public class PizzaDelivery { ... /** * Sets the address of this PizzaDelivery. * * @param address the address to set. */ public void setAddress(Address address) { ... } } Naturally, this doc took the code author time to write. He typed…

Returning boolean isn't always that helpful

In complex systems, transparency can sometimes help. In my fake pizzastore application, I've got an API that's used to control whether the Place Order! button is enabled or disabled: public boolean isOrderValid(PizzaOrder pizzaOrder) { if (!geography.isAcceptableAddress(pizzaOrder.getAddress())) { return false; } if (!deliveryRules.isLargeEnoughOrder(pizzaOrder)) { return false; } List&lt;…

Your mind is a terrible profiler

Today I found the following interface while doing a code review: interface DeliveryListener { void deliveryFulfilled(Delivery delivery); void deliveriesFulfilled(Set&lt;Delivery&gt; deliveries); } This code offends me because the first interface method is a special case of the second method. Why not just use a singleton list!…

Review: Toshiba HD-A20 1080p HD-DVD Player

When I bought my HDTV in February, I paid extra for 1080p so I could brag about having a higher resolution than my friends who all have 1080i TVs. But my ability to brag was theoretical until I could plug in a source that produced a 1080p signal. Naturally, that…

Refactoring to Guice: Part 3 of N

In Part 1 and Part 2, I removed several static calls in my pizza program. The services class now benefits from an object-oriented design. Replacing static with non-static methods allows for polymorphism and that helps in testing: public class PizzaServices { private final Oven currentOven; private final Address storeAddress; private final…

Living APIs: Part 1 of N

Writing APIs is hard. There's several factors to balance and it's difficult to get it right the first time. Fortunately, often we don't! We're not all writing code for the JDK, where bad APIs can never be removed in order to retain strict compatibility. Most of the APIs I write…

Find the RSS Feed for any blog!

Most blogging tools like Blogger include an secret link to the page feed in your published HTML. You can only see it by viewing the HTML source of a blog page: &lt;html&gt; &lt;head&gt; &lt;meta http-equiv="Content-Type" content="…

Beans binding is getting simpler and better

I've kind of had a love-hate attitude towards the JSR-295 Beansbinding project: love: observable lists in the JDK hate: the observable lists' events are [not fine-grained](http://publicobject.com/2006/06/fine-grained-events-for-performance.html) love: binding in the JDK hate: [it requires EL](http://weblogs.java.net/blog/forax/archive/2007/…

Refactoring to Guice: Part 2 of N

In Part 1, I removed some of the static calls in my pizza program, leaving me with this code. It still has several static calls that interfere with testability: public class PizzaServices { private final Oven currentOven; @Inject public PizzaServices(Oven currentOven) { this.currentOven = currentOven; } public Order createOrder(List&lt;…

Refactoring to Guice: Part 1 of N

In this N-part series, I'm attempting to document some patterns for improving your code with Guice. In each example, I'll start with sample code, explain what I don't like about it, and then show how I clean it up. The bad code They're everywhere! Static utility methods that depend on…

Language Expressiveness and Complexity

Recently I've seen comments about how language complexity is a Bad Thing that Must Be Avoided. I disagree. The expressiveness of a language influences what you can say with it. This applies to natural languages, programming languages, even programming APIs! When the language gets more complex (by adding new words…

Properties would work nicely with First-class methods

First-class methods (FCM) is a compelling proposal to enhance the Java language so that methods, fields and constructors can have full type-safety. In today's Java, we write this: Method getter = Action.class.getDeclaredMethod("isEnabled", new Class[] { }); Method setter = Action.class.getDeclaredMethod("setEnabled", new Class[] { boolean.class…

Modelling Properties in Java

We're having a properties discussion over on the beansbinding (JSR-295) mailing list. Here's a recent revision of the API: /** * Models the relationship between two related types, such as * the address of a customer or the size of a List. * * &lt;p&gt;A property is not bound to…

Thoughts on Java as the configuration language for Guice

Google Guice uses plain old Java code as the configuration code. For example, here's the code that sets up my fictional pizza store management application: public class PizzaOrdering implements Module { public void configure(Binder binder) { // tell Guice that whenever the code needs an implementation of // my CallInOrderHandler interface, the WebCallInOrderHandler…

AssistedInject, an easier way to help the Guice Injector build objects

Frequently on my team we have a class that gets some of its constructor parameters from the Guice Injector and others from the caller: public class RealPayment implements Payment { public RealPayment( CreditService creditService, // from the [Injector](http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Injector.html) AuthService authService,…

Why dreamhost.com rules for domain hosting

I pay a cheap annual fee - $97/year - to host publicobject.com, swank.ca and some others at Dreamhost. Today I went to publicobject.com and the site was down. I checked the usual suspects: did I let my domain registration expire? is DNS set up correctly by…

Java language tweak: protected switch

I have an enumerated type, and it's possible that I'll be adding more values in the future. public enum Office { CALGARY, REGINA, TORONTO, BERLIN; }`</pre> Somewhere in the code, I switch on this type: <pre>`public CurrencyCode getCurrencyForPayingEmployees(Office office) { switch(office) { case CALGARY: case REGINA:…

Cory Doctorow's Overclocked in Podcast form

Today Cory Doctorow gave a tech talk to my company. He talked about how DRM is a wasted effort and how it's important that we don't bake-it-in to the technology that we build. So this evening I decided to look for Cory's Overclocked book in audiobook form. Unfortunately, I couldn't…

A fun problem: IndexedValues

This is a fun problem - how would you implement it? public interface IndexedValues&lt;V&gt; { /** * Inserts the specified value at the specified index. The same * value may be inserted several times in the same collection. */ void insert(int index, V value); /** * Returns the index of the…

Audiobook Builder: it just works

I recently subscribed to Simply Audiobooks, which is a Netflix-like service that rents books-on-CD through the mail. I listen to them unabridged so each book spans several CDs - 12 CDs for a single book is typical. Unfortunately, iTunes doesn't handle Audiobooks-from-CD nearly as well as it handles music or…

Glazed Lists talk at JavaOne: Friday at 2:50pm

Details on our Glazed Lists tech session: Sexy Models! An API for Declarative Data Models on the Desktop Session TS-3057, desktop track Friday May 11 at 14:50 in Hall E - 135 We're planning on writing code live during the session to show off how productive Glazed Lists is.…

A helper method for unit testing Comparators

For the poker game I'm not writing, I wrote a Comparator to rank the player's hands. Now to write a unit tests for that Comparator. Generally I find that it's hard to write test cases for Comparators. You end up having to puzzle over whether to use &lt; 0…

A PDF Printer for Mac OS X

Some applications don't use the built-in print dialog on Mac OS X, which usually means no PDF printing. Fortunately, some kind soul has created a PDF printer that is easily installed on Mac OS X. Its mechanics are similar to PDF 995 for Windows: install the virtual printer print a…

Subversion and case-insensitive filesystems

My Mac's filesystem is case-insensitive. It thinks Foo and foo are the same file. Subversion's filesystem is case-sensitive. It thinks Foo and foo are different files. As you can imagine, this mismatch has hilarious consequences. If your repository contains a directory with both Foo and foo, then svn crashes hard…

CodeSearch-Plugin M9

Today's update is pretty sparse - I cleaned up the new intersect & union features so that you can kick off a new query to intersect and union against. I also drew up some custom icons for union and intersection. My next tasks include a lot of polishing: making the…

Debugging HTTP? Get Charles

Charles is an amazing tool that every web developer should have in their toolchest. It records the HTTP conversations between your browser and the web and lets you analyze them. It can even record HTTPS conversations and remove the encryption. Some questions that Charles will quickly answer: what cookies are…

CodeSearch-Plugin M8

Today's update of CodeSearch-Plugin allows you to intersect the results of one query with another query. This allows you to search for code that contains both spline and Graphics2D, neither of which is particularly useful on its own. I've also fixed the preflight dialog's handling of ENTER etc., which was…

CodeSearch-Plugin M7

The newest CodeSearch-Plugin remembers what you searched for last time (including file-types & case-sensitivity), so you can search for it again. Unfortunately, this version has an unfortunate bug - when you change and then tab out of any of the text fields, it tends to kick off your query early.…

CodeSearch-Plugin M6

CodeSearch-Plugin now has options in the preflight search dialog to select the Google Code Search filetype and package. For command line search, you can now add extra arguments from the preflight dialog. I've also fixed the renderers so that the filename shows up on the left, and its path on…

CodeSearch-Plugin M5

I've made 2 new updates to the CodeSearch-Plugin. Multiple tabs Expand All, Collapse All, Next, Previous buttons I've also come up with a very interesting feature - 'Intersect With' to combine multiple searches in an interesting way.…

CodeSearch-Plugin M4

I've added some fixes to my codesearch-plugin project: whole words only, a convenient way to focus your regex search field is populated with the selected text search terms are remembered settings are application-wide You can install the plugin right in IntelliJ - instructions are here.…

Upcoming Glazed Lists talks

James and myself will be giving a couple talks on Glazed Lists over the next couple months. I'm very excited about the opportunity, but I'm also nervous - doing a good talk is a lot of work! We'll be talking at Desktop Matters on Friday March 9. This is a…

JDiff - a great tool for managing API changes

Today I was working on upgrading our test infrastructure to the latest EasyMock. Since we've got lots of tests that make extensive use of EasyMock, I needed a tool to give me a 'heads up' on the potential pr_screenshot-788324.png)](/uploaded_images/jdiff_screenshot-796848.png) JDiff is just that…

CodeSearch-Plugin M3

I've fixed a bunch of bugs in the CodeSearch-Plugin: the plugin won't reopen the same file multiple times the plugin allows you to open local project files from the search results (via a right click) the plugin now works if you have multiple projects open in IntelliJ there's now a…

Tagsoup: An easy API for parsing HTML in Java

I needed an API to convert sourcecode embedded in HTML (example) into plain text. I needed to keep track of where the <pre> tags start and stop, plus extra stuff for my parsing heuristic. The Java API I chose for this task is Tagsoup and I'm very impressed.…

CodeSearch-Plugin M2

Development on the [CodeSearch-Plugin](http://code.google.com/p/codesearch-pluginarch_config-719177.png)](/uploaded_images/codesearch_config-722430.png) I've added a CommandLine Search source so custom search providers can be added. The process of setting this up is still a bit intimidating since it requires you write a regex that can…

Why Moo.com sucks

I just spend 45 minutes trying to create some funky business card-sized prints of flickr photos on MOO. Very slow AJAX The site uses heavy amounts of Ajax to do in-browser selection and cropping. It looks very pretty. But it's ridiculously slow. Their minimum batch is 100 photos, and it…

CodeSearch-Plugin

I've finally uploaded a first draft of my CodeSearch-plugin to the project website. It's full of bugs but if you'd like to take it for a spin, you can download it here.…

Extensible Properties for the JVM, refined

Remi and Richard are talking about properties again, refining their ideas. I figured I should organize my thoughts as well. FIrst off, how about some aggressive requirements: Properties should support arbitrary implementations! It should be possible to have properties backed by fields, HashMaps, databases, calculations, devices etcetera. Using such a…