Java Generics Bound mismatch - java

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.

Related

error incompatible types: Comparable<T> cannot be converted to T

I'm not sure what is going on.
The method works pereclty with an array but if I use a list... well.
I really hope you can help me.
public static <T> void ordenaSeleccion(List<? extends Comparable<T>> datos)
{
Object aux;
int menor;
for (int i = 0; i < datos.size(); i++) {
menor = i;
for (int j = i + 1; j < datos.size(); j++) {
if (datos.get(menor).compareTo(datos.get(j)) > 0) { //error line
menor = j;
}
}
if (menor != i) {
aux = datos.get(i);
datos.set(i, datos.get(menor));
datos.set(menor, aux);
}
}
}
this is the error:
List<? extends Comparable<T>> only says that the elements of the list can be compared with instances of T, not that they are subclasses of T. That's why you get your error message.
Could you change your implementation as follows:
public static <T extends Comparable<T>> void ordenaSeleccion(List<T> datos)
{
T aux;
int menor;
for (int i = 0; i < datos.size(); i++) {
menor = i;
for (int j = i + 1; j < datos.size(); j++) {
if (datos.get(menor).compareTo(datos.get(j)) > 0) { //error line
menor = j;
}
}
if (menor != i) {
aux = datos.get(i);
datos.set(i, datos.get(menor));
datos.set(menor, aux);
}
}
}
Let's assign types to each of these:
Comparable<T> m = datos.get(menor);
Comparable<T> mj = datos.get(j);
if ((m).compareTo(mj) > 0) { //error line
The Comparable<T> interface expects a T, not a Comparable<T>, as its parameter.
Your signature should instead be:
public static <T extends Comparable<T>> void ordenaSeleccion(List<T> datos)

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.

Refactoring a nested loop

I have the following code which I use a lot of times in the class.
for (int i = 0; i < someList.size(); i++) {
for (int j = 0; j < someList.size(); j++) {
if (i != j) {
someList.get(i).sendMessageTo(someList.get(j))); //variable action
}
}
}
The purpose of the loop is to make each element in the List to send a message (or perform another action) to every element in the list except itself.
Is there any way I can create a helper method so I don't have to repeat the loop code.
Edit:
I need just one helper method to take care of the for loop and the if algorithm. I will supply the List and the whatever action I need to use. It should work for all.
I want to be able to state the variable action and call the helper method.
Thanks.
You could do something like (I don't know what type is in your List, I called it Element):
public interface ApplySomeAction
{
public apply(Element e1, Element e2);
}
...
public void applyActionToAllElements(ApplySomeAction action)
{
for (int i = 0; i < someList.size(); i++) {
for (int j = 0; j < someList.size(); j++) {
if (i != j) {
action.apply(someList.get(i), someList.get(j));
}
}
}
}
later call it with:
applyActionToAllElements(new ApplySomeAction() {
public apply(Element e1, Element e2)
{
e1.sendMessageTo(e2));
}
};
Could make another interface+method with just one element if you often do an action with just one of those elements.
You could maybe get rid of one of the loops by doing it this way:
for (int i = 0; i < someList.size() - 1; i++) {
someList.get(i).sendMessageTo(someList.get(i + 1))); //variable action
}
And use #NESPowerGlove's solution to abstract the method that's called.
I'd make me an Iterable
/**
* Returns all pairs of the list except those where i == j.
* #param <T>
*/
public class AllPairs<T> implements Iterable<Pair<T, T>> {
// The list.
private final List<T> list;
public AllPairs(List<T> list) {
this.list = list;
}
#Override
public Iterator<Pair<T, T>> iterator() {
return new PairIterator();
}
private class PairIterator implements Iterator<Pair<T, T>> {
// The indexes.
int i = 0;
int j = 0;
// The next to return.
Pair<T, T> next = null;
// Easier to read.
int size = list.size();
#Override
public boolean hasNext() {
while (next == null && (i < size || j < size)) {
// Step j.
j += 1;
// Wrap j.
if (j >= size && i < size) {
j = 0;
i += 1;
}
if (i < size && j < size && j != i) {
// Grab it.
next = new Pair<>(list.get(i), list.get(j));
}
}
return next != null;
}
#Override
public Pair<T, T> next() {
Pair<T, T> it = next;
next = null;
return it;
}
}
}
/**
* A simple Pair
*/
public static class Pair<P, Q> {
public final P p;
public final Q q;
public Pair(P p, Q q) {
this.p = p;
this.q = q;
}
}
public void test() {
System.out.println("Hello");
List<Integer> l = Arrays.asList(0, 1, 2, 3);
for (Pair<Integer, Integer> p : new AllPairs<>(l)) {
System.out.println("[" + p.p + "," + p.q + "]");
}
}
Then define an interaction mechanism - this would be almost trivial using Lambdas:
// Objects that can interact with each other.
public interface Interacts<T extends Interacts<T>> {
public void interact(T with);
}
public static <T extends Interacts<T>> void interactAllPairs(List<T> l) {
// Interact all pairs.
for (Pair<T, T> p : new AllPairs<>(l)) {
p.p.interact(p.q);
}
}
Then you can make your message objects interact - here's a simple example:
// Interact by sending a message.
public class Messenger implements Interacts<Messenger> {
private final int me;
public Messenger(int me) {
this.me = me;
}
#Override
public void interact(Messenger with) {
sendMessage(with);
}
public void sendMessage(Messenger to) {
System.out.println(this + "->" + to);
}
#Override
public String toString() {
return Integer.toString(me);
}
}
Testing now looks like:
public void test() {
// Meassage list.
List<Messenger> messages = new ArrayList<>();
for (int i = 0; i < 4; i++) {
messages.add(new Messenger(i));
}
interactAllPairs(messages);
}
giving your required output:
0->1
0->2
0->3
1->0
1->2
1->3
2->0
2->1
2->3
3->0
3->1
3->2

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

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?

Java constructor question

How do I write a constructor to change ints to ints or longs or strings....I am making a Memory system and I have code for Memory and a Memory Element (MemEl) and my test code and I am trying to write these constructors: MemEl(int), MemEl(long), MemEl(String) I already have done it for shorts and bytes but I need some help with these. Thanks.
Here is my Memory code:
class Memory{
private MemEl[] memArray;
private int size;
public Memory(int s)
{size = s;
memArray = new MemEl[s];
for(int i = 0; i < s; i++)
memArray[i] = new MemEl();
}
public void write (int loc, int val)
{if (loc >=0 && loc < size)
memArray[loc].write(val);
else
System.out.println("Index Not in Domain");
}
public MemEl read (int loc)
{return memArray[loc];
}
public void dump()
{
for(int i = 0; i < size; i++)
if(i%1 == 0)
System.out.println(memArray[i].read());
else
System.out.print(memArray[i].read());
}
}
Here is my Memory Element Code:
class MemEl{
private int elements;
public Memory MemEl[];
{
elements = 0;
}
public void MemEl(byte b)
{
elements = b;
}
public void MemEl(short s)
{
elements = s;
}
public int read()
{
return elements;
}
public void write(int val)
{
elements = val;
}
}
Here is my Test code
class Test{
public static void main(String[] args)
{
int size = 100;
Memory mymem;
mymem = new Memory(size);
mymem.write(98,4444444);
mymem.write(96,1111111111);
MemEl elements;
elements = mymem.read(98);
System.out.println(mymem);
mymem.dump();
}
}
If you can afford to lose precision, then you can cast:
public MemEl(long longValue) {
elements = (int) longValue;
}
and parse:
public MemEL(String str) {
elements = Integer.parseInt(str);
}
elements is an int. byte and short can be cast implicitly (without you knowing) to int. long and String can't, hence you will not be able to add a constructor to the MemEl class

Categories