2

I am still new to Generics and I am wondering why I can't do "if(b[m] > key)" its probably something very simple and I'm too tired to notice. But As you can see I am trying to find a certain number in an array of integers. What am I doing wrong? It has to be a generic method.

public class Question1<T>
{    
/**
 * This method searches through the array of integers to check if they match the key.
 * @param b array
 * @param key certain number
 */
public static <T> void search(T[] b,T key)
{
   int l = 0; 
    int r = b.length - 1;
    while (l <= r)
    {
        int m = (l + (r-l)/2);
        if(b[m].equals(key))
            System.out.println("Key: " + key.toString()+ " is in Element: " + m);

        if (b[m] > key)
        {
            l = m + 1;
        }
        else
        {
            r = m - 1;
        }
    }
    System.out.println("Not in array.");        
}
public static void main(String[] args)
{

    Integer[] iray = {1,2,3,4,5};
    int key = 4;
    search(iray,key);
}
1
  • You can't compare objects with >. Commented Apr 20, 2018 at 6:44

2 Answers 2

1

In Java, Generics are not usable with primitives types (int, double, etc.), but only with Objects (Integer, Double, etc.). The boxed numbers (int --> Integer) cannot use comparison operator (except == but its behavior is not the one you want in that case). To resolve your problem, you have two solutions:

Make your T generic be a comparable (by defining ). Once done, replace

b[m].equals(key)

with

key.compare(b[m]) < 0

Note that it's not very optimized, due to the boxing of each value in your array. That's a troublesome limitation of Java. Currently, there's a work in progress to attempt to resolve the problem, and allow generics to be used with primitive values. It's called the Valhalla project.

If you want optimized solution, you're forced to adopt the same strategy as in standard java.util.Arrays class : duplicate your etod for each primitive type, without using generics.

Hope it helps !

Sign up to request clarification or add additional context in comments.

Comments

0

The error occurs because T can literally be any reference type. Let's say T is now java.util.UUID or java.util.Scanner or java.util.List. Objects of these types cannot be compared by >. Some can't even be compared at all.

So what you need to do is to constrain the generic parameter T to types that can be compared:

public static <T extends Comparable<T>> void search(T[] b,T key)
                 ^^^^^^^^^^^^^^^^^^^^^

Now, you can call compareTo on b[m] to compare them. The method will return a positive result if b[m] is greater than the parameter:

if (b[m].compareTo(key) > 0)

Alternatively, you can add a new Comparator parameter to let callers of this method specify how they want the objects to be compared:

public static <T> void search(T[] b,T key, Comparator<? super T> comparator)

Then the comparison line will become:

if (comparator.compare(b[m], key) > 0)

Also, you seem to have (accidentally?) made Question generic. That is unnecessary unless you have some code not shown that is using it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.