6

I've been staring at the screen the last 5 minutes and can't seem to figure out what I'm doing wrong:

class Example {

    private final Set<String> values;

    public Example(String... values) {
        values = new HashSet<String>(Arrays.asList(values));
    }
}

I'm surprised why the String[] cannot be converted to List<String> to initialize the HashSet<String> with it.

I'm getting the build error:

incompatible types: java.util.HashSet<java.lang.String> cannot be converted to java.lang.String[]

What's wrong with my assignment?

7
  • 8
    The values parameter inside of your constructor is shadowing the class field values. Commented Dec 19, 2014 at 20:44
  • As @ajp15243 said. You can fix it by assigning to this.values, or by changing the name of the constructor argument. Commented Dec 19, 2014 at 20:45
  • 2
    @AbhijeetKushe that make a nice answer Commented Dec 19, 2014 at 20:50
  • Correct answers were already given so I thought I will make a comment Commented Dec 19, 2014 at 20:52
  • @AbhijeetKushe You're making a good point which I would definitely upvote, but it's up to you Commented Dec 19, 2014 at 20:53

4 Answers 4

9

You're missing a qualification to actually access the private field. Currently you're trying to reassign the parameter passed to the constructor. Instead you should use the following code:

public Example(String... values) {
     this.values = new HashSet<String>(Arrays.asList(values));
}

This can be shortened even further by using the "Diamond Operator", which is avaliable since Java 7:

public Example(String... values) {
     this.values = new HashSet<>(Arrays.asList(values));
}
Sign up to request clarification or add additional context in comments.

1 Comment

Facepalm... Thanks Vogel!
3

This is how you can do it

 if(values != null)
      this.values = new HashSet<>(Arrays.asList(values));
 else
      this.values = Collections.emptySet();

Add the if(values != null) check before the assignment.Whenever you use var args you are exposing a contract which will permit your clients to create an valid Example object without any arguments.If you want to avoid that from happening then just use String[] values directly and throw an exception incase if it is null

2 Comments

You're right that I should validate my inputs, excellent point. Actually I think throwing IllegalArgumentException might be best for a null arg.
Yeah IllegalArgumentException would be ideal if use Sting[] values as the parameter
3

Other answers have addressed the cause, but wouldn't it be better to simply rename the parameter to avoid the shadowing?

1 Comment

Good point. I wouldn't have been in this situation in the first place.
0

Use this.values inside a constructor in place of value because the parameter of constructor is string array and you are trying to convert a List to array.

this.values = ......

2 Comments

I don't understand how you ended at the correct result with such a wretched premise... Your logic is... abysmal
@Vogel612 perhaps the formulation of this answer is a bit confusing, but the conclusion seems to be totally correct.

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.