Realize the Radio and Channel classes that represent radio and a radio station. The radio class offers an argumentless constructor and the following methods:
- addChannel: stores and returns a new station, characterized by name, frequency. Attempting to store a station that has the same frequency as an already stored station should result in an exception.
- nearest: accepts a frequency and returns the station with the closest frequency to that given.
Furthermore, if you iterate on a Radio object you get the sequence of stations entered, in increasing order of frequency.
Make sure that the only way to create Channel objects is through the addChannl method.
Observe the following example of use:
Radio r = new Radio();
Channel c1 = r.addChannel("Rai Radio Uno", 89.3);
Channel c2 = r.addChannel("Radio Monte Carlo", 96.4);
Channel c3 = r.addChannel("Radio Kiss Kiss", 101.4);
for(Channel c: r) {
System.out.println(c);
}
System.out.println(r.nearest(98.1));
Output: Radio Monte Carlo (96.4)
I would like your opinion on my implementation. What can be improved or fixed?
My implementation:
import java.util.*;
public class Radio implements Iterable<Radio.Channel>{
public static final Comparator<Channel> COMP = (Channel c1, Channel c2) -> {
return Double.compare(c1.frequenza, c2.frequenza);
};
private Set<Channel> channels;
private List<Channel> my_nesteds;
public Radio() {
channels = new TreeSet<>(COMP);
my_nesteds = new ArrayList<>();
}
public Channel addChannel(String nome, double frequenza) {
Channel new_channel = new Channel(nome,frequenza);
if(!channels.add(new_channel)){
throw new RuntimeException("...");
}
return new_channel;
}
public Channel nearest(double frequenza){
double distance = 0.0;
double min = 0.0;
boolean first = true;
Channel ret_channel = null;
for(Channel cc: channels) {
if(first) {
min = Math.abs(cc.frequenza - frequenza);
ret_channel = cc;
first = false;
}else {
distance = Math.abs(cc.frequenza - frequenza);
if(min > distance) {
min = distance;
ret_channel = cc;
}
}
}
return ret_channel;
}
@Override
public Iterator<Radio.Channel> iterator() {
return new Iterator<>() {
int index = 0;
@Override
public boolean hasNext() {
if(index < channels.size()) {
return true;
}
return false;
}
@Override
public Channel next() {
if(index < channels.size()) {
Channel c = my_nesteds.get(index);
index++;
return c;
}
throw new NoSuchElementException();
}
};
}
/* **************************************************** */
protected class Channel{
private String nome;
private double frequenza;
public Channel(String nome, double frequenza) {
this.nome = nome;
this.frequenza = frequenza;
my_nesteds.add(this);
}
@Override
public String toString() {
return nome+" "+"("+frequenza+")";
}
@Override
public boolean equals(Object o){
if(!(o instanceof Channel)){ return false; }
Channel c = (Channel) o;
if(COMP.compare(this,c) == 0){ return true; }
return false;
}
}
/* **************************************************** */
}
comp
is a static final field after the constructor. Unusual, but working. \$\endgroup\$TreeSet
is aNavigableSet
which has readymadeceiling()
andfloor()
functions. In a professional review, I'd tell the developer to use these instead of calculating the distance manually. Here, I guess these features have not been subject in the class yet. \$\endgroup\$public static final Comparator <String> CASE_INSENSITIVE_ORDER
\$\endgroup\$