OU blog

Personal Blogs

Attachments:
text/plainClipboard.pde
ExLibris

Cliboard for Processing sketch

Visible to anyone in the world
Edited by Martin Thomas Humby, Saturday, 7 Jun 2014, 18:27

Giving a sketch copy and paste capability allows sequential copy and save to a graphics application (Photoshop, Paint.NET are suitable) and reverting back to an earlier version by pasting it into the sketch.

Clipboard images

As show an image can also be produced using two separate sketches.

The attached file provides a template. Simply place the Java library imports at the top of your sketch and past in the rest of the clipboard code at the end.

Permalink Add your comment
Share post
ExLibris

Higgs boson

Visible to anyone in the world
Edited by Martin Thomas Humby, Sunday, 9 Feb 2014, 17:57

Last chance to sign up for the 'The discovery of the Higgs boson' , now includes Relativity and Quantum Mechanics, Quantum Electrodynamics, Quantum Chromodynamics and the Standard Model it says. Maybe I will not need to do SMT359, S383, SM358 after all.

big grin

Permalink
Share post
ExLibris

Monty Hall

Visible to anyone in the world
Edited by Martin Thomas Humby, Friday, 12 Jul 2013, 22:02

Spent some time with this as recreation from AI Class. Now see by drawing a probability diagram the 2/3 chance of winning for swappers is obvious:

Monty Hall

Set swap-probability x to 1 and there is a 2/3 chance of winning the car.

With swap-probability 1/2 and there is a 1/2 chance of winning.

 

p.s. for posterity: the only comprehensive description of Bayes Ball I found at the time was in these slides nos. 21, 22, 23.

Permalink
Share post
ExLibris

Breaking the Silence on MST121 TMA01

Visible to anyone in the world
Edited by Martin Thomas Humby, Sunday, 24 Nov 2013, 16:16

As I found out to the cost of two or three marks on Question 5(A)(i) you have to do the scalings and translations in a particular order specified by the OU, an order that makes it as hard as possible to understand what is going on - the whole purpose of the exercise one might have thought.

The optimum solution understanding-wise is to apply the y translation first to get some x intercepts but if you do so it cannot be the one you want. What is all this about I wondered. Think I've got it but its still fairly amazing:

Consider a function, not the one in the question in case discussion is still off limits, Exercise Book A, Chapter A3, Exercise 2.3 (a), after completing the square we get:

f of x equals three left parenthesis x plus three times right parenthesis squared minus 12 full stop

Start with the basic parabola, y = x2 Fig (i).

 

Apply the y translation, y = x2 - 12 Fig (ii). The 'apex', 'minium', 'origin' of the curve moves down to (0, -12). Now we have some x intercepts.

Because the curve is descending and then ascending at a rate of x2 for every x, the coresponding y manages to get from zero to -12 in √12 units of x and back up again in another √12 units. The x intercepts are at ± root 12.

 

Graphs i/ii

Now apply the y scaling. We do this about where the 'apex', 'minium', 'origin' of where the curve is now, not about where it was before the translation Fig (iii).

With the scaling x2 is changing three times faster. Now y changes from zero to -12 for for an increase of only √12 / √3 units of x. The x intercepts are at +|- √12 / √3 which is √3√4 / √3 = √4 = ± 2, as can be seen from the graph.

If the scaling was ½ or some other factor in (0, 1) this would increase the change in x needed to get from zero to -12 but we still divide by the square root of the scale factor, less than one, and ½ x2 -12 comes out as √12 / √½ = √12√2 = 2√3.√2, not such a happy calculation.

Now we know where the intercepts are at ± 2, applying the x translation simply moves everything left by 3 units . The intercepts are at -2-3 = -5, 2-3 = -1 and the apex is at (-3, -12) Fig (iv).

 

Graphs iii/iv

Adding 3 to x inside the function makes the value submitted to the squaring three units more for any x submitted to the function itself: the x we are plotting on the graph.

Finished! No need to solve any equation, but this is too easy apparently. Solving the equation is compulsory because you are not allowed to do it by thinking.

A strategy for success

Be warned: thinking may be a 'bad thing' to do on MST121. All you had to do in this question it seems, was identify the scaling and translations and write them down in the specified order.

Scaling first is safest: a y scaling with factor 3, a horizontal translation by 3 units to the left, a vertical translation by 12 units downwards. We could do the horizontal translation first because even under OU rules a translation in the x direction has no effect on a subsequent y scaling and similarly for a y translation and an x scaling.

The TMA question asked 'Explain how the parabola that is the graph of f can be obtained from the graph of y = x2'. Personally I wouldn't class such a list as an explanation but it is all that is expected it seems, making it the sum total of what we need to know.

Having already completed the square all that is needed to find the intercepts is to solve the equation in completed square form

3(x + 3)2 - 12 = 0; (x + 3)2 = 4; x + 3 = +|- 2; x = -1 or x = -5

but, looking at the solution to Exercise 2.3 (a), even this was too easy a way.

The mystery revealed

So, what are the OU on about translation and scaling wise? A polite explanation: while translation results in linear modification of coordinates, scaling (and rotation) takes place about an origin. The further a point is from that origin the greater the effect. Consider a y scaling factor of 3 applied to a point (1, 1): after scaling the point ends up at (1, 3), a displacement of 2 units. A point already at (1, 3) ends up at (1, 9) a displacement of 8 units. The scaling has no effect on a point at (0, 0) or (1, 0) for a y scaling. These points remain where they are. If the translation is done first and its origin relocated the scaling must still be applied about the global origin, or so says the OU. The result is a function

f of x equals three left parenthesis open x plus three times right parenthesis squared minus 12 close full stop

Where my concept of scaling and the OU's differed (and still does) relates to the possibility of a local origin, in this case the point on the curve where it passed through the global origin before any translations. I am certainly not alone here - the process for scaling or rotating a curve (or anything else) with global coordinates about a point other than the global origin is known as 'translation to the origin', and back again after the scaling or rotation has been done.

We can look at this in two ways: either the centre of scaling/rotation is moved to the global origin taking all points on the curve with it by subtracting the global x y offsets of the centre from their coordinates or we can view the same process as translating the points into a new frame of reference with the centre as its origin, the result is the same and an inverse translation must be applied to get back to the same frame of reference as before.

Come on OU, if this possibility is excluded Lara Croft would never be able to turn around. If she tried to do so she would simply precess in an arc about image (0, 0, 0) and if she turned 180 degrees would end up off-screen in the universe of negative offsets. With regard to scaling, as she moved away from image-origin the heaving of her decolletage would become ever more spectacular - quite spectacular enough as it is I think.

(In fact Lara will have her own local origin and a set of numerous other local origins about which she can rotate or scale parts of her anatomy as required: quoting her here is for illustrative purposes only)

 

So, MST121 is (again) presenting a very limited view, in relation to translation and scaling this time. What I would like to know is where in the 'Chapters' is there any explanation of this view, perhaps similar to my one paragraph explanation above.

The diagrams were done with a quick program I wrote to investigate the effect of changing constant values in a function. Bit late now but I will post it on the Chat forum shortly in case anyone else would like to give it a try:
Sin + Cos     Martins map
sin + cos : th = -2...2pi, a = 1, b = 1, c = 1, d = 1, e = 1, f = 1, n = 3
   
Martin's Map : x = 2 1/2, y = 3, a = 988/1000, b = 1 234/1000, r = 37
Permalink 2 comments (latest comment by Martin Thomas Humby, Tuesday, 7 May 2013, 14:27)
Share post
ExLibris

Java assertions

Visible to anyone in the world
Edited by Martin Thomas Humby, Sunday, 9 Feb 2014, 18:01

Java Assertions

Assertions are one of the most useful debugging tools around but from what I have seen using them may not be common Java practice. There are several probable reasons for this:

  • assertions came late on the scene only being added to the language in J2SE 1.4.

  • control over assertions is a function of a JVM switch not a compiler option. This means that generated code for asserts is included in a deploy build whether or not it is required. (there are ways around this: [jGuru] [Java.net], but nothing particularly inviting unless you want to make your code look like something out of the C++ STL)

  • Java provides a detailed but comprehensible stack trace when an exception is thrown making error root cause much easier to identify than in some other languages, at least until comparatively recently.

A Java assertion has the form

assert <boolean expression> : <problem>;

with the : <problem> part being optional. If the boolean evaluates to false and the JVM -ea switch is set a java.lang.AssertionError is thrown with <problem> as its message. <problem> is an expression that evaluates to anything other than void, generally a String.

To set assertions on in NetBeans, right click on the project node and select Properties. Choose Run from the tree and type -ea in the VM Options edit. Alternatively you can click [Customize] and check ea in the list. warning: running from NetBeans part of an AssertionError message may be missing in the output window.

 

Assertions allow preconditions, post-conditions and invariants to be checked by code that is optionally executed by the JVM bringing these aspects of formal methods (basically VDM) into as-coded reality. Java method specifications are referred to as contracts making contract verification seem quite appropriate. The Java article [here] provides a comprehensive review.

For example: if n < 0, the Math.squrt(n) function returns a Not a Number (NAN) without throwing an exception. NANs have some fairly strange and probably unwanted characteristics when used in computations so we could write our own square root that checks for this problem:

     public static double asqrt(double n) {

        // pre-condition
        assert (n >= 0) : n + ": no real sqrt";

        return Math.sqrt(n);
    }

NetBeans is not clever enough to include the -ea option in its suggested command-line invocation. It must be inserted by hand to run an app. with assertions from a terminal window e.g:

F:\>java -jar -ea "F:\PROGRAMMING PROJECTS\NetBeans\Tests\Assert Test\dist\Asser
t Test.jar
Exception in thread "main" java.lang.AssertionError: -1.0: no real sqrt
        at pkgassert.test.Asserts.asqrt(Asserts.java:14)
        at pkgassert.test.AssertTest.main(AssertTest.java:17)

F:\>

When turned off in the JVM assertions get no runtime overhead apart from a conjectured increase in the time taken to load bigger classes. Admittedly control over their execution is not all it might be but for a small fee and given maybe a day to make it look pretty, I could write a Delphi GUI app. providing navigation to a project directory or to any sub-directory or file that would walk the file tree and strip or remark out assert statements in any java files encountered. Wonder why the Java gurus haven't produced a Java app. to do just that?

Permalink 2 comments (latest comment by Martin Thomas Humby, Sunday, 25 Sep 2011, 17:20)
Share post
ExLibris

Very Basic

Visible to anyone in the world
Edited by Martin Thomas Humby, Monday, 22 Aug 2011, 17:53

Summary

from http://www.developerfusion.com

rekessss (0 replies) just about sums it all up methinks.

 

Permalink
Share post
ExLibris

Text formatting and Tables for OU bloggers

Visible to anyone in the world
Edited by Martin Thomas Humby, Saturday, 7 Jun 2014, 13:15

Blogging indents

As far as blog facilities go the OU blog is about average and is easier to use than some. However one problem is trying to format text to get a neat presentation of facts by indentation or tables. Even if like me you have some knowledge of HTML many tags get stripped out when a blog is saved but there are a few relevant ones that do not. There is a neat way to indent paragraphs by any desired amount for example. Suppose we have paragraphs:

She sells sea shells

On the sea shore.

Perhaps an indent of half an inch (12.5mm) looks better for 'On the sea shore.' Simply type the lines in as above and open the HTML editor (the bleary blue HTML next to the preview icon). Find the lines

<p>She sells sea shells</p>

<p>On the sea shore.</p>

in the code and change the second line to:

<p class="western" style="margin-left: 0.5in;">On the sea shore.</p>

Or if the line was a heading in italics it would then be

<h3 class="western" style="margin-left: 0.5in;"><i>On the sea shore.</i></h3>

Headings, italics, bold, etc. can be applied or removed in the 'WYSIWYG' editor before or after applying the indentation.

The end result:

She sells sea shells

On the sea shore.

Blogging tables

The OU blog also accepts tables and making these is even easier because no HTML editing is required - unless you need to delete a table using the supplied editor that is. The downside is that it does not allow tables with lines but this is definitely better than nothing.

To use tables fire up your OpenOffice.org Writer (MS Word might also work but has not been tested). Type in required tables or the complete blog entry and save as Microsoft Word 97/2000/XP .doc format. Select all or individual tables / sections, Copy and paste into a Paste from Word box in the blog editor and click Insert.

When the blog is saved any lines in the table and column width data will be stripped out so there is no point in worrying about such features. Resulting spacings between columns are minimal but this problem can be fixed by inserting blank columns. An example looks like this in Writer:

Table in Writer

and displays in a blog thus:

Operating System

 

 

Commands

Ubuntu 8.04:

 

 

sudo /cdrom/VBoxLinuxAdditions.run

Ubuntu 10.04:

 

 

sudo /media/VBOXADDITIONS_4.0.6_71416/VBoxLinuxAdditions.run

 

 

 

 

Oracle Linux :

 

 

su

     

Password: <root password>

     

sh /media/VBOXADDITIONS_4.0.8_71778/VBoxLinuxAdditions.run

Text in the columns wraps to suit page width so the same technique can be used to get a reasonable looking list with sub headings.

Blogging pictures

A final point that may or may not be widely known among bloggers who post Visible to anyone in the world entries featuring pictures is that any graphics hosted on the OU site are in fact invisible to everyone in the world not logged-in to the OU. Currently the only way around this problem is to put graphics externally, with Google say, and insert a URL link in the document. Please fix this OU.

(this has now been fixed, apparently: thanks OU!)

Visible to anyone in the world:

Turkish cat

Turkish cat - Selçuk - my photo

Permalink 1 comment (latest comment by Jonathan Vernon, Friday, 27 May 2011, 08:12)
Share post
ExLibris

Equality of Java Objects

Visible to anyone in the world
Edited by Martin Thomas Humby, Friday, 3 Oct 2014, 15:27

Overriding equals() - a simple solution

Martin Humby 2010

Working with Java Persistence - TopLink and Hibernate, noticed that some of the entity classes generated from database tables by the IDE included an override of the equals(Object) method. Apparently there is some controversy in the Java world about how best to do this and seeing these classes reminded me of a fairly detailed look at this 'problem' from last year.

Opinions are divided into what could be called the Josh Bloch camp - using intanceof to admit objects with the same class and exclude unrelated objects, and the class-comparison camp doing much the same thing but with subtle differences. The vast majority of classes in the standard libraries that override equals use instanceof so we can call this the standard implementation.

In fact there is a trivial OOP solution to writing equals methods that allows further subclassing with or without a new equals that seems to overcome objections from either camp to the arrangement advocated by those of the opposing persuasion - the solution described here.

The original hope was that a way could be found to override equals() that would require no special provision in the superclass. This was found not to be the case but required modifications to the standard implementation are minimal - simply factoring off field comparisons to a separate method and calling this method against the equals() argument rather than the current object. Any possibility that subclasses may be needed appears to indicate use of the simple solution.

The equals() problem

Object's view of equality, no two objects are equal, can be got by comparing base addresses - same-address implies same-object. Otherwise fields, significant from the point of view of comparison, are tested for equality to find out whether two different objects represent the same data item. There is no difficulty in writing a method that compares significant fields when all the objects offered for comparison are the same class. When objects are of different classes things get a bit trickier.

There are three possible equality relationships a derived class can have with its superclass:

1.the subclass declares no new significant fields, does not override equals and instances can be compared with those of the superclass for field equivalence. Such subclasses may carry any number of additional fields that are not significant for determining equality.

2.the subclass declares zero or more new significant fields and overrides equals(): comparing instances with those of a superclass or vice versa always returns false.

3.the subclass declares new significant fields and overrides equals(): instances are comparable with superclass instances when the new fields supply a particular value set, generally nulls or some equivalent - not otherwise in which case comparison must always return false.

Another factor relevant to overriding equals() so it works according to plan is the so-called equals contract in Object JavaDoc. This is a definition of the view of equality that all overridden methods must comply with if the hashed data structures provided by the standard libraries are going to work to contract - a meta-contract if you like.

The most significant of these rules is symmetry: a.equals(b) == b.equals(a) must always be true. If objects comply with symmetry it is going to be fairly hard, although not impossible, to write an equals() that does not comply with transitivity for example. Transitivity problems generally relate to cumulative inaccuracies, which is bad news for comparing floating-point fields but these problems are - as they say, beyond the scope of this discussion.

In general the desirability for inheriting classes in a separate comparison set from an existing class rather than Object is to maintain assignability to references to a common superclass and/or to inherit superclass functionality. The problem dealt with here is that the standard implementation can cater for equality relationship (1) - all classes in the same comparison set, but not (2) - multiple comparison sets. Class-comparison can provide (2) but not (1). Nether can cope with (3).

Class names from a particular scenario are used in examples but the scenario is not described in detail. The resulting class hierarchy is shown below:

 
  Classes 1


DataItem has a type (1) equality relationship with RegisteredItem in the Red comparison set, RegionItem a type(2) or type (3) relationship. RgnDataItem has a type (1) relationship with RegionItem in a Green comparison set. Type (3) may be considered an unusual requirement but there can be advantages in implementing it when instances of all four classes are to be stored in the same hashed structure: a HashSet for example.

( Readers acquainted with the alternative equals() implementations may now like to skip forward to 'A simple solution'. Otherwise problems with these implementations are discussed below. )

equals() using instanceof

An equals() implementation for RegisteredItem using instanceof might be:

    @Override
public boolean equals(Object obj) {
if (this == obj) return true; // optional same-object check
if (obj instanceof RegisteredItem) {
final RegisteredItem other = (RegisteredItem) obj;
return (this.itemID == other.itemID &&
this.categoryID.equals(other.categoryID));
}
return false;
}

By making other final we can hope that the compiler will not allocate this local on the stack and generate the assignment but will use the now typechecked reference to obj instead. Otherwise how it works is straightforward: if obj is not null and a RegisteredItem, compare fields for equality, else return false: istanceof includes the not-null check. No provision is made for a situation where categoryID is null and if this field is null in an object submitted to the HashSet a NullPointerException will result.

 

Think an exception is probably in order when this object's categoryId field is null but if not and we want equals() to return true when itemIDs match and both categoryIds are null the return statement needs to be:

 return (this.itemID == other.itemID &&  ((this.categoryId == null) ? other.categoryId == null) : this.categoryId.equals(other.categoryId)));

RegisteredItems contain only the IDs and details of the server where full data is stored. Updates and new items arrive as ItemData instances carrying the full data set. A new ItemData is put into the HashSet where it remains until data is stored and it is replaced with a RegisteredItem.

When obj is an ItemData it is still a RegisteredItem so proceed as before. As a subclass ItemData inherits the equals() shown above. When this is an ItemData and obj is an RegisteredItem the inherited instanceof check will admit the RegisteredItem object. Using the standard implementation there is no problem, we can simply derive a new class without defining a new equals() and comparison complies with the symmetry requirement of the equals contract.

Note that the equals() method can be rearranged as below with the same effect:

    @Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof RegisteredItem))
return false;
final RegisteredItem other = (RegisteredItem) obj;
if (this.itemId != other.itemId)
return false;
return (this.categoryId.equals(other.categoryId));
}

An overridden hashCode method is also required for RegisteredItem and this can be got using NetBeans 6.x code completion. (Press Alt + Insert and select hashCode() from the list):

    @Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + (this.categoryID != null ?
this.categoryID.hashCode() : 0);
hash = 79 * hash + this.itemID;
return hash;
}

equals() using class-comparison

So why not use code completion to get the equals method for RegisteredItem? Doing this and deleting the redundant curly brackets that don't do a lot for clarity and can nearly double the height of the method, gets:

    @Override
public boolean equals1(Object obj) {
if (obj == null)
return false;
if (this.getClass() != obj.getClass())
return false;
final RegisteredItem other = (RegisteredItem) obj;
if ((this.categoryID == null) ? (other.categoryID != null) :
!this.categoryID.equals(other.categoryID))
return false;
if (this.itemID != other.itemID)
return false;
return true;
}

This is the class-comparison approach, quite a surprise when it first appears from code-completion because code generated by the 'Entity Classes from Database ...' wizard with TopLink generates equals() with the standard format. Here the optional same-object check has been omitted but a check for a null argument - implicit to instanceof, is now required. Class comparison rejects any object that is not a RegisteredItem, otherwise field comparisons are done as before.

Unfortunately, this get-it-for-free equals() does not work as required. Problems come up when incoming ItemData objects are compared with RegisteredItems in the HashSet. These comparisons always return false even when fields are equal. Class-comparison rejects an object of any other class and in this case the inherited equals() in ItemData objects rejects RegisteredItem objects in the HashSet.

Such non-intuitive rejection-by-proxy - modified behaviour without modifying a corresponding method, looks error prone to me. Class-comparison provides the second equality relationship with all subclasses doing so whether required or not.

But let's suppose a new scenario requirement is to produce a descendant of RegisteredItem - RegionItem say, that includes a region identifier, significant for equality, and has a similar relationship to a further subclass RgnItemData.

  • The standard equals() implementation cannot be used: it works OK in the derived class - superclass instances are rejected, but the superclass equals will accept the derived class. It has no knowledge of new significant fields, will do the comparison based on fields inherited by the subclass and produce a meaningless result.
  • Class-comparison cannot be used: in RegisteredItem it will will reject instances of RegionItem as might be required but scuppers the required type-one relationship with RgnItemData.

Fortunately the solution to this false dichotomy between the standard implementation and class-comparison is remarkably simple.

A simple solution

To allow for both inheritance options - overriding equals to get symmetry or not overriding equals and maintaining possible equality with a base-class instance, all that needs to be done is to factor off field comparison to a separate method and reverse the logic in the base-class equals(obj) so that obj calls the method passing the current object.

methods in base-class RegisteredItem:

    protected boolean equalFields(RegisteredItem other) {
return (this.itemID == other.itemID &&
this.categoryID.equals(other.categoryID));
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
return (obj instanceof RegisteredItem &&
((RegisteredItem)obj).equalFields(this));
}

instanceof fixes the compared class as the base RegisteredItem, not the type of any class that happens to inherit the method. Classes, like ItemData, comparable with the superclass that do not override equals inherit symmetrical comparison with superclass instances. A class like RegionItem with instances that must never be equal to an instance of the superclass override the inherited fields comparison method to return false.

methods in derived-class RegionItem:

    @Override
protected boolean equalFields(RegisteredItem other) {
return false;
}

The derived class then provides the root of a new comparison set: no instance of the superclass or any of its other subclasses will ever get a true result when equals() is called with an argument of this class. Reason - the call goes to the equalFields() method shown above or the comparison is rejected by a new instanceof test in that subclass' overloading of equals().

The equals() implementation used in the derived class is then optional. Code-completion could be invoked to get a class-comparison implementation for example, but to provide the same options for further subclasses, the equalFields format must be repeated at this level:

    private int regionID;

protected boolean equalFields(RegionItem other) {
// field comparisons can be in any order - lightest first looks good
if (this. regionID != other.regionID)
return false;
if (! super.equalFields(other))
return false;
return true;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
return (obj instanceof RegionItem &&
((RegionItem)obj).equalFields(this));
}

 

This approach requires little beyond what might be done anyway - factoring off field comparisons to improve clarity and facilitate amendments. Its simplicity means that coding errors are unlikely but a few criticisms have been made that I will try to answer here:

You can get incorrect results by calling equalFields directly - don't call this protected method using the same package get-out unless you are entirely confident in what you are doing.

It has sacrificed the simplicity of the canEqual solution for execution efficiency - the solution described here looks much simpler to me; it requires no new base-class methods above those that might be included to improve clarity in a standard implementation and resulting efficiency can only be a plus.

The solution presupposes knowledge of the hierarchy - a knowledge of the class-hierarchy is generally a prerequisite for coding descendants. Using @Override ensures inherited equalFields methods are overridden with a matching signature to return false and not overloaded by mistake.

Any further criticisms would be welcome - can't see any real drawbacks but here is a criticism of my own: code-completion cannot be used to get an equals() with this format. This is true but it can be used to generate a set of field comparisons in a form that can be put straight into an equalFields method without modification.

Equality of the third kind

Another benefit of the approach is that descendants of any class that implements the equalFields format can be coded to have any of the three possible equality relationships with a superclass. The code to implement relationship (3) is only slightly more complex but again readers are invited to skip forward. However, having pulled a scenario out of the hat to use in code examples it looks like the ability to implement (3) could be a real advantage.


A requirement for the third relationship might result if the 'Red' comparison set, shown again below, represents the initial set of classes to be stored in a HashSet. Circumstances change requiring the introduction of RegionItem etc. and life will be much easier if updates to existing items can arrive as either a DataItem or a RgnDataItem with a null regionID. The null is a zero in this case because regionID is an integer:

 
  Classes 2

The proposal is to make the Green set not completely separate from the Red set, as it would be using the equals() shown above. Here equals() and equalFields() for RegionItem must do field comparison between all RegionItems and also between RegisteredItems and RegionItems but only if the RegionItem has a regionID of zero.

Looking first at the field equality method that will be called when a RegionItem is the argument of RegisteredItem equals():

    private int regionID;
@Override
protected boolean equalFields(RegisteredItem other) {
return (regionID == 0 && super.equalFields(other));
}

Equality for RegionItem against RegionItem tests all fields:

    protected boolean equalFields(RegionItem other) {
if (this. regionID != other.regionID)
return false;
if (! super.equalFields(other))
return false;
return true;
}

The RegionItem equals() must now exclude any objects that are not RegisteredItems, call ((RegionItem) obj).equalFields(this) if obj is a RegionItem, equalFields(RegisteredItem) otherwise:

    @Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof RegisteredItem) {
if (obj instanceof RegionItem)
return ((RegionItem) obj).equalFields(this);
return equalFields((RegisteredItem)obj);
}
return false;
}

At the risk of obfuscating the code, this equals() can be made slightly more execution efficient by replacing the inner instanceof with an isA (RegionItem), to get rid of the redundant second check for a null argument, and by calling the superclass equalFields() directly:

    @Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof RegisteredItem) {
// if obj isA RegionItem
if (RegionItem.class.isInstance(obj))
return ((RegionItem) obj).equalFields(this);
return (regionId == 0 && ((RegisteredItem)obj).equalField(this));
}
return false;
}

Trust me, used as above Class.isInstance does provide an isA, although it may be hard to know that from either the method name or its JavaDoc.

Overriding hashCode() in subclasses

hashCode() implementations produced by code completion introduce a small prime, multiply this value by another small prime and add in a value for the first field. The field value is either an integer equivalent or its hashCode() return if the field is an object. The process is then repeated for any further fields.

Extending this format to derived classes, a 'simple solution' version of RegionItem gets say:

    @Override
public int hashCode() {
int hash = super.hashCode();
hash = 83 * hash + this.regionID;
return hash;
}

However, when a derived class instance with null fields may be equal to a superclass instance we need to make sure that under these circumstances equal inherited fields get equal hash codes.

One option is to omit overriding hashCode() in the subclass. Alternatively, null fields in the subclass must result in a zero hashcode contribution and the multiplicative factor be applied to this contribution rather than the inherited value:

    @Override
public int hashCode() {
int hash = super.hashCode();
hash = hash + 83 * this.regionID;
return hash;
}

One reason for ensuring that hashCode() is never zero is to allow for lazy initialization and as the cumulative number of fields increases a lazy approach is worth considering. Keep in mind however that String already implements a lazy hashCode(). A final example: a RegionItem of the third kind has grown an additional significant field and implements a lazy hashCode():

    private int regionID;
private LocalID localID;
private int hashcode;
@Override
public int hashCode() {
if (hashcode == 0) {
int hash = 79 * this.regionID +
(this.localID != null ? this.localID.hashCode() : 0);
hashcode = 101 * hash + super.hashCode();
}
return hashcode;
}

Afterword

Hopefully equality of the third kind has not obscured the nature of 'A simple solution'. This implementation is simple, very simple, and relies on nothing more complicated than basic OOP. The minimal nature of modifications to the standard implementation makes the simple solution suitable for general use where there is any possibility that a class may need to be subclassed at a later date. It seems strange that it is not more widely used but I have not seen it anywhere other than in my own code and web postings. Any comments would be greatly appreciated.

In Effective Java (Bloch 2008) Joshua Bloch condemns class-comparison in equals() as capable of violating the Liskov substitution principle and supplies examples showing how both the standard implementation and class comparison can be used to get such violations.

In Data Abstraction and Hierarchy (Liskov 1987) Barbara Liskov defines a subtype as one that can be substituted for a supertype without changing program behaviour. Her final conclusions recommend separation of interface and implementation inheritance. Josh is of the same mind identifying composition as a way around the equals problem but his example (page 40) demonstrates another OOP language problem identified by Liskov: broken encapsulation. To maintain encapsulation the aggregated object cannot be exposed as shown and numerous current class methods are required to call aggregated object methods. This work and resulting performance degradation is avoided by the simple solution.

A later paper (Liskov, Wing 1994), identifies object-equality as falling into a class of behaviour 'Nothing bad happens'. Ensuring that nothing bad happens, particularly when code is maintained and extended at a later time, is a major factor in writing real-world applications. To comply with good coding practice the standard equals() method needs to be final and any class using class-comparison should either be final or carry a prominent health warning 'DO NOT SUBCLASS WITHOUT OVERRIDING equals(Object)'.

However, Josh goes on to say, 'There is no way to extend an instantiable class and add a value component while preserving the equals contract, unless you are willing to forgo the benefits of object-oriented abstraction.' The simple solution does provide for extension of an instantiable class with equals contract compliance, which leaves us with 'object-oriented abstraction'.

Using the simple solution, calling contains(RegisterdItem) on a HashSet<RegisteredItem> - if fields match returns true, not otherwise. A RegionItem in the set has an additional field so fields can never match unless equality of the third kind is a requirement. Similarly for calls passing a RegionItem. RegionItems can be introduced with no modification of calls to HashSet methods needed to make things work as before - looks like abstraction to me! In the scenario it is more than likely that other work would result from introducing RegionItem, integration with existing database connectivity for example, but such problems are unrelated to equals() functionality.

Overriding equals() - a simple solution © Martin Humby November 2010 - all rights reserved.

References

canEqual solution [online] Martin Odersky, Lex Spoon, and Bill Venners How to Write an Equality Method in Java http://www.artima.com/lejava/articles/equality.html (accessed 06/11/2010)

Bloch 2008. Joshua Bloch. Effective Java Second Edition Adison-Wesley, © Sun-Micosystems 2008

Liskov 1987. Barbara Liskov. Data Abstraction and Hierarchy. In Addendum to the Proceedings of OOPSLA ‘87 and SIGPLAN Notices, Vol. 23, No. 5: Pages 17–34.

Liskov, Wing1994. Barbara Liskov, Jennette Wing. A Behavioral Notion of Subtyping ACM Transactions in Programmmg Languages and Systems, Vol 16, NO 6, November 1994, Pages 1811-1841

Permalink 2 comments (latest comment by Martin Thomas Humby, Saturday, 6 Nov 2010, 23:09)
Share post
ExLibris

The Oracle Sun Scenario

Visible to anyone in the world
Edited by Martin Thomas Humby, Wednesday, 10 Feb 2010, 17:32

For some time I have wondered how Sun's heavy support of free stuff stacked up against a strategy for profitability. Jonathan Schwartz 2009 blog reveals what it is (was?) all about.

So where does this leave Java? No worries apparently, everything is going to be all right: pdf here.

Fortunately there are other guarantees: the EU's MySQL intervention with subsequent assurances from Oracle; IBM's substantial commitment to Java in application server middleware - presumably backed by firm contractual arrangements in view of their previous experience with externally contracted software licensing. Do these changes indicate a bright and perhaps more targeted future for Java?

If anything Java is now even more squarely aligned against similar stuff from Microsoft. In my native language - Delphi pascal, the advent of .NET woke-up Borland after years of almost no innovation on the language side but too late to retrieve the level of superiority they had when Visual Basic was the main competition. We can hope that Oracle will not make the same error and perhaps something exciting is on the horizon.

Targeted innovation

Oracle's revenues have shown steady growth in recent years up to the current downturn and currently they lie third in world rankings for software sales. Their record for innovation includes applied bitmaped indexing (at least they hold some US patents) and the Exadata Storage Server - the driving incentive for their acquisition of Sun.

Initally Exadata ran on Hewlett-Packard hardware and for a surprisingly lucid sumarry of some of its workings look here. This contrasts nicely with the unveiling of Exadata 2 running on Sun's hardware reported here. Thankfully a more down to earth white paper is available in pdf format with an initial scan of pages 12 - 17 recommended. At this level Exadata must be seen as innovative. Putting purpose specific software closer to suitable hardware may seem pretty obvious but Exadata is entrepreneurial in an area where any proffered improvement is greeted with disbelief and suspicion. Will Oracle bring a similar drive to developing Java?

Java is now Oracle's C# and bringing it up to the richness of that language must be to their good. Java also has the advantage of not having to deal with .NET excess baggage. The downside for Oracle is that any basic improvements are also gifted to their arch rival IBM but we can hope that they can come to some arrangement.

The alternative is that the Java language will enter a period of stagnation similar to Delphi's with any improvement centred on extended and additional class libraries. Some may see this as no bad thing but the danger is that such additions are targeted towards a particular user problem resulting in ever more ways of doing much the same thing. Another symptom is the bolt-on syndrome: language additions that are not well integrated, of dubious utility and become an excuse for not putting a proper solution in place.

Some examples: initially Delphi got operator overloading using custom variants - over complicated, useless for any practical purpose and it took the .NET revolution to get a less half-baked implementation in place, an archetypal example of a bolt-on. Closures are now a feature of various OOP languages and are proposed for Java but how well do they fit in? Seems to me that either methods should become a first class data type (two actually) complete with closures, providing a fully integrated and substantially simpler solution to requirements that currently need a class or interface, or things are best left as they are.


Where do we get from here

Java's generics show how a new and powerful language feature can be integrated into an existing object model, maintaining code consistency and readability. On the other hand, while simple C# LINQ examples and operators are easy to comprehend, things do not look quite so good in relation to what this stuff is supposed to achieve: removal of the 'impedance mismatch' between code and database storage, according to Microsoft. I'm no expert but in the first example from this link can't see how the LINQ is fully equivalent to the SQL it is supposed to replace. More importantly: which alternative is easier to read?

Looking at how LINQ can be used shows the distance at least one aspect of Java would need to be taken to provide equivalent language richness. Currently the only Java provision I have come across is the for-each loop with an implied each and a hieroglyphic substituted for an in keyword. LINQ uses 14 keywords familiar to all SQL users - not necessarily getting 100% equivalent results, but LINQ looks a long way from providing an OOP replacement for SQL.

The Delphi solution from years past - hiding the SQL inside a TSQLQuery component solves one part of the problem but does not provide query language integration. Seems to me that full integration of database storage with OOP requires design of the object model from the bottom up to cater for runtime class creation and field access. In view of its age Java is excused. Microsoft have no excuse at all!

Currently an open verdict on LINQ seems justified but the danger is that if Java does not move forward it may be sidelined for some applications as happened to Delphi. A more telling example results from comparing code complexity Delphi / Java for a single-form (frame) database application with say a data grid, navigation and edits for the fields. The figure comes out at about 1/3 the lines of code. No doubt C# would show a similar ratio. Mutch of the difference relates to availability of off-the-shelf data aware components in Delphi but is also down to the way events are handled using methods assigned to component fields - not an option in Java.

Another danger for Java: .NET variants have the same potential for cross-platform application as Java with Microsoft showing a warm and friendly attitude to the Mono project. Can Oracle compete against Microsoft and Delphi's chief architect Anders Hejlsberg now leading their C# team? Based on current and past performance I think they have every chance.

 

The competion:


Relative worth / performance of high tech companies:

here

 

Impedance mismatch:

Two old Borland buddies discuss cutting-edge terminology at length. Oops! Might be inapplicable in view of recent findings and no excuse from immediacy. Seem to recollect apparent faster than light transmission in coax being reported in Wireless World letters about 25 years ago - mind you the writer was using some cable and an oscilloscope in his back garden to test the theory, not up to current experimental rigour no doubt.

 

More competion:

We must hope for success of the Sun Oracle Exadata server, but there is hardware and then there is Hardware!


IBM QS22

IBM Cell Broadband Engine-based BladeCenter QS22 (photos Research Daily and IBM) Are those heat sinks solid gold or just copper?

Cell vs Xeon

Permalink
Share post
ExLibris

Sun Java Application Server - change HTTP port

Visible to anyone in the world
Edited by Martin Thomas Humby, Tuesday, 2 Feb 2010, 01:19

To change port number to default / course-standard:

Go to program group from windows task bar:
start/All Programs/Sun Microsystems/Application Server PE 9

run app: Start Default Server
run app: Admin Console - opens window in default browser  
log on: - default user is admin, password is adminadmin

In the Common Tasks tree open the nodes: Configuration/HTTP Service/HTTP Listeners

Click http-listener-1, change port number to 8080, Click Save button

close Admin Console, close Server.

See http://docs.sun.com/app/docs/doc/819-3658/ablsw?a=view for HTTP configuration details.

Permalink
Share post

This blog might contain posts that are only visible to logged-in users, or where only logged-in users can comment. If you have an account on the system, please log in for full access.

Total visits to this blog: 74770