Override Integer compareTo? Or trick it? - java

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).

Related

Generic types and compareTo method for strings

I implemented a heap in java. Class declaration looks like this:
public class Heap<T extends Comparable<T>> implements HeapInterface<T>
And methods that I wanted to test look like this:
#Override
public void put(T item) {
if (item == null) {
throw new IllegalArgumentException("Cannot put null item.");
}
items.add(item);
int lastItemId = items.size() - 1;
heapUp(lastItemId);
}
private void heapUp(int childId) {
int parentId = (childId - 1) / 2;
while (childId > 0 && isChildBiggerThanParent(childId, parentId)) {
swapItems(childId, parentId);
childId = parentId;
parentId = (childId - 1) / 2;
}
}
And I used comapreTo method:
private boolean isChildBiggerThanParent(int childId, int parentId) {
T childValue = items.get(childId);
T parentValue = items.get(parentId);
return childValue.compareTo(parentValue) > 0;
}
Heap works fine for Integer, Double types and passed tests. But it doesn't work for Strings. Could you advice me what do i need to fix to make it work for strings also?

Inheritance var java

this is the qa:
Define a class called MoreSpeed which extends the following class, and which provides a new method called incSpeed() which adds 1 to the inherited variable length.
this is my answer:
public class Speed {
private int length = 0;
public int getSpeed () { return length; }
public void setSpeed (int i) {
if (i > 0) {
length = i;
}
}
}
public class MoreSpeed extends Speed {
private int length;
public int incSpeed() {
return length+1;
}}
its says that the syntax is good but the class operation is wrong.
please help me,thanks.
No. You are shadowing the length from Speed. Instead, implement incSpeed with getSpeed() like
public int incSpeed() {
return getSpeed() + 1;
}
If you are supposed to modify it as well then use setSpeed(int) to do so
public int incSpeed() {
int s = getSpeed() + 1;
setSpeed(s);
return s;
}

JUnit test in Isolation using Mockito

I have basic understanding of how to apply Mockito framework.
But when it comes to some real time scenarios I failed to write tests in Isolation(by Mocking the dependent classes).
Can you help me to write Unit test for PriorityQueuePrinter class by Mocking PriorityQueue Implementation(BinaryMaxHeap.java).
I wrote testPriorityQueue() with BinaryMaxHeap object, in this case my test becomes success but I want to achieve the same to mock BinaryMaxHeap so that my test will be Isolate. I think I have to set method behaviours also in my test method.
In short, Priority Queue is the Implementation for BinaryHeapTree and Printer class uses Priority Queue.
Below are the code classes.
public interface PriorityQueue<T extends Comparable<T>> {
int size();
void insert(T element);
T popMax();
}
public class BinaryMaxHeap<T extends Comparable<T>> implements PriorityQueue<T> {
private ArrayList<T> items;
public BinaryMaxHeap() {
items = new ArrayList<T>();
}
public int size() {
return items.size();
}
public void insert(T element) {
items.add(element);
shiftUp();
}
public T popMax() {
if (items.size() == 1) {
return items.remove(0);
}
T hold = items.get(0);
items.set(0, items.remove(items.size()-1));
shiftDown();
return hold;
}
/*
* place newly added element in correct position in binary tree
*/
private void shiftUp() {
int k = items.size() - 1;
while (k > 0) {
int p = (k-1) / 2; // get parent element index
T child = items.get(k);
T parent = items.get(p);
if (child.compareTo(parent) > 0) {
// parent and child are not in correct position, need to swap
items.set(k, parent);
items.set(p, child);
k = p;
} else {
break;
}
}
}
private void shiftDown() {
int k = 0;
int l = 2*k+1; // left leaf node
while (l < items.size()) {
int max = l; // assume left node as max element
int r = l+1; // right leaf node
if (r < items.size()) {
if (items.get(r).compareTo(items.get(l)) > 0) {
max++; // identify max element in leaf nodes
}
}
T parent = items.get(k);
T child = items.get(max);
if (parent.compareTo(child) < 0) {
// parent element is less than leaf node, need to swap it
T temp = items.get(k);
items.set(k, items.get(max));
items.set(max, temp);
k = max;
l = 2*k+1;
} else {
break;
}
}
}
}
public interface Printer {
public <T extends Comparable<T>> String asSortedString(T... values);
}
public class PriorityQueuePrinter implements Printer {
private PriorityQueue priorityQueue = null;
public <T extends Comparable<T>> PriorityQueuePrinter(PriorityQueue<T> priorityQueue) {
this.priorityQueue = priorityQueue;
}
public <T extends Comparable<T>> String asSortedString(T... values) {
//PriorityQueue<T> priorityQueue =
addElements(values);
//return getSortedElements();
return null;
}
private <T extends Comparable<T>> void addElements(T... values) {
//PriorityQueue<T> priorityQueue = new BinaryMaxHeap<T>();
for (T element : values) {
priorityQueue.insert(element);
}
//return priorityQueue;
}
public int size() {
return priorityQueue.size();
}
private String getSortedElements() {
StringBuilder sortedElements = new StringBuilder();
boolean isFirstElement = true;
while(priorityQueue.size() > 0) {
if (!isFirstElement) {
sortedElements.append(",");
}
isFirstElement = false;
sortedElements.append(priorityQueue.popMax());
}
return sortedElements.toString();
}
public static void main(String a[]) {
PriorityQueuePrinter p = new PriorityQueuePrinter(new BinaryMaxHeap<Integer>());
String sortedElements = p.asSortedString(1,4,6,3,2);
System.out.println(sortedElements);
}
}
Below is the sample test code tried but not able to complete.
public class PrinterTest {
#Mock
PriorityQueue<Integer> mockPriorityQueue; // mock object
PriorityQueue<Integer> priorityQueue;
#Test
public void testPriorityQueueWithMock() {
PriorityQueuePrinter printer = new PriorityQueuePrinter(mockPriorityQueue);
String s = printer.asSortedString(5,3,6);
assertEquals("6,5,3", s);
}
#Ignore
public void testPriorityQueue() {
priorityQueue = new BinaryMaxHeap<Integer>();
PriorityQueuePrinter printer = new PriorityQueuePrinter(priorityQueue);
String s = printer.asSortedString(5,3,6);
assertEquals("6,5,3", s);
}
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#After
public void tearDown() throws Exception {
System.out.println("==tearDown==");
}
}
#Before
public void setUp() throws Exception {
//mockPriorityQueue = new BinaryMaxHeap<Integer>();
MockitoAnnotations.initMocks(this);
}
}

implementing and interfaces

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>;

sorting function - how can this be improved

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.

Categories