edit: not sure if this is a correct fix but for some reason adding extends Comparable gets rid of the errors
I keep getting this same error. Why?
The error I receive is:
The method maxHeapify(T[], int) in the type HeapSort is not applicable for the arguments (T[], int)
Here's my code:
public class HeapSort {
private static int parent(int i)
{
if(i % 2 == 0)
{
return((i-1)/2);
}
else
{
return(i/2);
}
}
private static int leftChild(int i)
{
return(2*i + 1);
}
private static int rightChild(int i)
{
return(2*i + 2);
}
private static <T> void buildMaxHeap(T[] array)
{
int heapSize = array.length;
for(int i = (heapSize/2 - 1); i >= 0; i--)
{
maxHeapify(array, i);
}
}
private static <T extends Comparable<T>> void maxHeapify(T[] array, int i)
{
int L = leftChild(i);
int R = rightChild(i);
int Largest = (int) array[0];
T temp;
if(L <= array.length && array[R].compareTo(array[i]) > 0)
{
Largest = L;
}
else
{
Largest = i;
}
if(R <= array.length && array[R].compareTo(array[Largest]) > 0)
{
Largest = R;
}
if(Largest != i)
{
Swap(array[i], array[Largest]);
maxHeapify(array, Largest);
}
}
public static <T> void heapSort(T[] array)
{
buildMaxHeap(array);
int heapSize = array.length;
for(int i = array.length - 1; i >= 0; i--)
{
Swap(array[0], array[i]);
heapSize = heapSize-1;
maxHeapify(array, 0);
}
}
}
The reason for the error is because this line defines T differently
private static <T extends Comparable<T>> void maxHeapify(T[] array, int i)
to this
private static <T> void buildMaxHeap(T[] array)
and this
public static <T> void heapSort(T[] array)
Its
<T>
vs
<T extends Comparable<T>>
because buildMaxHeap and heapSort both call maxHeapify so you get a generics type mismatch
If you convert all the types to
<T extends Comparable<T>>
Then this will fix that error
You will also have another error when you fix this
int Largest = (int) array[0];
because your array doesn't contain int's, it contains your generic type objects
Related
Create and implement a Policy class following the below class diagram with a simple configuration mechanism:
Select MergeSort when the List has more than 10 dates.
Select BubbleSort when the List has less or equal 10 dates.
So what I've done is extended the class Policy to Context to share the methods.
The variable "dates" is of type List<Date>. I made it an array list so I can get the size of it easily.
I used the size method to compare its size to 10 using an if/else function. After, I used the setAlgorithm method to set the type of sort that is required.
// Policy Class
import packageName.Context;
import packageName.MergeSort;
import packageName.BubbleSort;
import static java.util.Collections.list;
public abstract class Policy extends Context {
private Context context;
void Policy(Context context){
this.context = context;
}
//You can check the length of the list any time with list.size()
void configure() {
if(!CollectionUtils.isEmpty(dates)) {
//gives me cannot find symbol for CollectionUtils
if(dates.size() > 10) {
setSortAlgorithm(MergeSort);
//gives me cannot find symbol for MergeSort
} else if(dates.size() <= 10{
setSortAlgorithm(BubbleSort);
//gives me cannot find symbol for BubbleSort
}
} else {
}
}
}
//Context Class
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public abstract class Context implements SortStrategy {
List<Date> dates = new ArrayList<Date>();
SortStrategy sortAlgorithm;
List<Date> getDates(List<Date> dates) {
return dates;
}
void setDates(List<Date> dates){
this.dates = dates;
}
void setSortAlgorithm(SortStrategy sortAlgorithm){
this.sortAlgorithm = sortAlgorithm;
}
SortStrategy getSortAlgorithm() {
return sortAlgorithm;
}
void sort(List<Comparable> input) {
performSort(input);
}
}
//MergeSort Class
import java.util.List;
public abstract class MergeSort implements Comparable<SortStrategy> {
public <T extends Comparable<T>> void performSort(List<T> input) {
mergesort(input, 0, input.size() - 1);
}
// Recursive mergesort method
private static <T extends Comparable<T>> void mergesort(List<T> input, int low, int high) {
if (high - low < 1) return;
int mid = (low + high) / 2;
mergesort(input, low, mid);
mergesort(input, mid + 1, high);
merge(input, low, mid, high);
}
// Merge method
// Here we need to allocate a new array, but Java does not allow allocating arrays of a generic type
// As a work-around we allocate an array of type Object[] the use type casting
// This would usually generate a warning, which is suppressed
#SuppressWarnings("unchecked")
private static <T extends Comparable<T>> void merge(List<T> input, int low, int middle, int high) {
Object[] tmp = new Object[high - low + 1];
int leftIndex = low;
int rightIndex = middle + 1;
int wholeIndex = 0;
while (leftIndex <= middle && rightIndex <= high) {
if (input.get(leftIndex).compareTo(input.get(rightIndex)) <= 0)
tmp[wholeIndex] = input.get(leftIndex++);
else
tmp[wholeIndex] = input.get(rightIndex++);
wholeIndex++;
}
if (leftIndex <= middle && rightIndex > high) {
while (leftIndex <= middle)
tmp[wholeIndex++] = input.get(leftIndex++);
} else {
while (rightIndex <= high)
tmp[wholeIndex++] = input.get(rightIndex++);
}
for (wholeIndex = 0; wholeIndex < tmp.length; wholeIndex++) {
input.set(wholeIndex+low, (T) (tmp[wholeIndex]));
// this is the line that would generate the warning
}
}
}
//Bubble Sort Class
import java.util.List;
public abstract class BubbleSort implements Comparable<SortStrategy> {
public <T extends Comparable<T>> void performSort(List<T> input) {
for (int i = input.size() - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (input.get(j).compareTo(input.get(j + 1)) > 0) {
T temp = input.get(j);
input.set(j, input.get(j + 1));
input.set(j + 1, temp);
}
}
}
}
}
UML Class Diagram
if(!CollectionUtils.isEmpty(list)) {
if(list.size() > 10) {
mergeSort(list);
} else {
bubbleSort(list);
}
}
To explain it: as soon as you don't have an empty or a null list, you check the number of elements using list.size(). Depending on that, you either use mergeSort if the length is grater then 10, either bubbleSort
class BubbleSort<T> extends ArraySort<T>
{
public void iSort(T[] inArray) {
int n = inArray.length;
int k;
for (int m = n; m >= 0; m--) {
for (int i = 0; i < n - 1; i++) {
k = i + 1;
if (compare(inArray[i], inArray[k])) {
T temp;
temp = inArray[i];
inArray[i] = inArray[k];
inArray[k] = temp;
}
}
}
print(inArray);
}
public static <T extends Comparable<T>> boolean compare(T a, T b) {
if (a.compareTo(b) > 0) {
return true;
} return false;
}
I'm getting (T extends comparable < T >, T extends comparable < T >) in the type bubblesort< T > is not applicable for the arguments (T,T) error!
The quick fix is telling me to change method compare(T,T)< T > to compare(T,T), but that wouldn't resolve my problem. It works perfectly fine when I enter in actual value of elements, for example, compare(3, 5) or compare("hi", "hello") instead of compare(inArray[i], inArray[k]).
I would appreciate it a lot if someone could explain why it's doing that and give me a solution.
You've already defined your class with a generic type T, so there's no point in declaring a separate one for the method:
class BubbleSort<T extends Comparable<T>> extends ArraySort<T> {
public void iSort(T[] inArray) {
int n = inArray.length;
int k;
for (int m = n; m >= 0; m--) {
for (int i = 0; i < n - 1; i++) {
k = i + 1;
if (compare(inArray[i], inArray[k])) {
T temp;
temp = inArray[i];
inArray[i] = inArray[k];
inArray[k] = temp;
}
}
}
print(inArray);
}
public static boolean compare(T a, T b) {
if (a.compareTo(b) > 0) {
return true;
}
return false;
}
}
Anyway, you should denote T extends Comparable<T> in the class declaration rather than in the method.
I need to write a algorithm to sort a collection, more than 10, 000, 000 elements.
So I write a forkjoin quick sort...
But when the input become bigger, the code collapses.
Firstly, I use the test cases is a random list, implements can handle.
Then, I just try some extremely cases, just as a ordered numbers. Code fails.
I check the code, but have no idea of why.
This is code below:
public class ForkJoinSort {
private static int THRESHOLD = 1000;
private static ForkJoinPool pool = new ForkJoinPool();
public static <T extends Comparable<T>> void quickSortFJ(List<T> rawList) {
pool.invoke(new QuickSort<>(rawList));
}
static class QuickSort<T extends Comparable<T>> extends RecursiveAction {
List<T> rawList;
int lo;
int hi;
QuickSort(List<T> rawList) {
this.rawList = rawList;
this.lo = 0;
this.hi = rawList.size() - 1;
}
QuickSort(List<T> rawList, int lo, int hi) {
this.rawList = rawList;
this.lo = lo;
this.hi = hi;
}
#Override
protected void compute() {
if (hi > lo && hi - lo >= THRESHOLD) {
int pivot = partition(rawList, lo, hi);
invokeAll(new QuickSort<>(rawList, lo, pivot - 1),
new QuickSort<>(rawList, pivot + 1, hi));
} else {
quickSort(rawList, lo, hi);
}
}
}
private static <T extends Comparable<T>> int partition(List<T> rawList, int lo, int hi) {
T key = rawList.get(hi);
int index = lo;
for (int i=lo; i<hi; i++) {
if (rawList.get(i).compareTo(key) > 0) {
swap(rawList, index, i);
index ++;
}
}
swap(rawList, index, hi);
return index;
}
private static <T extends Comparable<T>> void swap(List<T> rawList, int left, int right) {
if (left != right) {
T temp = rawList.get(left);
rawList.set(left, rawList.get(right));
rawList.set(right, temp);
}
}
public static <T extends Comparable<T>> void quickSort(List<T> rawList, int lo, int hi) {
if (lo < hi) {
int pivot = partition(rawList, lo, hi);
quickSort(rawList, lo, pivot-1);
quickSort(rawList, pivot+1, hi);
}
}
}
Test case failed:
List<Long> longTwoList = new ArrayList<>();
for (long i=0; i!=17000; i++) {
longTwoList.add(i);
}
ForkJoinSort.quickSortFJ(longTwoList);//failed
ForkJoinSort.quickSort(longTwoList, 0, longTwoList.size()-1);//falied
Quite confused with this problem. Thank you for replying.
I am developing a big example case for teaching generics. A group of classes and interfaces that mimic the collections class in Java. Here's one of the source files:
package edu.brandeis.cosi12b.listdemo;
public class ArrayList<E extends Comparable<E>> extends AbstractList<E> implements List<E> {
private E[] list;
private int size;
private int capacity;
public ArrayList() {
this(20);
}
#SuppressWarnings("unchecked")
public ArrayList(int initialCapacity) {
list = (E[]) (new Object[initialCapacity]);
size = 0;
capacity = initialCapacity;
}
public int capacity() {
return capacity;
}
public int size() {
return size;
}
public void add(E val) {
list[size] = val;
size++;
}
public String toString() {
StringBuffer s = new StringBuffer();
s.append("[");
for (int i = 0; i < size - 1; i++) {
s.append(list[i]);
s.append(", ");
}
s.append(list[size - 1]);
s.append("]");
return (s.toString());
}
public void set(int index, E value) {
expandIfNecessary(index);
for (int i = size; i > index; i--) {
list[i] = list[i - 1];
}
list[index] = value;
if (index > size)
size = index + 1;
}
#SuppressWarnings("unchecked")
private void expandIfNecessary(int index) {
if (index < capacity)
return;
int newCapacity = capacity * 2 + index;
E[] oldArray = list;
list = (E[]) (new Object[newCapacity]);
for (int i = 0; i < size; i++)
list[i] = oldArray[i];
capacity = newCapacity;
}
public E get(int index) {
if (index < 0 || index >= size)
throw new ArrayIndexOutOfBoundsException("i: " + index + " s: " + size);
return list[index];
}
public void remove(int index) {
for (int i = index; i < size; i++)
list[i] = list[i + 1];
size--;
}
public boolean isEmpty() {
return size() == 0;
}
public int indexOf(E value) {
for (int i = 0; i < size; i++) {
if (list[i] == value)
return i;
}
return -1;
}
public boolean contains(E value) {
return (indexOf(value) != -1);
}
#Override
public void add(int index, E value) {
// TODO Auto-generated method stub
}
}
When I run this in a test case I get this error. I know it's something pretty subtle and it exceeds my knowledge of Java.
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
at edu.brandeis.cosi12b.listdemo.ArrayList.<init>(ArrayList.java:14)
at edu.brandeis.cosi12b.listdemo.ArrayList.<init>(ArrayList.java:9)
at edu.brandeis.cosi12b.listdemo.TestSuite.arrayListtest1(TestSuite.java:134)
at edu.brandeis.cosi12b.listdemo.TestSuite.runArrayListTests(TestSuite.java:15)
at edu.brandeis.cosi12b.listdemo.TestSuite.runAll(TestSuite.java:9)
at edu.brandeis.cosi12b.listdemo.ListDemo.runTests(ListDemo.java:13)
at edu.brandeis.cosi12b.listdemo.ListDemo.main(ListDemo.java:6)
Use
list = (E[]) new Comparable<?>[initialCapacity];
and
list = (E[]) (new Comparable<?>[newCapacity]);
Java doesn't have fully reified generics at runtime (it uses erasure), so it doesn't actually know what E is - only that it extends Comparable, so that is what the compiler inserts for the casts.
The bytecode generated by the compiler for your code looks like this if decompiled:
list (Comparable[]) new Object[initialCapacity];
which fails.
I am trying to use a generic method to sort an array. I am receiving an error on Lab6Sort(octArr); that says classname cannot be applied to Shape[].
public static void main(String[] args) {
Shape[] octArr = new Shape[10];
for(int i = 0; i < 10; i++){
octArr[i] = new L6MPerRegOct(Math.floor(Math.random() * 1000) / 10);
}
Lab6Sort(octArr);
}
.
.
public static <AnyType> void Lab6Sort (AnyType [] arr, Comparator<? super AnyType> cmp)
It seems that I need a second argument, but I am unsure what this should be.
Here is the complete code:
public class L6MPerRegOct extends Shape {
public static void main(String[] args) {
Shape[] octArr = new Shape[10];
for(int i = 0; i < 10; i++){
octArr[i] = new L6MPerRegOct(Math.floor(Math.random() * 1000) / 10);
}
Lab6Sort(octArr);
}
private double sideLength;
public L6MPerRegOct(double len){
sideLength = len;
}
public double area(){
return 2 * sideLength*sideLength * (1 + Math.sqrt(2));
}
public static <AnyType> void Lab6Sort (AnyType [] arr, Comparator<? super AnyType> cmp)
{
int j, minIndex, n = arr.length;
AnyType temp;
for ( int index = 0; index < n - 1; index++ ) {
minIndex = index;
for (j = index + 1; j < n; j++) {
if (cmp.compare(arr[index], arr[minIndex]) < 0)
minIndex = j;
}
if (minIndex != index) {
temp = arr[index];
arr[index] = arr[minIndex];
arr[minIndex] = temp;
}
}
public abstract class Shape implements Comparable<Shape>
{
public abstract double area( );
public abstract double perimeter( );
public int compareTo( Shape rhs )
{
double diff = area( ) - rhs.area( );
if( diff == 0 )
return 0;
else if( diff < 0 )
return -1;
else
return 1;
}
public double semiperimeter( )
{
return perimeter( ) / 2;
}
}
You need to pass it an instance of a Comparator, e.g.
Lab6Sort(octArr, new Comparator<Shape>() {
#Override
public int compare(Shape o1, Shape o2) {
return 0;
}
});
Or define the Comparator in a separate class, if you want to reuse it
public class ShapeComparator implements Comparator<Shape> {
#Override
public int compare(Shape o1, Shape o2) {
return 0;
}
}
class ShapeComparator implements Comparator<Shape> {
#Override
public int compare(Shape o1, Shape o2) {
return 0;
}
}