web-dev-qa-db-fra.com

Renvoyer différents types de données d'une méthode en Java?

public static void main(String args[]) {
    myMethod(); // i am calling static method from main()
 }

.

public static ? myMethod(){ // ? = what should be the return type
    return value;// is String
    return index;// is int
}

myMethod() retournera String et int value. Alors, prenez ces valeurs de retour de main(). Je suis venu avec la solution suivante. 

créer un appel de classe ReturningValues

public class ReturningValues {
private String value;
private int index;

// getters and setters here
}

et changez myMethod() comme suit. 

 public static ReturningValues myMethod() {
    ReturningValues rv = new ReturningValues();
    rv.setValue("value");
    rv.setIndex(12);
    return rv;
}

Maintenant ma question, y at-il un moyen plus facile de réaliser ceci? 

23

Enfin, je pensais que mon chemin était meilleur puisque, lorsque le nombre de types de retour augmentait, ce type d'implémentation le faisait de la meilleure façon.

public static ReturningValues myMethod() {
ReturningValues rv = new ReturningValues();
rv.setValue("value");
rv.setIndex(12);
return rv;
}

Les méthodes Java ne peuvent renvoyer qu'un seul résultat (void, une primitive ou un objet), et la création d'une classe struct- type est la suivante.

En remarque, il est souvent possible de rendre des cours comme votre ReturningValues immuables comme ceci:

public class ReturningValues {
    public final String value;
    public final int index;

    public ReturningValues(String value, int index) {
        this.value = value;
        this.index = index;
    }
}

Cela présente l'avantage qu'une ReturningValues peut être transmise, par exemple entre les threads, sans aucune inquiétude quant à la désorganisation accidentelle de certains éléments.

17
chrylis

Je crée différents types de retour en utilisant Enum. Cela ne se définit pas automatiquement. Cette mise en œuvre ressemble à un motif d'usine.

public  enum  SmartReturn {

    IntegerType, DoubleType;

    @SuppressWarnings("unchecked")
    public <T> T comeback(String value) {
        switch (this) {
            case IntegerType:
                return (T) Integer.valueOf(value);
            case DoubleType:
                return (T) Double.valueOf(value);
            default:
                return null;
        }
    }
}

Test de l'unité:

public class MultipleReturnTypeTest {

  @Test
  public void returnIntegerOrString() {
     Assert.assertTrue(SmartReturn.IntegerType.comeback("1") instanceof Integer);
     Assert.assertTrue(SmartReturn.DoubleType.comeback("1") instanceof Double);
  }

}
17
Wendel

En règle générale, si vous n'êtes pas sûr de la valeur à renvoyer, vous devriez envisager d'utiliser return-type comme super-classe de toutes les valeurs de retour. Dans ce cas, où vous devez renvoyer String ou int, envisagez de renvoyer la classe Object (la classe de base de toutes les classes définies en Java).

Mais faites attention à avoir instanceof vérifie où vous appelez cette méthode. Sinon, vous risquez de recevoir ClassCastException .

public static void main(String args[]) {
        Object obj = myMethod(); // i am calling static method from main() which return Object
    if(obj instanceof String){
    // Do something
    }else(obj instance of Integer) {
    //do something else
     }
5
Ankur Shanbhag

Cela peut être l'une des solutions. Mais votre solution actuelle est suffisante. Vous pouvez également ajouter de nouvelles variables et le garder propre, ce qui ne peut pas être fait avec le code actuel.

private static final int INDEX_OF_STRING_PARAM = 0;
private static final int INDEX_OF_INT_PARAM = 1;

public static Object[] myMethod() {
    Object[] values = new Object[2];
    values[INDEX_OF_STRING_PARAM] = "value";
    values[INDEX_OF_INT_PARAM] = 12;
    return values;
}
1
Narendra Pathai

l'approche que vous avez adoptée est bonne. Just La mise en œuvre pourrait devoir être améliorée . Par exemple, ReturningValues ​​devrait être bien défini et C'est mieux si vous pouvez rendre ReturningValues ​​comme immuable .

// this approach is better
public static ReturningValues myMethod() {
    ReturningValues rv = new ReturningValues("value", 12);
    return rv;
}


public final class ReturningValues {
    private final String value;
    private final int index;


    public ReturningValues(String value, int index) {
      this.value = value;
      this.index = index;
     }

} 

Ou si vous avez beaucoup de paires clé-valeur, vous pouvez utiliser HashMap alors 

public static Map<String,Object> myMethod() {
  Map<String,Object> map = new HashMap<String,Object>();
  map.put(VALUE, "value");
  map.put(INDEX, 12);
  return Collections.unmodifiableMap(map); // try to use this 
}
1
veritas

vous pouvez avoir le retour sous forme d'objet. Vous créez cet objet 'à la volée' dans votre 

function: if(int) 
 return new object(){
   int nr=..
}

idem pour string. Mais je crains que ce soit une solution coûteuse ...

1
Botea Florin

Je veux juste mettre mon avis 

Vous devez donc créer un type de retour générique et le mettre en œuvre par différents types de types de retour concrets . La classe Service peut créer différents types d’objets, une classe concrète et un retour en tant que type générique.

public interface GenericReturnType{
    public static RETURN_TYPE enum{
        MACHINE, PERSON;    
    }
    public RETURN_TYPE getReturnType();
}

public class PersonReturnType implements GenericReturnType{
    // CONSTRUCTORS //

    // GETTRE AND SETTER //

    public RETURN_TYPE getReturnType(){
        return PERSON;
    }
    public String getAddress(){
        return something;
    }
}

public class MachineReturnType implements GenericReturnType{
    // CONSTRUCTORS //

    // GETTRE AND SETTER //

    public RETURN_TYPE getReturnType(){
        return MACHINE;
    }
    public String getManufatureName(){
        return something;
    }
}


public class TestService{
    public GenericReturnType getObject(// some input //){
        GenericReturnType obj ;
        if(// some code //){
            obj = new  PersonReturnType();
            // some code //
        }
        if(// some code //){
            obj = new  MachineReturnType();
            // some code //
        }
        return obj;
    }
}

public class TestDriver{
    TestService service = new TestService();
    GenericReturnType genObj = TestService.getObject(// some input //);
    if(genObj.getReturnType() == RETURN_TYPE.MACHINE){
        // SOME CODE // 
    }
    if(genObj.getReturnType() == RETURN_TYPE.PERSON){
        // SOME CODE // 
    }
}
0
ParagFlume

@ruchira votre solution elle-même est la meilleure.Mais je pense que s'il ne s'agit que d'un nombre entier et d'une chaîne, nous pouvons le faire de manière simple et très simple.

 class B {   
    public String myfun() {         
        int a=2;           //Integer .. you could use scanner or pass parameters ..i have simply assigned
        String b="hi";      //String
        return Integer.toString(a)+","+b; //returnig string and int with "," in middle          
    }       
}

class A {    
    public static void main(String args[]){

        B obj=new B();  // obj of class B with myfun() method  
        String returned[]=obj.myfun().split(",");
             //splitting integer and string values with "," and storing them in array   
        int b1=Integer.parseInt(returned[0]); //converting first value in array to integer.    
        System.out.println(returned[0]); //printing integer    
        System.out.println(returned[1]); //printing String
    }
}

j'espère que c'était utile .. :)

0
Mukesh Kumar Singh

La classe que vous recherchez existe déjà. Map.Entry :

public static Entry<Integer,String> myMethod(){
    return new SimpleEntry<>(12, "value");
}

Et ensuite:

Entry<Integer,String> valueAndIndex = myMethod();
int index = valueAndIndex.getKey();
String value = valueAndIndex.getValue();

Il ne s'agit que d'une simple structure de données à deux champs qui stocke une clé et une valeur. Si vous devez effectuer un traitement spécial, stocker plus de deux champs ou avoir un autre cas particulier, vous devez créer votre propre classe. Sinon, Map.Entry est l'une des classes Java les plus sous-utilisées et convient parfaitement à de telles situations.

0
ndm13

Je sais que c'est tard, mais j'ai pensé que cela aiderait quelqu'un qui viendrait chercher une réponse à cette question. Vous pouvez utiliser une variable Bundle pour renvoyer plusieurs valeurs de type de données sans créer une autre méthode. Je l'ai essayé et a parfaitement fonctionné. 

Dans votre MainActivity où vous appelez la méthode:

Bundle myBundle = method();
String myString = myBundle.getString("myS");
String myInt = myBundle.getInt("myI");

Méthode:

public Bundle method() {
    mBundle = new Bundle();
    String typicalString = "This is String";
    Int typicalInt = 1;
    mBundle.putString("myS", typicalString);
    mBundle.putInt("myI", typicalInt);
    return mBundle;
}

P.S: Je ne suis pas sûr de pouvoir mettre en place un Bundle comme celui-ci, mais pour moi, cela a parfaitement fonctionné.

0
Dante