logo

Java: Custom Address Class to Check for Duplicates

My adventures as a "proper" programmer continue apace. Yesterday I created a custom class in Java that implements the Comparable interface and now feel quite smug about it. Probably undeservedly so.

I was writing a Domino-based reporting Agent in Java which need to loop a set of invoice documents for a given user and report back a sorted list of each unique billing addresses they'd supplied over the years, so that a data audit could take place.

Here's the use case code for the class:

ArrayList addresses = new ArrayList();

Document d = dc.getFirstDocument();
    
while (null!=d){
    BillingAddress address = new BillingAddress();
                        
    address.setAddress("AddressLine1");
    address.setTown(d.getItemValueString("AddressTown"));
    address.setCounty(d.getItemValueString("AddressCounty"));
    address.setPostCode(d.getItemValueString("AddressPostCode"));
              
    //Make sure the address is isn't in the array.          
    if(!addresses.contains(address)){
        addresses.add(address);
    }
                        
    d = dc.getNextDocument(d);
}

//Sort our addresses before output
Collections.sort(addresses);

//For each address convert to HTML string.
for (int i=0; i<addresses.size(); i++){
    _html+=("<p>"+((BillingAddress)addresses.get(i)).toString().replace("\\n", "<br/>")+"</p>");
}

As you can see I'm able to check whether a BillingAddress is already in the ArrayList and I'm able to sort them. The former is due to the existence of the equals() method in the class and the latter because of the compareTo() method.

Here's the class itself:

public class BillingAddress implements Comparable {

    private String _address;
    private String _town;
    private String _county;
    private String _postCode;
    
    
    public int compareTo(Object address) throws ClassCastException {
        if (!(address instanceof BillingAddress))
              throw new ClassCastException("A BillingAddress object expected.");
            
        return (_address.compareTo(
                ((BillingAddress)address).getAddress()
            ));
    }
    
    public boolean equals(BillingAddress address){
        return (
            address!=null &&
            address.getAddress().equalsIgnoreCase(_address) &&
            address.getPostCode().equalsIgnoreCase(_postCode)
        );
    }

    public void setAddress(String address){
        _address = address;
    }
    
    public String getAddress(){
        return _address;
    }
    
    public void setTown(String town){
        _town = town;
    }
    
    public String getTown(){
        return _town;
    }
    
    public void setCounty(String county){
        _county = county;
    }
    
    public String getCounty(){
        return _county;
    }
        
    public void setPostCode(String postCode){
        _postCode = postCode;
    }
        
    public String getPostCode(){
        return _postCode;
    }
    
    public String toString(){
        String out = "<p>";
        if (!_address.equals("")){
            out+=_address+"\n";
        }
        if (!_town.equals("")){
            out+=_town+"\n";
        }
        if (!_county.equals("")){
            out+=_county+"\n";
        }
        if (!_postCode.equals("")){
            out+=_postCode;
        }
        return out;
    }

}

Inside the equals() method you can see I've deemed any address where the first line and the post code (ZIP) match to be the same. Whether this holds true or not I don't know yet. But it's easy to change this logic. As is the case for changing how the compareTo() method sorts your addresses. You could choose to sort by Town/City or Post Code rather than by the first line. It's all up to you.

As you can probably tell I'm writing the code in Java 1.3 (ouch!) because the client is still on Domino 6.5.5 (double ouch!!). If you were using a later version of Java you could make the above code a lot simpler, but the theory still holds true and the principles are the same.

Comments

    • avatar
    • ChrisC
    • Wed 14 Dec 2011 04:16 AM

    Very nice Jake...sure we can't tempt you over to the XPages world yet?

    1. It's not really about being tempted (which I'm not really) it's all about work (money!). When a customer asks me to write them a web app and specifies it must be done in Xpages, then I'll be tempted (forced!) to. The chances of it happening are fairly remote though.

      Show the rest of this thread

  1. As you do not recycle you should check memory consumption at the server if you iterate over a large collection.

    Most parts of the code would fit well into an XPages environment too but a 6.5.5 customer would not benefit from an XPage solution anyway.

    In my dreams IBM enhanced the "classic" application approach so that old ugly applications automatically become nice looking modern GUI applications that work on both the web and a client simple by upgrading the server and starting the design task on a database level.

    That would mean enormous potential for customers that already said good-bye to Notes and Domino a long time ago but still keep it running. There are thousands of former customers falling into this category.

    1. Spot on. XPages is a solution in search of a problem. Most Domino application environments have been left on minimal life support for very good reasons. Since an XPages migration is effectively a total rewrite, it has little or no advantage over migrating to any other platform - especially one that might be cheaper, more robust, more open, better documented or more widely adopted. This is why XPages deployments are few and far between and developer interest and market demand for those skills is near non-existent.

      Show the rest of this thread

      • avatar
      • axel
      • Wed 14 Dec 2011 11:19 AM

      You should better use:

      [code]

      Document oldOne = d;

      d = dc.getNextDocument(d);

      oldOne.recycle();

      }

      [/code]

      Way much saver, when you iterate over a larger collection of Domino Objects.

  2. If you use a TreeSet instead of an ArrayList, you don't have to check for duplicates and you don't have to sort the collection.

    1. Are TreeSets in Java 1.3?

      How do they know if an object based on a custom class is already in them?

      How do they manage custom sorting?

      Show the rest of this thread

  3. Thanks Jake, I always like to see other peoples code samples to see how they use a language feature.

    Two questions.

    Does/can the post office provide address verification as a service or Database and API?

    Also, does this customer have less than a thousand seats?

    If so, sounds like a really good candidate to switch to express server licensing and upgrade in an incremental manner.

    1. Hi Wayne,

      1. I'd be surprised if it didn't.

      2. No.

      Jake

    2. Is express server licensing even available any more? Last I heard, big blue had gone to a 'one size fits all (we care about)' model... no more foundations, no more express.... maybe I totally misunderstood (hopefully so - both express and foundations were great ideas for small biz).

      Show the rest of this thread

  4. You could also use Session.evaluate() with @sort and @unique

    1. Now, come on Bob, that's hardly going to make me a better developer and prepare for a world without Domino is it?! ;-)

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Wed 14 Dec 2011

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content