19

I'm new to Java so I'm probably doing something wrong here, I want to create an array of Sets and I get an error (from Eclipse). I have a class:

public class Recipient 
{
String name;
String phoneNumber;

public Recipient(String nameToSet, String phoneNumberToSet)
{
    name = nameToSet;
    phoneNumber = phoneNumberToSet;
}

void setName(String nameToSet)
{
    name = nameToSet;
}

void setPhoneNumber(String phoneNumberToSet)
{
    phoneNumber = phoneNumberToSet;
}

String getName()
{
    return name;
}

String getPhoneNumber()
{
    return phoneNumber;
}
}

and I'm trying to create an array:

Set<Recipient>[] groupMembers = new TreeSet<Recipient>[100]; 

The error I get is "Cannot create a generic array of TreeSet"

What is wrong ?

2

5 Answers 5

22

From http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html:

you cannot instantiate an array of a generic type (new List<String>[3] is illegal), unless the type argument is an unbounded wildcard (new List<?>[3] is legal).

Rather than using an array, you can use an ArrayList:

List<Set<Recipient>> groupMembers = new ArrayList<Set<Recipient>>();

The code above creates an empty ArrayList of Set<Recipient> objects. You would still have to instantiate every Set<Recipient> object that you put into the ArrayList.

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

3 Comments

I don't understand the first part of the answer: you wrote List[3] is both legal and illegal. what is the meaning of "unbounded wildcard " ?
Apologies, stackoverflow was interpreting the generics (e.g. <String>) as HTML tags. I have fixed the formatting.
thanks. I think you are missing > in <Set<Recipient>, but its a very good answer. +1
0

Arrays don't support Generics. Use an ArrayList:

ArrayList<Set<Recipient>> groupMembers = new ArrayList<Set<Recipient>>();

Comments

0

You might want to consider using Guava's Multimap where the key is the index. This will handle creating the Sets for each index as you need them.

SetMultimap

SetMultimap<Integer, Recipient> groupMembers;

Comments

0

In that specific case, the number of groups being variable, it is certainly better to use an ArrayList or some other collection type instead of an array.

But if for some reason an array of size 100 is really what you need, you can do as follows:

@SuppressWarnings("unchecked")
Set<Recipient>[] groupMembers = (Set<Recipient>[])new Set<?>[100];

You should not create a TreeSet<?>[] and assign it to a Set<?>[] because that would not be typesafe. The compiler would allow to store, say, a HashSet in the array but at runtime it would be rejected with an exception.

Note that the array is still empty at this point, the actual Sets need to be created:

groupMembers[0] = new TreeSet<>();
groupMembers[0].add(new Recipient("John", "123-45-67"));
groupMembers[0].add(new Recipient("Doe", "987-65-43"));

Comments

0

First, your syntax is incorrect. Second, your class must implement the Comparable interface or pass a Comparator to use when you assign each TreeSet<>.

  • The first set uses the Recipient's implemented Comparable<T> interface and sorts on the name.
  • The second set uses a supplied Comparator to sort on the phone number.
class Recipient implements Comparable<Recipient> {
    String name;
    String phoneNumber;
   
    // existing code here.

    //Comparable implementation to sort on name
    @Override
    public int compareTo(Recipient r) {
        return name.compareTo(r.name);
    }
}

@SuppressWarnings("unchecked")
Set<Recipient>[] groupMembers = new TreeSet[2];

groupMembers[0] = new TreeSet<>();
groupMembers[0].add(new Recipient("Mary", "555-1212"));
groupMembers[0].add(new Recipient("Bob", "555-1213"));
groupMembers[0].add(new Recipient("John", "555-1214"));

groupMembers[1] = new TreeSet<>(Comparator.comparing(Recipient::getPhoneNumber));
groupMembers[1].add(new Recipient("Phil", "444-9999"));
groupMembers[1].add(new Recipient("Jane", "444-8888"));
groupMembers[1].add(new Recipient("Simon", "444-7777"));

for (Set<Recipient> group : groupMembers) {
    for (Recipient r : group) {
        System.out.println(r.getName() + " " + r.getPhoneNumber());
    }
    System.out.println();
}

prints (first set sorting on name, next set on phone number)

Bob 555-1213
John 555-1214
Mary 555-1212

Simon 444-7777
Jane 444-8888
Phil 444-9999

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.