1

I have a situation where I would like to return 2 values from a method. I am trying to figure out how to do this in Java. In C# I would just use 2 out parameters or a struct in this case but not sure what is best to do for Java (other than Pair as I may have to change this to 3 values, or having to create a new class to return object).

My example is this:

public void myMethod(Signal signal){
  MyEnum enum = MyEnum.DEFAULT;
  String country = "";

  // based on signal, I need to get 2 values, one is string, other is 
  // an enumeration
  if (signal.getAction() == "Toyota"){
    enum = MyEnum.TOYOTA;
    country = "Japan";
  } else if (signal.getAction() == "Honda"){
    enum = MyEnum.HONDA;
    country = "Japan";
  } else if (signal.getAction() == "VW"){
    enum = MyEnum.VW;
    country = "Germany";
  } else {
    enum = MyEnum.DEFAULT;
    country = "Domestic";
  }

  // how to return both enum and country?
  return ???
}

This is just an example to explain what I need (returning one-something, having 2 values, one is string, other is an enum in this case). So, ignore any issues with my string comparison or logic, my point is how to return something. For example, in C#, I could define a struct and return that struct, or I could use out parameters to return 2 values. But I am not sure how to do that elegantly in Java.

pixel
  • 9,653
  • 16
  • 82
  • 149
  • 6
    Why don't you want to return a new class for the make and model? Note that your string equality tests are broken, you're calling `car.getMake()` in almost every case, and you'd be better off having a `MyEnum.fromText` method or something similar... – Jon Skeet Nov 20 '15 at 18:03
  • 1
    Out does not exist in Java but you can return an array with the values or create a value outside the method and give it a value – Yassin Hajaj Nov 20 '15 at 18:04
  • @JonSkeet Thanks Jon. My point is that I need to return one "something" consisting of a String and an enum value. So, checking for string is irrelevant. Also, in regards to returning an object, the reason I would rather not to is because I have to define new class and also deal with the object returned such as clearing the memory taken by that object. – pixel Nov 20 '15 at 18:13
  • @YassinHajaj Array suggests multiple values but I am really returning just one "something" that consists or 2 or potentially 3 values. So, it is like returning one struct or record having String and an enum. – pixel Nov 20 '15 at 18:16
  • 1
    Java doesn't have tuples. It's best to do as what Jon Skeet said - Create a class. Otherwise you can return Object[] and cast it on the return side which is a bit messy. I think you are slightly confused though, Toyota is a make, and Corolla is a model. You actually don't need all those if statements, you can store keys in a hashmap to return the enum you want. One thing I don't know is what you are trying to do. why can't you call `car.getMake()` and `car.getModel()`? – WalterM Nov 20 '15 at 18:28
  • @WalterM I realize that my example is confusing so I updated. It is irrelevant what I do inside this method, main point is how to return a data structure. What would be appropriate structure? If I use an array, that is messy, it suggests multiple values. If I return an object, I have to free that object in caller right? – pixel Nov 20 '15 at 18:42
  • 1
    oh no. Java has a garbage collector, you don't call free on anything. In this new example you showed, you could store the country as a value in the enum `MyEnum.TOYOTA.getCountryOrigin()`. If this question is only about returning 2 values, then it is a duplicate of this http://stackoverflow.com/questions/2832472/how-to-return-2-values-from-a-java-function You should use a HashMap instead of your if/else it's much cleaner and faster/less code. – WalterM Nov 20 '15 at 18:58

2 Answers2

1

I think this is mainly an example of what Jon Skeet has suggested. (edited to include country)

Make your Enum carry the text and the conversion functionality.

public enum AutoMake {
    HONDA("Honda", "Japan"),
    TOYOTA("Toyota", "Japan"),
    VW("Volkswagon", "Germany");

    private String country;
    private String text;

    private AutoMake(String text, String country) {
        this.text = text;
    }

    public static AutoMake getMake(String str){
        AutoMake make = null;
        AutoMake[] possible = AutoMake.values();
        for(AutoMake m : possible){
            if(m.getText().equals(str)){
                    make = m;
            break;
            }
        }
        return make;
    }

    /**
     * @return the country
     */
    public String getCountry() {
        return country;
    }

    /**
     * @return the text
     */
    public String getText() {
        return text;
    }

}

And then store the the make as an enum in the car object

public class Car {
    private AutoMake make;
    private String model;
    public Car() {
    }
    public Car(AutoMake make, String model) {
        super();
        this.make = make;
        this.model = model;
    }
    /**
     * @return the make
     */
    public AutoMake getMake() {
        return make;
    }
    /**
     * @return the model
     */
    public String getModel() {
        return model;
    }
    /**
     * @param make the make to set
     */
    public void setMake(AutoMake make) {
        this.make = make;
    }
    /**
     * @param model the model to set
     */
    public void setModel(String model) {
        this.model = model;
    }
}

and now you can get both text and enum values from the car object

car.getMake() // Enum
car.getMake.getText() // Text
car.getMake.getCountry // Country

You can convert from text to enum with

Enum make = AutoMake.getMake("Honda");

This would mean AutoMake.getMake(Signal.getAction()) could replace myMethod(signal) with the resulting Enum carrying both make and country.

1

If you really really want to have tuples in java you can import them from the scala standard lib. As both languages are compiled to the same byte code they can be used together in one project.

import scala.Tuple2;

public class ScalaInJava {
    public static Tuple2<String, Integer> tupleFunction(){
        return new Tuple2<>("Hello World", 1);
    }

    public static void main(String[] args) {
        System.out.println(tupleFunction()._1());
    }
}
Aracurunir
  • 625
  • 6
  • 10