2

Hopefully another simple question that shouldn't be difficult, but I'm new to Java and struggling. I have a set setElements in a class classA, which is a set of anther class' objects (classB), that will always only contain two elements. What I need to do is prepare a method that takes an argument, then checks if either element of setElements is equal to that argument. If one element is equal, the method returns the other element from the set.

I'm just really struggling to get the functionality out and I'm fairly certain it's due to my mediocre Java skills :)

This is the code I have now:

Set<classB> setElements = new HashSet<classB>();
 public classA(classB x, class B y) {
        setElements.add(x);
        setElements.add(y);


\\method to return the other element if one element is equal to argument

public classB otherElement(classB argument){
    for (classB x:setElements){
        if (x==argument){
            return \\other element in setElements} } }

Please help!

flexcookie
  • 113
  • 1
  • 3
  • 12

4 Answers4

0

If your Set always contains exactly two elements, you could convert it to an array, then use an indexed loop:

public classB otherElement(classB argument) {

    classB[] arrayElements = new classB[2];
    setElements.toArray(arrayElements);

    for (int i=0; i<arrayElements.length; i++) {
        if (arrayElements[i] == argument) {
            return setElements[1-i];
        }
    }
}
starf
  • 1,063
  • 11
  • 15
  • Why don't you use `arrayElements.length` instead of `2`? Why would use a `Set` in the first place if you only have 2 elements. – martijnn2008 Mar 30 '16 at 17:59
  • @martijnn2008 Edited to use .length. But as stated, this assumes (as in the question) that there will always be exactly 2 items. – starf Mar 30 '16 at 18:02
  • Thank you, I appreciate the comments. The learning curve for Java is slightly steep and you guys are an invaluable resource :) – flexcookie Mar 30 '16 at 18:12
0

I do not know why this approach is being modeled as a Set. If the elements must be unique, then using a List would be easier. Nonetheless, assuming there are two elements in a Set, then one could iterate the Set, keeping track of what was found. Something like:

public classB getOtherFromSet(classB arg)
{
   // setElements is the set of elements, with two entries
   classB otherVal = null;
   for (classB x : setElements) {
     if (! (x.equals(arg)) {
       otherVal = x;
     }
   }

   return otherVal;
}

Note it could return null if the Set only contained a value equal to the argument.

As an aside, it would be best if Java conventions about class names were followed.

KevinO
  • 4,303
  • 4
  • 27
  • 36
  • Thank you, I appreciate the comments. The learning curve for Java is slightly steep and you guys are an invaluable resource :) – flexcookie Mar 30 '16 at 18:11
0

First of all you can't put the elements in your HashSet directly from your class. You have to do in in some method as follows:

public void init() {
    setElements.add(x);
    setElements.add(y);
}

As per your requirements I would suggest you to use an ArrayList instead of a HashSet.

Here is the code snippet:

public classA(classB x, classB y) {

    private List<classB> setElements = Arrays.asList(x, y);

    public classB otherElement(classB argument) {
        if(0 == setElements.indexOf(argument)) {
            return setElements.get(1);
        }
        return setElements.get(0);
    }
}
user2004685
  • 9,548
  • 5
  • 37
  • 54
0

The elements in a generic Set do not have any defined order, so technically there's no "first" nor "second" element. But in your case the task is clear.

If you are sure that the set always contains exactly two elements, then you could do all the work without loops and conversions:

public classB otherElement(classB argument){
    Iterator<classB> iterator = setElements.iterator();
    classB first = iterator.next(); 
    classB second = iterator.next(); 
    if (first.equals(argument))
        return second;
    if (second.equals(argument))
        return first;
    return null;
}

If you are also sure that the argument will always be equal to either "first" or "second" element, then you could express this even simpler:

public classB otherElement(classB argument){
    Iterator<classB> iterator = setElements.iterator();
    classB first = iterator.next(); 
    return first.equals(argument) ? iterator.next() : first;
}

The usage of Set is very questionable in this case, actually. I would recommend to create a method with three arguments instead. Please compare the readability of this method to the previous two:

public classB otherElement(classB argument, classB first, classB second){
    return first.equals(argument) ? second : first;
}

Please also note that in most cases objects should be compared via .equals() rather than ==.

Community
  • 1
  • 1
Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
  • Excellent, I think this is what I was looking for. I originally tried using next() but obviously got the syntax wrong. I appreciate it! After everyone's comments, I think I will definitely ditch the Hashset in this case :) – flexcookie Mar 30 '16 at 18:13