This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes Working out a problem statement posted in another thread. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Working out a problem statement posted in another thread." Watch "Working out a problem statement posted in another thread." New topic
Author

Working out a problem statement posted in another thread.

Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1000
    
  16
Greetings,

I'm trying to work out a problem that was recently posted in the following thread.

http://www.coderanch.com/t/610868/java/java/CompareTo-ArrayLists

I greatly appreciate both-- a clearly stated problem statement, and the suggestions, and hints posted in response to the original thread.

I am working out the problem based on the suggestions and pointers posted in response to the original thread but I can't figure out the ideal way to create the simulcast relationship.

Now coming to my solution, I tried creating the simulcast relationship in the compareTo method. I don't like this approach but this is all I could come up with. And even with this approach there is an issue which I will come to later. Here is my compareTo code.




With this, if I add following records in my ArrayList



I get a simulcast on stations with frequencies 91.2 and 91.3. But I want the simulcast to
work for 91.1 and 91.2.


run:
[Station1 band1 91.1, Station2 band1 92.1, Station3 band1 93.1, Station4 band1 94.1, Station0 band0 90.1, Station1 band0 91.3, Station1 band0 91.2]
Collection is sorted. Your radio stations would be :
[Station0 band0 90.1, Station1 band1 91.1, Station1 band0 91.2 (simulcast on band0 91.3), Station1 band0 91.3 (simulcast on band0 91.2), Station2 band1 92.1, Station3 band1 93.1, Station4 band1 94.1]
BUILD SUCCESSFUL (total time: 0 seconds)


RadioStation ( implements Comparable interface ) class member variables and methods I've coded are as follows.



Coming to my solution, I think it makes my compareTo method less modular and ugly. But even with my solution ( at least it does the job partly ) when jvm does an actual comparison to place my records in the arraylist, shouldn't it have created a simulcast on stations with frequencies 91.1 and 91.3 instead of on stations with frequencies 91.2 and 91.3.

Any pointers, hints, and suggestions would be greatly appreciated. Thanks.

Chan
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1000
    
  16
I thought it'd be better if I posted my classes in here. So here they are.




Piet Souris
Ranch Hand

Joined: Mar 08, 2009
Posts: 417
    
    5
Hi Chan Ag,

indeed it was an interesting post. What remained unclear to me was whether this simulcast is defined when it is given
explicitedly (as the poster writes, IMHO), or whether two stations are simulcast when they share the same
name (as the given examples suggest). Furthermore, and this is relevant to your post), whether simulcasts
is always between two and no more than two stations.

Now, in your code, a simulcast is created in the compareTo method, so effectively when you sort the arraylist in
line 16.

But in your class, a station can only have a simulcast relation with one other station. So I guess that in the comparison
between 91.1 and 91.3 the simulcast is recorded, but when comparing the 91.3 and the 91.2, the simulcast with 91.1 gets lost.

Given that a station can only have one simulcast station, I don't see how you can solve this the way you intend to.
A possibility is to add a List of simulcast stations in stead of just one simulcast station.

Anyway, I would not put this simulcast thing into the compareTo method. First of all, it doesn't belong there, and secondly, it will only
work after a sort has been done (unless you use a TreeSet).

Greetings,
Piet
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1000
    
  16
Thanks for your response, Piet.

Piet Souris wrote:
Anyway, I would not put this simulcast thing into the compareTo method. First of all, it doesn't belong there,


I thought same but couldn't come up with any other solution.

Piet Souris wrote:
A possibility is to add a List of simulcast stations in stead of just one simulcast station.


I will try to work on that while refining this code.

For now, what I have done is this.



It does the job and my compareTo method doesn't look ugly. I'm not sure though that this is the right approach to solve the problem. Now although my RadioStation class has methods that belong there, but the RadioStationApplication class still has a very long main method. I'm now thinking how to break my main method into separate methods. The thing that is making it slightly complicated is that main is a static method and I don't want to have many static method calls in my RadioStationApplication. Also my ArrayList should not be a static member.

Another thing I'm not sure about is the algorithm used by compareTo to sort objects. Because on a different run of my old compareTo I got a simulcast on 91.1 and 91.3 like I expected and I could not even reproduce my old output. So I figure the sort algorithm used for compareTo varies depending on ...... ( no idea what -- run time conditions? )..
Piet Souris
Ranch Hand

Joined: Mar 08, 2009
Posts: 417
    
    5
hi Chan Ag,

some remarks:

1) your "compareTo" method only compares on names, and if necessary, frequency (and then getting the simulcast situation).
In the original problem it was stated that the comparison should be on band and then frequency.
Given this, I think the philosophy is that two stations are equal if and only if both band AND frequency are equal, name doesn't matter,
and that actually does seem to make sense to me!

So, before proceeding, we should consider whether to stick to the original assignment or that we take the liberty of expanding
the assignment, as far as we would like to go. I'd say: let's give our fantasies all the space they need and consider the assignment as
a training mission in which we practice as much stuff as we can. Agree?

In this case, let us take the original assignment: two stations R1 and R2 are comparing to zero iff R1.band equals R2.band &&
R1.freq equals R2.freq.

2) let us assume that two stations R1 and R2 are simulcasts iff (= if and only if) we say explicitly that they are. So no automatic
simulcasting, UNLESS two stations R1 and R2 are equal. It seems obvious that when two stations R1 and R2 have both band and
frequency in common, that both are the same station. However, they might have been given two different names, though, so that
in effect both stations are different objects. What does that impose on the "equals" method? I mean: R1 and R2 are different objects, but
euqal in the compareTo-method!

3) Recently I discovered an aspect of Java that I found was very strange (and shocking, actually). I learned that a private member of some object
is private to the class, and not to the object!
So, taking your "RadioStation" class as an example:

"name" is a private member of the RS and so is "simulcastSation". Nevertheless, in your compareTo method you
use "o.name" and "o.simulcastStation = this" as if they were public fields!
But, since "private" means "private to the class" I guess it is all legal. But I find this very weird and defeating the whole purpose
of this "private" thingy!

4) so, in order to allow more than one simulcast, let's include a member called simulcast, as follows:

private ArrayList<RadioStation> simulcastList = new ArrayList<RadioStation>();

5) since doing the simulcasting only on command, we need a method setSimulcast(RadioStation rs) {...}
It should add rs to the ArrayList, if it's not in there yet (we don't want duplicates in our list)
So, we should use something like : if ( ! simulcastList.contains(rs) ) simulcastList.add(rs).
And at the same time, we also incorporate rs.setSimulcast(this).
This will ensure that it is always a two-way function. Now, would we need to make this function private or public?
Private would work, I guess, in the same way as described earlier, but I think it would stop working whenever
you subclass RadioStation. But that consideration also applies to the use of the other private fields!

However, this leads us to define an equals-method for two radiostations! We cannot use the compareTo-
function, or else we can't have two different names for one station. So in the "equals" method, we also
check for the names.

Now, everyone would say that if we redefine the "equals" method, then we should also redefine the "hashCode" method.
However, to me that is only necessary if you are ever going to use a hashSet or so. Since I have no plans to do so, I'd say
let's leave this for now (and be prepared for all the comments that this will give us!).

/************/

Anyway, lots to think about (and to code). What are your thoughts?

Greetings,
Piet
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1000
    
  16
Hi Piet,

Thanks for your response.

Piet Souris wrote:
1) your "compareTo" method only compares on names, and if necessary, frequency (and then getting the simulcast situation).
In the original problem it was stated that the comparison should be on band and then frequency.


Thanks for pointing out. I've corrected the code now. Here's my compareTo.



Piet Souris wrote:
Given this, I think the philosophy is that two stations are equal if and only if both band AND frequency are equal, name doesn't matter,
and that actually does seem to make sense to me!


I think that is how it would be in real world. But since the problem description said the comparison criterion is band+frequency and in that order and also that there was going to be an ArrayList of RadioStations, I took the liberty to assume that there could be duplicate records in the arraylist ( goes even for cases in which an object's name, band, and frequency are all same as that of another object ). They would still be in the ArrayList as simulcasts of one another ( if there has not been another RadioStation with the same name and a different band with a band name that would come before this band in ordering).

Considering that I think it is fine to let two similar objects be simulcasts of one another. However if we still want to treat two stations equal as you said ('iff R1.band equals R2.band && R1.freq equals R2.freq'), what it is we want to do if they are equal is still not clear to me. We can work it out if we know how the code is going to handle equal stations. And then we might want to give us another flexibility of choosing a datastructure of our choice, like say a TreeSet( I don't know much about it-- I am still doing recursion and simple arrays currently) I would assume.

Point 2 again would be a refinement we can work on later if we decide to choose another datastructure. Having said that, I am yet not too sure about the significance of equals method in the case of an ArrayList. It'll perhaps become more clear once I do some more practice problems. And then I will definitely revisit this post.

Piet Souris wrote:
3) Recently I discovered an aspect of Java that I found was very strange (and shocking, actually). I learned that a private member of some object
is private to the class, and not to the object!


Yes they are private to the class and that is precisely why we code public accessor methods like getName() etc. Or did you mean something else?

Piet Souris wrote:
So, taking your "RadioStation" class as an example:

"name" is a private member of the RS and so is "simulcastSation". Nevertheless, in your compareTo method you
use "o.name" and "o.simulcastStation = this" as if they were public fields!
But, since "private" means "private to the class" I guess it is all legal. But I find this very weird and defeating the whole purpose
of this "private" thingy!


This part was coded inside the class RadioStation. So like you said, yes simulcastStation is a private field to the class but again my method which is accessing it is also inside the class.

Piet Souris wrote:

4) so, in order to allow more than one simulcast, let's include a member called simulcast, as follows:

private ArrayList<RadioStation> simulcastList = new ArrayList<RadioStation>();



Yes, let us work on it. But unfortunately I've also got bitwise manipulations, recursion, and simple array assignments currently and they seem very very complicated to me and I am struggling to get those programs working ( I have to get them working by the end of this week). So yes, I will come back to this refinement. But that is for later.

Once more, thanks so much for taking interest in this problem statement and responding to my post and working it out with me. It means a lot to me.

Chan
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Working out a problem statement posted in another thread.
 
Similar Threads
Implementing Comparable Interface with TreeSets
CompareTo and ArrayLists
Sorting in List<Hash Map>
Making a String accessible to other classes
non duplicates in a Set