I tried looking up tutorials and videos and I understand what implementing does, although I'm a bit confused as to how one would implement a class from the Java Library. In my homework, I'm suppose to utilize the class, DataSet and make it so it accepts Comparable objects. The program is suppose to record the Min and Max values depending on the objects, in this case, I'm suppose to use strings. I wasn't sure if I needed any classes to implement the Comparable interface, so I made two classes just in case I was suppose to do so. My real question is how do I actually incorperate a String variable in the tester class to actually read and compare the object to another? thanks in advance.
public class Word implements Comparable
{
private String str;
public Word()
{
str = null;
}
public Word(String s)
{
str = s;
}
public int compareTo(Object other)
{
String n = (String) other;
return str.compareTo(n);
}
}
I wasn't sure which of the two classes would be suitable for implementing Although i think the String class below would not work at all b/c It's already a standard class so I wasn't too sure about using it
public class String implements Comparable
{
public String s;
public String()
{
s = null;
}
public String(String str)
{
s = str;
}
public int compareTo(Object other)
{
String n = (String) other;
return s.compareTo(n);
}
}
public interface Comparable
{
public int compareTo(Object other);
}
public class DataSet
{
private Object maximum;
private Object least;
private Comparable compare;
private int count;
public DataSet(Comparable s)
{
compare = s;
}
public void add(Object x)
{
if(count == 0)
least = x;
if(count == 0 || compare.compareTo(x) >=0)
maximum = x;
else if(compare.compareTo(x) <0)
least = x;
count++;
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
public class DataSetTester
{
public static void main(String[] args)
{
Comparable n = new Word("sand");
DataSet data = new DataSet(n);
data.add(new Word(man));
System.out.println("Maximum Word: " + data.getMaximum());
System.out.println("Least Word: " + data.getLeast());
}
}
An interface is a contract that showes that your class contain all methodes that are implemented in the interface. In this case the CompareTo(object other). The String class already implements the comparable interface so you don't need youre own class. I think your data set class should look something like this :
public class DataSet<T implements Comparable>
{
private T maximum;
private T least;
private T count;
public void add(T x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public T getMaximum()
{
return maximum;
}
public T getLeast()
{
return least;
}
}
T is a generic type and in your case it should be String, Here is how you create a new Data set:
DataSet<String> ds = new DataSet<String>;
Related
I have two types of objects that can perform a calculate() operation with either an int or a byte:
public class A {
public int calculate(int n) {...}
}
and
public class B {
public byte calculate(byte n) {...}
}
I want to have an ArrayList of objects that I can loop over calling the calculate method.
How do I do that, using an interface?
Considering the difference in the int/byte signature
Would something like this be a good approach?
public interface Calculatable {
int calculate(int number);
default byte calculate(byte number) {
return (byte) calculate((int) number);
}
}
Maybe using a 3-rd class and check based on type could be useful
public class TestCalc {
public static void main(String[] args) {
List<Object> l = new ArrayList<Object>();
l.add(Integer.valueOf(300));
l.add(Byte.valueOf("120"));
l.add(Integer.valueOf(1));
TestCalc tc = new TestCalc();
ComputeAB cab = tc.new ComputeAB();
for (Object o : l) {
System.out.println(cab.calculate(o) + ":" + cab.type);
}
}
class A {
public int calculate(int n) {
return n;
}
}
class B {
public byte calculate(byte n) {
return n;
}
}
class ComputeAB {
String type = "";
public Object calculate(Object o) {
if (o instanceof Integer) {
type = "int";
return new A().calculate((int) o);
}
type = "byte";
return new B().calculate((byte) o);
}
}
}
Output
300:int
120:byte
1:int
I am trying to write a generic heap class.
import java.util.ArrayList;
public class heap<T extends Comparable<T>>
{
private ArrayList<T> h;
private int size;
public heap()
{
h = new ArrayList<T>();
h.add(null);
size = 0;
}
public T getMin()
{
return h.get(1);
}
public T popMin()
{
T tmp = getMin();
h.set(1, h.get(size));
size--;
sift(1);
return tmp;
}
public void insert(T key)
{
h.add(key);
percolate(++size);
}
public int getSize()
{
return this.size;
}
private int getLeftSon(int i)
{
return (i<<1<=size)? i<<1 : 0;
}
private int getRightSon(int i)
{
return ((i<<1)+1<=size)? (i<<1)+1 : 0;
}
private int getFather(int i)
{
return ((i>>1)!=0)? i>>1 : 0;
}
private void swap(int i, int j)
{
T tmp = h.get(i);
h.set(i, h.get(j));
h.set(j, tmp);
}
private void sift(int i)
{
int son;
do {
son = 0;
if (getLeftSon(i) != 0)
{
son = getLeftSon(i);
if (getRightSon(i) != 0 && h.get(getRightSon(i)).compareTo(h.get(getLeftSon(i))) > 0)
son = getRightSon(i);
if (h.get(son).compareTo(h.get(i)) <= 0)
son = 0;
}
if (son!=0) {
swap(i, son);
i = son;
}
} while (son!=0);
}
private void percolate(int i)
{
T key = h.get(i);
while ((i > 1) && (key.compareTo(h.get(getFather(i))) > 0))
{
h.set(i, h.get(getFather(i)));
i = getFather(i);
}
h.set(i, key);
}
}
All good. It works like a charm. Excepting one thing: if I work with Integers I don't have 'access' to the method compareTo from Integer. meaning that I can not override it's behaviour. I will always have a Max heap this way. Can Integer compareTo by override (I don't think it can)?
So what can I do apart from creating another class MyInteger extends Integer{...} and override it there.
You could make your heap accept a Comparator in constructor and then provide a Comparator that reverses the order.
That's what the Comparator is for actually - defining an ordering that's not a natural one for the given class, being able to define multiple orderings of the same class, or indeed defining an ordering for a class you cannot modify.
The approach of accepting a comparator at construction time can be seen in TreeSet for example.
Example code stub:
public class Heap<T> { /* no need for items to extend Comparable anymore */
private final Comparator<T> cmp;
public Heap(Comparator<T> cmp) {
this.cmp = cmp;
...
}
...
}
... and then use cmp.compare(item1, item2) wherever you now use item2.compareTo(item2).
The compiler says " cannot find symbol: method compareTo(java.lang.Object) ". Could you please advice where is the mistake here?
Here is the part of the code:
public class OBTComparable<ObjectType> implements Comparable<OBTComparable>
{
public OTBComparable leftNode = null;
public OBTComparable mainNode = null;
public OBTComparable rightNode = null;
public ObjectType object = null;
public OBTComparable(ObjectType requiredObject)
{
object = requiredObject;
}
#Override
public int compareTo(OBTComparable other)
{
if(object.compareTo(other.object) == 0)
return 0;
else
if (object.compareTo(other.object) > 0)
return 1;
else return -1;
}
}
You need to scope ObjectType to Comparable too, because OBTComparable is delegating compareTo() to ObjectType:
If you change <ObjectType> to <ObjectType extends Comparable<ObjectType>>, it will compile:
public class OBTComparable<ObjectType extends Comparable<ObjectType>> implements Comparable<OBTComparable>
I think this is the proper code you are looking for (I replaced ObjectType with T for clarity):
class OBTComparable<T extends Comparable<? super T>> implements Comparable<OBTComparable<T>> {
public OBTComparable<T> leftNode = null;
public OBTComparable<T> mainNode = null;
public OBTComparable<T> rightNode = null;
public T object = null;
public OBTComparable(T requiredObject) {
object = requiredObject;
}
#Override
public int compareTo(OBTComparable<T> other) {
if (object.compareTo(other.object) == 0) {
return 0;
} else if (object.compareTo(other.object) > 0) {
return 1;
} else return -1;
}
}
What did I change here:
OBTComparable uses a type parameter, so you should show it when you implement Comparable. Therefore you have implements Comparable<OBTComparable<T>> instead of simply implements Comparable<OBTComparable>.
You compare two objects in the compareTo method, but are they comparable? To make sure this requirement is fulfilled, you should write OBTComparable<T extends Comparable<T>> instead of just OBTComparable<T>. Then you will know that you can call compareTo.
ObjectType must also implement Comparable<ObjectType>.
And if you do this, I believe that this:
public int compareTo(OBTComparable other)
{
if(object.compareTo(other.object) == 0)
return 0;
else
if (object.compareTo(other.object) > 0)
return 1;
else return -1;
}
can be simplified to this:
public int compareTo(OBTComparable other)
{
return object.compareTo(other.object);
}
I have this class:
public class Sample implements Comparable<Sample> {
public String a;
public String b;
public String c;
public int compareTo (Sample sampleToCompare) {
int compResult = this.a.compareTo(sampleToCompare.a);
return (compResult != 0 ? compResult :
this.b.compareTo(sampleToCompare.b));
}
}
I want compareTo() to behave or sort using different class properties depending if a flag is set.
So, if flag == 1 I'd like compareTo() to using property c, otherwise is flag == 0, whatever is currently in the method.
In other words, sort the same class in different ways.
I am not sure how to achieve this. Please help.
Also, please let me know if more information is needed from my side.
If you want to implement different kind of sorting, you should take a look at java.util.Comparator interface.
public class SampleComparatorA implement Comparator<Sample> {
public int compare(Sample a, Sample b) {
// Your sorting
}
}
And use java.util.Collections.sort() method with the Comparator as the secound parameter instead.
Collections.sort(aSampleList, new SampleComparatorA());
How about:
public int compareTo(Sample sampleToCompare) {
if (flag == 1) {
return this.c.compareTo(sampleToCompare.c);
}
if (flag == 0) {
// current stuff
}
...
}
That's not a very object-oriented way to do it, though. Probably you should have two different comparators and a way to select them based on your "flag" value. Something like:
class Sample {
private String a;
private String b;
private String c;
}
class ASampleComparator implements Comparator<Sample> {
public int compare(Sample o1, Sample o2) {
return o1.a.compareTo(o2.a);
}
}
class BSampleComparator implements Comparator<Sample> {
public int compare(Sample o1, Sample o2) {
return o1.b.compareTo(o2.b);
}
}
class CSampleComparator implements Comparator<Sample> {
public int compare(Sample o1, Sample o2) {
return o1.c.compareTo(o2.c);
}
}
public Comparator<Sample> pickComparator(int flag) {
switch (flag) {
case 0:
return new ASampleComparator();
case 1:
return new BSampleComparator();
case 2:
return new CSampleComparator();
default:
throw new IllegalArgumentException("Bad flag value: " + flag);
}
}
You should make your flag static so the comparison will be consistent (as described in Effective Java, item 12), otherwise, you might get that a.compareTo(b) returns that a > b, but b.compareTo(a) returns that b > a. So the simplest implementation I can think about is:
public class Sample implements Comparable<Sample> {
public String a;
public String b;
public String c;
public static boolean my_flag = false;
public int compareTo (Sample sampleToCompare) {
if (flag) {
return this.c.compareTo(sampleToCompare.c);
}
int compResult = this.a.compareTo(sampleToCompare.a);
return (compResult != 0 ? compResult :
this.b.compareTo(sampleToCompare.b));
}
}
I have the following code for sorting. Can this be improved?
import java.util.*;
class Church {
private String name;
private String pastor;
public Church(String name, String pastor) {
this.name = name;
this.pastor = pastor;
}
public String getPastor() {
return pastor;
}
public String getName() {
return name;
}
public void setPastor(String pastor) {
this.pastor = pastor;
}
public String toString() {
return getName() + " is Pastored by "+getPastor();
}
public int compareByPastor(Church c) {
int x = pastor.compareTo(c.getPastor());
return x;
}
public int compareByName(Church c) {
int x = name.compareTo(c.getName());
return x;
}
}
class Churches {
private final List<Church> churches;
public Churches() {
churches = new ArrayList<Church>();
}
public void addWithoutSorting(Church c) {
churches.add(c);
}
//You could always add using this method
public void addWithSorting(Church c) {
}
public void display() {
for(int j = 0; j < churches.size(); j++) {
System.out.print(churches.get(j).toString());
System.out.println("");
}
}
public List<Church> getChurches() {
return churches;
}
public void sortBy(String s) {
for (int i = 1; i < churches.size(); i++) {
int j;
Church val = churches.get(i);
for (j = i-1; j > -1; j--) {
Church temp = churches.get(j);
if(s.equals("Pastor")) {
if (temp.compareByPastor(val) <= 0) {
break;
}
}
else if(s.equals("Name")) {
if (temp.compareByName(val) <= 0) {
break;
}
}
churches.set(j+1, temp);
}
churches.set(j+1, val);
}
}
public static void main(String[] args) {
Churches baptists = new Churches();
baptists.addWithoutSorting(new Church("Pac", "Pastor G"));
baptists.addWithoutSorting(new Church("New Life", "Tudor"));
baptists.addWithoutSorting(new Church("My Church", "r035198x"));
baptists.addWithoutSorting(new Church("AFM", "Cathy"));
System.out.println("**********************Before Sorting***********************");
baptists.display();
baptists.sortBy("Pastor");
System.out.println("**********************After sorting by Pastor**************");
baptists.display();
baptists.sortBy("Name");
System.out.println("**********************After sorting by Name****************");
baptists.display();
}
}
Take a look at Collections.sort(list, comparator)
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html
class Churches
{
public void sortBy(String attribute)
{
Comparator<Church> c = null;
if ("Name".equals(attribute)) c = new ChurchNameComparator();
else if ("Pastor".equals(attribute)) c = new ChurchNameComparator();
else System.out.println("unexpected sort attribute : '" + attribute + "'");
if (c != null) Collections.sort(churches, c);
}
private static final class ChurchNameComparator implements Comparator<Church>
{
public int compare(Church c1, Church c2)
{
return c1.getName().compareTo(c2.getName());
}
}
private static final class ChurchPastorComparator implements Comparator<Church>
{
public int compare(Church c1, Church c2)
{
return c1.getPastor().compareTo(c2.getPastor());
}
}
}
The real answer here is pretty much in line with iluxa's: you want to implement a Comparator interface on your Church objects (sample code here, though you'll want to decide what constitutes greater than/less than for a church...), and then you can use Collections.sort() to sort them. That will get the job done, at the end of the day.
Of course, you just asked for advice about sorting on Stack Overflow, so I feel compelled to ask you if you need an in-place sort, what kind of Big-O performance you're looking for, and then ask you to choose between Quicksort, IntroSort, HeapSort, MergeSort, and StoogeSort for what will work best for you.
For kicks, I once coded up a few sorts in Java:
This one forces Quicksort into quadratic time, which was harder to do than I'd originally assumed,
This one shows how to implement MergeSort,
and this one demonstrates a HeapSort
I did these for my own enjoyment and education. As a general rule, you want to stick with the standard library for these sorts of things.