5

Why am I getting these 4 warnings from -Xlint and what should I do about them? I'm just starting in Java, so am likely missing something obvious.

import java.util.*;

class CompareGerbils implements Comparator {
    public int compare(Object o1, Object o2) {
       return ((Gerbil)o2).number() - ((Gerbil)o1).number();
    }
}

class Gerbil {
int gerbilNumber;

Gerbil(int gN) {
    gerbilNumber = gN;
    }

int number() {
    return gerbilNumber;
    }
}

public class lt {
    public static void main(String[] args) { 

    // I'd like to be able to add both ints and strings to list
    ArrayList list = new ArrayList();

    //unchecked call warning:
    list.add(1);  

    //unchecked call warning:
    list.add("b");  

    ArrayList<Gerbil> gerbillist = new ArrayList<Gerbil>();

    for(int i = 0; i < 5; i++) {
        gerbillist.add(new Gerbil(i));
    }

    //unchecked conversion warning
    //unchecked method invocation
    Collections.sort(gerbillist, new CompareGerbils());
  }
}

EDIT: replies so far have answered the Arraylist declaration. How about the sort warnings at the bottom of the code? thanks

foosion
  • 7,619
  • 25
  • 65
  • 102
  • 1
    Someone else answered while I was typing, but I'd like to make a style note. Your Comparator impl is named improperly and should begin with a capital letter. Not meaning to be pedantic, but you'll go crazy someday maintaining this code wondering why the type argument for a variable declaration seems to be a variable. – Mike Yockey Feb 28 '11 at 14:04
  • 3
    Please be pedantic. As I mentioned, I'm just learning. I'll make the change. – foosion Feb 28 '11 at 14:05
  • 3
    `// I'd like to be able to add both ints and strings to list` - That's typically a design flaw. Why are you trying to create a collection with fundamentally different kinds of things in it? – Mark Peters Feb 28 '11 at 14:15
  • the sort warning is because you've defined the Comparator with no data type, i.e. `new Comparator()` instead of `new Comparator()`. I've updated my answer to reflect the correct usage. – Lucas Zamboulis Feb 28 '11 at 14:25
  • @Mark Peters: I'm just learning at the moment. All the examples I've seen cast to a single type, so I wanted to see if the language had this flexibility. – foosion Feb 28 '11 at 14:34

4 Answers4

7

You're getting this because you have not defined a data type for the ArrayList list. The only way to add both Strings and Integers in list without getting warnings is by defining it as ArrayList<Object> list - which is what happens here implicitly (line list.add(1); is implicitly converting 1 to new Integer(1) - this is called autoboxing). Also note that if you want to have both Strings and Integers in lists, the sorting method does not really make sense - how are you expecting things to get sorted, alphabetically or numerically?

Edit: Also, it is not considered good practice to declare a concrete type (i.e. ArrayList<Object> list) unless you have very good reasons to do so. It is recommended that you initialise using an interface, i.e. List<Object> list.

So, your code would have to be like this (note the part Comparator<Gerbil> which fixes the warning in Collections.sort):

// I'd like to be able to add both ints and strings to list
List<Object> list = new ArrayList<Object>();

list.add(new Integer(1));  

list.add(new String("b"));  

List<Gerbil> gerbillist = new ArrayList<Gerbil>();

for(int i = 0; i < 5; i++) {
    gerbillist.add(new Gerbil(i));
}

Collections.sort(gerbillist, new Comparator<Gerbil>() {
    public int compare(Gerbil o1, Gerbil o2) {
        int diff = o1.getNumber() - o2.getNumber();
        if (diff > 0)
           return 1;
        else if (diff <0)
           return -1;
        else
           return 0;
    }
});

With respect to the Gerbil class, I suggest you use the form getNumber as a method name rather than number - it's a de facto standard for method names to retrieve the value of a member variable (and, respectively setNumber(int value) for setting it):

class Gerbil {
int gerbilNumber;

Gerbil(int gN) {
    gerbilNumber = gN;
    }

int getNumber() {
    return gerbilNumber;
    }
}
Lucas Zamboulis
  • 2,494
  • 5
  • 24
  • 27
3

The warning occurs when you are using a non-generic type in a context where a generic is expected. The compile is saying, you might be right, but I cannot check the type for you.

You cna either;

  • Make the type the correct generic.
  • Turn off the warning with @SuppressWarnings
  • Ignore the warning.

EDIT: In this example, you have to pick a super class/interface of the elements in the list.

// I'd like to be able to add both ints and strings to list
List<Object> list = new ArrayList<Object>();

list.add(1);  
list.add("b");  

Instead of Object you could pick Seralizable or Comparable however eneither is likely to be useful. Indeed a List<Object> is rarely useful except in exercises.

The correct way to implement the Comparator is to use comparison. Using - is only valid if you know this cannot possibly overflow. e.g. 2000000000 - -2000000000 < 0 whereas you might expect 2000000000 - -2000000000 > 0

class CompareGerbils implements Comparator<Gerbil> {
    public int compare(Gerbil a, Gerbil b) {
       return a.number() > b.number() ? +1 
            : a.number() < b.number() ? -1 : 0;
    }
}

For testing purposes I suggest trying to sort a List which is not already sorted. A simple way to do this is to use the shuffle() method. This could still be sorted but the large the list, the less likely that is the case.

Collections.shuffle(gerbillis);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2
    I'd like to understand the warnings rather than ignore or suppress them. How do I make the type the correct generic? – foosion Feb 28 '11 at 14:03
  • Good point on the comparison, although I've been using 'a - b' in other languages for years without an issue (and thought it a common idiom). On reflection, a > b is clearer, which is a virtue. – foosion Feb 28 '11 at 14:41
2
public static void main(String[] args) {
    final List<Object> list = new ArrayList<Object>();
    list.add(1);
    list.add("b");

    final List<Gerbil> gerbillist = new ArrayList<Gerbil>();
    for (int i = 0; i < 5; i++) {
        gerbillist.add(new Gerbil(i));
    }

   Collections.sort(gerbillist, new CompareGerbils());
}
Paul McKenzie
  • 19,646
  • 25
  • 76
  • 120
1
  1. you need to know Generics http://download.oracle.com/javase/1.5.0/docs/guide/language/generics.html

  2. you are trying to add primitive and a string in arraylist. either u do this to take anything

List<Object> list = new ArrayList<Object>();

or if you want to allow only strings

 List<String> list = new ArrayList<String>();  
Dead Programmer
  • 12,427
  • 23
  • 80
  • 112