2009-08-21 5 views
0

est-il possible de l'élément suivant pour revenir plusieurs éléments dans un appel (à savoir deux GRects) demandez-vousEst-il possible de renvoyer plusieurs articles en un seul appel?

private GObject getColidingObject(){ 
    if(getElementAt(ball.getX(), ball.getY()) != null){ 
     return getElementAt(ball.getX(), ball.getY()); 
    }else if(getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY()) != null){ 
     return getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY()); 
    }else if(getElementAt(ball.getX(), ball.getY() + BALL_RADIUS *2) != null){ 
     return getElementAt(ball.getX(), ball.getY() + BALL_RADIUS *2); 
    }else if(getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY() + BALL_RADIUS *2) != null){ 
     return getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY() + BALL_RADIUS *2); 
    }else{ 
     return null; 
    } 
} 

Répondre

9

Vous ne pouvez renvoyer qu'une seule valeur, mais peut faire de cette valeur un tableau. Par exemple:

private GObject[] getCollidingObjects() { 
    GObject[] ret = new GObject[2]; 

    ret[0] = ...; 
    ret[1] = ...; 
    return ret; 
} 

BTW, quand vous commencez à réutiliser la même expression plusieurs fois dans la même méthode, vous devriez penser à l'introduction d'une variable locale pour plus de clarté. Par exemple, considérez ceci au lieu de votre code d'origine:

private GObject getCollidingObject(){ 
    int x = ball.getX(); 
    int y = ball.getY(); 
    if (getElementAt(x, y) != null) { 
     return getElementAt(x, y); 
    } 
    if (getElementAt(x + BALL_RADIUS * 2, y) != null) { 
     return getElementAt(x + BALL_RADIUS * 2, y); 
    } 
    if (getElementAt(x, y + BALL_RADIUS * 2) != null) { 
     return getElementAt(x, y + BALL_RADIUS * 2); 
    } 
    if (getElementAt(x + BALL_RADIUS * 2, y + BALL_RADIUS * 2) != null) { 
     return getElementAt(x + BALL_RADIUS * 2, y + BALL_RADIUS * 2); 
    } 
    return null; 
} 

(Vous pouvez faire la même chose pour x + BALL_RADIUS * 2 et y + BALL_RADIUS * 2 ainsi.)

Vous pourriez aussi envisager quelque chose comme ceci:

private GObject getCollidingObject(){ 
    int x = ball.getX(); 
    int y = ball.getY(); 
    return getFirstNonNull(getElementAt(x, y), 
     getElementAt(x + BALL_RADIUS * 2, y), 
     getElementAt(x, y + BALL_RADIUS * 2), 
     getElementAt(x + BALL_RADIUS * 2, y + BALL_RADIUS * 2)); 
} 

private static getFirstNonNull(GObject... objects) { 
    for (GObject x : objects) { 
     if (x != null) { 
      return x; 
     } 
    } 
    return null; 
} 

(En C# il ya une meilleure façon de le faire avec l'opérateur de coalescence nulle, mais peu importe ...)

+0

+1 pour int x = ball.getX(); – extraneon

3

si votre fonction pourrait retourner plusieurs objets?

Je pense que la chose la plus simple à faire serait de retourner une liste ou un tableau d'objets dans votre fonction.

0

Non. Sauf s'il y a un GArray. Mais comme écrit, non. Il retournera un ou "zéro" (nul) objet.

4

Non, il est uniquement possible de renvoyer un élément de l'appel. Dans le code que vous avez posté, une seule des lignes getElementAt sera exécutée.

1

Vous pouvez retourner un tableau ou une liste de GRects. Ou, peut-être fournir un tableau ou une liste vide que la méthode pourrait remplir.

1

Renvoyez juste un tableau de deux GRect s.

-2

Une méthode ne peut avoir qu'un seul retour. Dès qu'un retour est trouvé, la méthode termine son exécution.

1

Oui et non. La réponse courte n'est pas la façon dont vous essayez de le faire ici.

Si vous voulez retourner deux choses, vous pouvez les encapsuler dans un objet qui peut être retourné comme une seule entité. Par exemple, une carte ou une autre collection devrait faire l'affaire. Alternative, vous pourriez retourner un tableau.

0

Il retournera toujours un objet. Cependant, cet objet peut être une classe conteneur héritant de GObject qui contient plusieurs objets, par ex. un GCompound.

2

Comme une collection de GObject?

private List<GObject>getColidingObject(){ 
    ... 
    List<GObject> colidingObjects = new ArrayList<GObject>(); 
    colidingObjects.add(...); 
    return colidingObjects; 
} 
0

Non, ce n'est pas le cas.

Une fonction Java a une seule valeur de retour.

Si vous avez vraiment besoin de retourner plusieurs valeurs, vous pouvez retourner une liste ou un tableau des valeurs comme ceci:

private List<GObject> getColidingObject() { 
     List<GObject> results = new ArrayList<GObject>(); 
     if(cond1()) { 
      results.add(getElementAt(....) ; 
     } else if(cond2()) { 
      results.add(getElementAt(....) ; 
     } else if (etc ... 

     return results; 
} 
+0

Dans presque toutes les langues, les fonctions n'ont qu'une seule valeur de retour. En fait, les seules langues que j'ai jamais vues avec plusieurs valeurs de retour * simultanées * sont Common Lisp et son ancêtre Lisp Machine Lisp. (Des fonctionnalités telles que "yield" de Python autorisent plusieurs valeurs de retour * asynchrones *.) – Ken

0

Si vous voulez retourner plus d'un élément du même type que vous avez toujours peut renvoyer une collection de ces objets. Si vous renvoyez toujours deux objets, un tableau peut être meilleur car il vous donne un accès trié rapide aux objets.

Si vous avez plusieurs valeurs et devez les retourner, vous devrez peut-être introduire un nouveau type d'objet pour stocker toutes les valeurs et retourner cet objet. C'est un très bon indice que vous avez tôt ou tard besoin de cet objet pour déplacer les données dans votre application si vous rencontrez de nombreux tableaux, des listes d'Intergers ou des paires.

0

Oui, mais cela va être un cauchemar pour quelqu'un de maintenir dans un environnement de production.

0

La réponse simple est "Non", vous ne pouvez avoir qu'une seule valeur de retour. Mais la majorité des affiches ont raison de dire que vous pouvez utiliser des collections pour retourner plusieurs choses. Je remarque que la plupart des gens semblent préconiser le retour d'une liste ou d'un objet de collection, ce qui fonctionne normalement, mais si votre problème est isolé dans une classe particulière que vous développez, vous pourriez également envisager de définir une classe interne de convience la vie plus facile. Ceci est un exemple tout à fait mort cérébrale, mais nous espérons qu'il obtient le point à travers:

public class InnerClassDemo 
{ 
    public static void main(final String[] args) 
    { 
     InnerClassDemo icd = new InnerClassDemo(); 

     Holder h = icd.getTwoRandomValues(); 
     System.out.println("Value 1 = " + h.getVal1()); 
     System.out.println("Value 2 = " + h.getVal2()); 
    } 

    public Holder getTwoRandomValues() 
    { 
     Random r = new Random(); 

     int x = r.nextInt(); 
     int y = r.nextInt(); 

     return(new Holder(x,y)); 
    } 

    private class Holder 
    { 
     private int val1; 
     private int val2; 

     public Holder() 
     { 
      this.val1 = 0; 
      this.val2 = 0; 
     } 

     public Holder(int val1,int val2) 
     { 
      this.val1 = val1; 
      this.val2 = val2; 
     } 

     public int getVal1() 
     { 
      return this.val1; 
     } 

     public void setVal1(int val1) 
     { 
      this.val1 = val1; 
     } 

     public int getVal2() 
     { 
      return this.val2; 
     } 

     public void setVal2(int val2) 
     { 
      this.val2 = val2; 
     } 
    } 
} 

Donc dans votre cas, juste faire une classe interne qui tient un couple GRects se passe autour de deux GRects à un moment va être une opération commune pour vous.

Questions connexes