Generics in Java: How do I make this example work? - java

class main{
public static void main(String[] args){
int[] array = new int[3];
array[0]=3;
array[1]=2;
array[2]=1;
System.out.println(<Integer>countGreaterThan(array,1));
}
static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
int count = 0;
for (T e : anArray)
if (e.compareTo(elem) > 0)
++count;
return count;
}
}
I got this examle in Java Documentation. When i write extends Comparable, how can i tell the compiler what is type?
I think i should instantiate T in <T extends Comparable<T>>, but how?

Just change the int to Integer and remove that ugly <Integer> inside your print statement.
Integer[] array = new Integer[3];
array[0] = 3;
array[1] = 2;
array[2] = 1;
System.out.println(countGreaterThan(array, 1));

I would arrange this so you can use varargs
static <T extends Comparable<T>> int countGreaterThan(T elem, T... anArray) {
int count = 0;
for (T e : anArray)
if (e.compareTo(elem) > 0)
++count;
return count;
}
}
System.out.println(countGreaterThan(1, 3,2,1));

class main {
public static void main(String[] args){
Integer[] array = new Integer[3];
array[0]=3;
array[1]=2;
array[2]=1;
System.out.println(countGreaterThan(array,1));
}
static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
int count = 0;
for (T e : anArray)
if (e.compareTo(elem) > 0)
++count;
return count;
}
}

Integer[] array = new Integer[3];
array[0]=3;
array[1]=2;
array[2]=1;
System.out.println(countGreaterThan(array,1));
Is this what you are looking for?

Related

Select max from a List using Generics

I have to write a method which selects the maximum value from a list, and it has to be with Generics. Obviously the List can be Number and String as well. (The return value has to be Opt Object. This is the tasks.)
This is what I have so far, but its not working, I would appreciate your advice:
public static <T> Opt<T> max(List<? extends Object> list) {
T max = (T) list;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) > max) {
max = (T) list.get(i);
}
}
return (Opt<T>) max;
}
And this is the main looks like: (From this one I have to make my method work.)
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
Utility.addTo(stringList, "aghi");
Utility.addTo(stringList, "fed");
Utility.addTo(stringList, "ghh");
Utility.addTo(stringList, "abc");
Utility.addTo(stringList, "123");
System.out.println("The maximum value: " + Utility.max(stringList).get());
List<Integer> intList = new ArrayList<>();
Utility.addTo(intList, 123);
Utility.addTo(intList, 456);
Utility.addTo(intList, -199);
Utility.addTo(intList, -90);
Utility.addTo(intList, 0);
Utility.addTo(intList, -10);
Utility.addTo(intList, 200);
System.out.println("The maximum value: " + Utility.max(intList).get());
List<Double> doubleList = new ArrayList<>();
Utility.addTo(doubleList, 123.0);
Utility.addTo(doubleList, 456.001);
Utility.addTo(doubleList, -199.0);
Utility.addTo(doubleList, -90.90);
Utility.addTo(doubleList, 0.0);
Utility.addTo(doubleList, -10.20);
Utility.addTo(doubleList, 200.1);
System.out.println("The maximum value: " + Utility.max(doubleList).get());
}
And the Output shoud be:
The maximum value: ghh
The maximum value: 456
The maximum value: 456.001
Using Streams makes it really easy by doing all the work for you:
public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
return list.stream().max(Comparator.naturalOrder());
}
or the Collections class of utility functions:
public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
if (list.isEmpty()) {
return Optional.empty();
} else {
return Optional.of(Collections.max(list, Comparator.naturalOrder()));
}
}
Your code is not working (I mean cannot be compiled) because of this line:
if (list.get(i) > max) {
In Java, there are no overloaded operators as in C++, so you need to find another way...
By Opt you probably meant java.util.Optional class and you can use it like this:
public static <T> Optional<T> max(List<T> list) {
Optional<T> max = Optional.empty();
for (int i = 0; i < list.size(); i++) {
// if (list.get(i) > max) {
max = Optional.of(list.get(i));
// }
}
return max;
}
This is of course not working, it returns last element from list.
When creator of a class expects users might be interested in sorting (comparing), they would implemente java.lang.Comparable, this is the case for String, Long and Double. So instead of T, you can say T extends Comparable like this:
public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
T max = null;
for (int i = 0; i < list.size(); i++) {
final T item = list.get(i);
if (max == null) {
max = item;
} else if (max.compareTo(item) < 0) {
max = item;
}
}
if (max == null) return Optional.empty();
return Optional.of(max);
}
Look at Comparable#compareTo JavaDoc.
Try to understand what this line means exactly (and why you cannot use it with list of java.lang.Objects):
public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
and why we do not need it in addTo:
public static <T> void addTo(List<T> list, T e) {

java : how to compare generic variables with int

Write a Java program to define a generic method that counts the number of elements in an array T [ ] that are greater than a specified element elem.
I have written my code as:
public class GenericMethods<E extends Comparable<E>> {
public static < E > void printArray( E[] inputArray ) {
// Display array elements
for(E element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
public static < E > void countArray( E[] inputArray, int elem) {
int i=0;
for(E element : inputArray){
if(elem>element)
i++;
}
System.out.println(i);
}
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
Integer[] intArray = { 1, 2, 3, 4, 5 };
System.out.println("\nArray contains:");
printArray(intArray);
int elem=0;
System.out.println("Enter the specified number: ");
elem = sc.nextInt();
countArray(intArray, elem);
}
}
I get the following errors:
error: bad operand types for binary operator '>'
if(elem>element)
^
first type: int
second type: E
where E is a type-variable:
E extends Object declared in method countArray(E[],int)
1 error
One way is to require that your generic type parameter E is a Number.
Then you can use Number's intValue() method to convert each element of the array to an int, which can be compared to elem.
public static <E extends Number> void countArray(E[] inputArray, int elem) {
int i = 0;
for (E element : inputArray) {
if(elem > element.intValue ())
i++;
}
System.out.println(i);
}
you cant use > operator on object
you can do as Eran said or ensure E implements Comparable and use compareTo()
<E extends Comparable>
if(element.compareTo(new Integer(elem))<0)

Java Recursive Merge Sort

Currently am struck on my recursive merge sorting program, I have been looking to see where the problem is and i cant seem to find it.
package mergesort;
import java.util.ArrayList;
public class MergeSort {
public MergeSort() {
// TODO Auto-generated constructor stub
}
public static <T extends Comparable<? super T>> void mergesort(T[] list, int n)
{
mergeSort(list,0,n-1);
}
static <T extends Comparable<? super T>>
void mergeSort(T[] tempArray, int firstHalfSorted, int secondHalfSorted){
T[] temp = (T[]) new Comparable <?>[tempArray.length];
mergeSort(tempArray, temp, firstHalfSorted, secondHalfSorted);
}
private static <T extends Comparable<? super T>>
void mergeSort (T[ ] tempArray, T[] a, int firstHalfSorted, int secondHalfSorted){
if (firstHalfSorted < secondHalfSorted)
{
int mid = (firstHalfSorted + secondHalfSorted) / 2;
mergeSort(tempArray,a,firstHalfSorted, mid);
mergeSort(tempArray,a,mid+1, secondHalfSorted);
if(tempArray[mid].compareTo(tempArray[mid+1])>0)
merge(tempArray,a,firstHalfSorted, mid, secondHalfSorted);
}
}
private static <T extends Comparable<? super T>>
void merge(T[] a, T[] tempArray, int firstHalfSorted, int mid, int secondHalfSorted)
{
int bhalf1 = firstHalfSorted;
int ehalf1 = mid;
int bhalf2 = mid + 1;
int ehalf2 = secondHalfSorted;
int j = 0;
for(;(bhalf1 <= ehalf1) && (bhalf2 <= ehalf2); j++)
{
if (a[bhalf1].compareTo(a[bhalf2]) < 0)
{
tempArray[j] = a[bhalf1];
bhalf1++;
}
else
{
tempArray[j] = a[bhalf2];
bhalf2++;
}
for(;bhalf1 <= ehalf1; bhalf2++, j++)
tempArray[j] = a[bhalf1];
for(;bhalf2 <= ehalf2; bhalf2++, j++)
tempArray[j] = a[bhalf2];
for(j = firstHalfSorted; j <= secondHalfSorted; j++)
a[j] = tempArray[j];
}
}
}
here is the sample of what should be happening
Before sort:
Zeke
Bob
Ali
John
Jody
Jamie
Bill
Rob
Zeke
Clayton
After sort:
Ali
Bill
Bob
Clayton
Jamie
Jody
John
Rob
Zeke
Zeke
also my main driver i made is here also
package mergesort;
import java.util.ArrayList;
import java.util.Arrays;
public class Driver <T extends Comparable<? super T>>{
public Driver() {
// TODO Auto-generated constructor stub
}
public static <T> void main(String[] args) {
String array[] = new String[] {"Zeke,"Bob","Ali","John","Jody","Jamie","Bill","Rob", "Zeke", "Clayton"};
MergeSort sortList = null;
sortList.mergeSort(array,0,10);
for(int a=0;a<array.length;a++)
System.out.println(array[a]);
}
}
Your merge method has many problems.
Take every for loop in there and write a 1-line comment describing what it's supposed to do.
Do not declare a variable (like j) and then reuse it for multiple loops. Confine the loop variable to the loop scope, e.g. for (int j = ..; .. ; ..).
Correct your indentation and make sure that the nested loops were really meant to be nested.
Write a few test cases for merge method and test just that method separately from all the recursion.

Java Generics Bound mismatch

Here is a implementation of a generic search algorithm:
The interface:
public interface Comparable<T extends Comparable<T>> {
int compare(T arg);
}
CompareSort.java
public abstract class CompareSort<T extends Comparable<T>> {
protected boolean less(T v, T w) {
return (v.compare(w) < 0);
}
protected void swap(T[] args, int i, int j) {
T swap = args[i];
args[i] = args[j];
args[j] = swap;
}
public abstract void sort(T[] args);
}
One of the algorithm:
public class SelectionSort <T extends Comparable<T>> extends CompareSort<T> {
#Override
public void sort(T[] args) {
int N = args.length;
for (int i = 0; i < N; i++) {
int min = i;
for (int j = i + 1; j < N; j++) {
if (less(args[j], args[min])) {
min = j;
}
}
swap(args, i, min);
}
}
}
And finally a main method to sort Strings.
public class StringSorter {
public static <T extends Comparable<T>> void main(String[] args) throws IOException {
ArrayList<String> list = new ArrayList<String>();
int i = 0;
while (i < 10) {
Scanner s = new Scanner(System.in);
String str = s.nextLine();
list.add(str);
i++;
}
String[] a = list.toArray(new String[list.size()]);
// Create a sort object, use it on a, and print the sorted array.
SelectionSort<String> selection = new SelectionSort<String>();
selection.sort(a);
for (i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}
Here is the problem:
SelectionSort<String> selection = new SelectionSort<String>();
Bound mismatch: The type String is not a valid substitute for the bounded parameter (T extends Comparable(T)) of the type SelectionSort(T)
(box brackets = curved brackets)
Where is the problem? I can not figure it out...
the generic parameter T is extended as well.
Instead of creating your own Comparable, which String does not implement, use Java's java.lang.Comparable, which String does implement.

compareTo with generics for heapSort

For class I had to either implement a BST or a heapSort. I did the BST but figured it would be good to know this too but now I'm stuck. This is my first time working with heaps(and really coding with generics/implementing Comparable so I apologize for all the errors) and im running into an issue implementing compareTo.
Essentially I want to be able to add generic objects to my heap Array and then compare them for the Heap sorting. I use compareTo to check a new entry when adding to the heap and for swapping in the reheap method.
My errors returned:
Heap.java:64: error: bad operand types for binary operator '<'
if (this < other)
^
first type: Heap<T>
second type: Heap<T>
where T is a type-variable:
T extends Comparable<T> declared in class Heap
Im not sure how to work around that though. I understand that my binary operator isnt for generics but I dont know how to work around it.
Thanks for any input. Sorry about all the beginners mistakes you may find!
Heres my code:
import java.util.*;
class Heap<T extends Comparable <T>> implements Comparable<Heap<T>>{
private T[] heap;
private int lastIndex;
private static final int CAPACITY = 25;
public Heap(){
this(CAPACITY);
}
public Heap(int capacity){
heap = (T[])new Comparable[capacity+1];
lastIndex = 0;
}
public void add(T newEntry){
lastIndex++;
if(lastIndex>=heap.length)
doubleArray();
int newIndex = lastIndex;
int parentIndex = newIndex/2;
while((parentIndex>0)&&(heap[parentIndex].compareTo(newEntry)>0))
{
heap[newIndex] = heap[parentIndex];
newIndex = parentIndex;
parentIndex = newIndex/2;
}
heap[newIndex] = newEntry;
}
public void display()
{
for(int i=1;i<heap.length;i++)
{
System.out.println(heap[i]);
}
}
private void doubleArray()
{
T[] oldHeap = heap;
int oldSize = heap.length;
heap = (T[]) new Object[2*oldSize];
for(int i =0; i < oldSize-1;i++)
{
heap[i] = oldHeap[i];
}
}
public int compareTo(Heap<T> other)
{
int sort = 0;
if (this < other)
{
sort = -1;
}
else if (this> other)
{
sort = 1;
}
else
{
sort = 0;
}
return sort;
}
private <T extends Comparable<T>> void reheap(T[] heap, int rootIndex, int lastIndex)
{
boolean done=false;
T orphan = heap[rootIndex];
int leftChildIndex = 2 * rootIndex + 1;
while(!done && (leftChildIndex<=lastIndex))
{
int largerChildIndex = leftChildIndex;
int rightChildIndex = leftChildIndex + 1;
if(rightChildIndex<=lastIndex && (heap[rightChildIndex].compareTo(heap[largerChildIndex])>0))
largerChildIndex = rightChildIndex;
if(orphan.compareTo(heap[largerChildIndex])<0)
{
// System.out.println(orphan+ "--" + largerChildIndex);
heap[rootIndex] = heap[largerChildIndex];
rootIndex = largerChildIndex;
leftChildIndex = 2 * rootIndex+1;
}
else
done = true;
}
heap[rootIndex] = orphan;
}
public <T extends Comparable<T>> void heapSort(int n)
{
for(int rootIndex = n/2-1;rootIndex >=0;rootIndex--)
reheap(heap,rootIndex,n-1);
swap(heap,0,n-1);
for(int lastIndex = n-2;lastIndex > 0;lastIndex--)
{
reheap(heap,0,lastIndex);
swap(heap,0,lastIndex);
}
}
private <T extends Comparable<T>> void swap(T[] a,int first, int last)
{
T temp;
temp = a[first];
a[first] = a[last];
a[last] = temp;
}
}
Any help with any of this is very very appreciated
You don't want your heap to be Comparable; you want to compare its members. Therefore remove implements Comparable<Heap<T>> from your class declaration and remove the compareTo method.
Many of your methods (reheap, heapSort, swap) redundantly declare <T extends Comparable<T>> where you are already in the context of your class parameterized with T. Remove those declarations.
I think you need to implement the compareTo on you T object, not on the heap itself. You have to
make sure T is comparable for it to be in the heap.

Categories