views:

111

answers:

4

Hi all, I'm very new to Java programming language so this is probably dumb question but I have to ask it because I can't figure it out on my own. Here is the deal.

I want to create method which extracts certain object type from a list. So the method should receive List as argument, meaning list should contain either Object1 or Object2. I've tried like this :

   public Object1 extractObject(List<Object>){
    //some pseudo-code 
   ... loop trough list and check if list item is instance of object one return that instance
    }

The problem with declaring method with List<?> as method argument is that I receive compilation error from eclipse Syntax error on token ">", VariableDeclaratorId expected after this token.

How do I set the method signature properly to accept object types either Object1 or Object2 ? Thank you

This is my Code :

protected Object1 getObject1(List<Object> list){
        for(Object obj : list) {
            if(obj instanceof Object1) {
                return (Object1) obj;
            }
        }
        return null;
    }

Edit - what is the difference between these 2 :

public Object1 getObject1(List<Object> list){
        for(Object obj : list) {
            if(obj instanceof Object1) {
                return (Object1) obj;
            }
        }
        return null;
    }

public Object1 extractObject(List<Object> list, Class<Object1> type) {
    for(Object obj : list) {
        if(type.isInstance(obj)) {
            return (Object1)obj;
        }
    }
    return null; // no match found
}
+3  A: 
public Object1 extractObject(List<?> list){
    //some pseudo-code 
   ... loop trough list and check if list item is instance of object one return that instance
    return null;
}

You need a variable for your instance

And a return.

Michael B.
@Michael B. shoot this is it :D
London
@Michael B. is this ok with additional casting it won't compile other way
London
@London, it's normal that you need to Cast, you didn't pass the Class type to your list.
Michael B.
@Michael B. I can't pass Class type because I don't know which class type of this object is, I'm trying to extract it
London
@London this is why you need to do a cast.
Michael B.
+1  A: 

I'd do something like this - note, my syntax might be wrong, but the idea is the same.

// this works for any type - just pass in an Object1
public Object extractObject(List<?> list, Class clazz) {
    for(Object obj : list) {
        if(obj.getClass().equals(clazz) {
            return obj;
        }
    }
    return null; // no match found
}

And non-generic:

// this works for just one type
public Object1 extractObject(List<?> list) {
    for(Object obj : list) {
        if(obj.getClass().equals(Object1) {
            return obj;
        }
    }
    return null; // no match found
}

Tested the concepts with this driver:

public static void main(String[] args) {
    Class c = "".getClass();
    if("".getClass().equals(c)) System.out.println("true");
    else System.out.println("false");
}

From the comments, consider clazz.isAssignableFrom(otherClazz) as well.

glowcoder
@glowcoder is this ok with additional casting it won't compile other way
London
In the first snippet - can you do `obj instanceof clazz` and if so does it work as intended? Off the top of my head, I would have thought you need `clazz.isAssignableFrom(obj)`.
Andrzej Doyle
@glowcoder: -1 because you cannot do `obj instanceof [a Class object]`. This isn't possible. You have to do something like `if (clazz.isInstance(obj))` PS: The `instanceof` is two times with a lowercase character.
Martijn Courteaux
PS: See this topic: http://stackoverflow.com/questions/1920284/java-how-should-look-an-instanceof-method
Martijn Courteaux
As I clearly stated, the syntax may not be right, but the concept is. Yeah, I have a habit of camel casing by default, and instanceof isn't something I use all that often. -whoops- I'll fix the camel case.
glowcoder
I can also change it to use the .equals instead.
glowcoder
@Martijn Courteaux , @glowcoder take a look at my edit pls
London
+1  A: 

As you are using generics, you can do

public <T> T extractObject(List<?> list, Class<T> type) {
    for(Object obj : list) {
        if(type.isInstance(obj)) {
            return (T)obj;
        }
    }
    return null; // no match found
}

This will make the return type of your method the same as the type you are looking for.

Thanks to generics, we can use the same method to extract different types of objects:

Object1 object1 = extractObject(list, Object1.class);
Object2 object2 = extractObject(list, Object2.class);

This is preferred to hard-coding the type check by using obj instanceof Object1 since doing that would result in needing a distinct method per type, all of them almost identical apart from the return type and the instanceof check.

mdma
@mdma take a look at my edit pls
London
The difference is that you can use this method to retrieve both types. When you hardcode the instance check via instanceof, rather than Class.isInstance, you can only return one type. See my edit.
mdma
A: 

The difference between the two is nothing. According to the javadoc, This method is the dynamic equivalent of the Java language instanceof operator.

glowcoder