Este post discutirá como retornar vários valores de um método em Java.
De acordo com a Java Language Specification, os métodos em Java podem retornar apenas um valor por vez. Portanto, retornar vários valores de um método teoricamente não é possível em Java. Mas a beleza do Java está no fato de que podemos fazer as coisas desejadas com algumas soluções inteligentes. Este post fornece uma visão geral de algumas das alternativas disponíveis para fazer isso.
1. Usando um POJO
instância de classe
Este é o método mais comumente usado para retornar vários valores de um método em Java. A ideia é retornar uma instância de uma classe contendo todos os campos que queremos retornar.
Essa classe pode ser um POJO com variáveis de membro público e um construtor público para iniciar seus campos com valores obrigatórios ou um JavaBean
com getters e setters correspondentes para suas variáveis de membro privado e construtor público no-arg.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// POGO para agrupar vários campos final class Person { public String name; public int age; public char gender; public Person(String name, int age, char gender) { this.name = name; this.age = age; this.gender = gender; } } class Main { public static Person getDetails() { // retorna detalhes da pessoa do método String name = "Ryan"; int age = 25; char gender = 'M'; return new Person(name, age, gender); } // Retorna vários valores de um método em Java public static void main(String[] args) { Person person = getDetails(); System.out.println("Name is " + person.name); System.out.println("Age is " + person.age); System.out.println("Gender is " + person.gender); } } |
Resultado:
Name is Ryan
Age is 25
Gender is M
Os benefícios de usar esse método sobre outros métodos discutidos abaixo são que ele fornece segurança de tipo e melhora consideravelmente a legibilidade do código.
A seguir está uma versão mais simples do programa acima que usa uma array de objetos para armazenar todos os campos obrigatórios, mas não oferece nenhuma segurança de tipo nem mesmo passa informações de campo para o chamador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import java.util.Arrays; // Classe para agrupar vários campos class Collection { private Object[] items; private final int size; // Constrói um array de objetos e inicializa com os valores fornecidos public Collection(Object... values) { this.size = values.length; this.items = Arrays.copyOf(values, size); } public Object get(int i) { return items[i]; } public int getSize() { return size; } @Override public String toString() { return Arrays.toString(items); } } class Main { public static Collection getDetails() { String name = "Ryan"; int age = 25; char gender = 'M'; long income = 100000; return new Collection(name, age, gender, income); } // Retorna vários valores de um método em Java public static void main(String[] args) { Collection details = getDetails(); System.out.println("The returned values are " + details); System.out.println("The collection size is " + details.getSize()); System.out.println("The name field has value " + details.get(0)); } } |
Resultado:
The returned values are [Ryan, 25, M, 100000]
The collection size is 4
The name field has value Ryan
Também podemos implementar um Pair genérico ou Tuple genérico, que também oferece segurança de tipo se precisarmos apenas retornar dois ou três campos do método.
2. Usando javafx.util.Pair
class
A partir do Java 8, podemos usar o Pair classe incluída no javafx.util
pacote que representa os pares nome-valor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import javafx.util.Pair; class Main { public static Pair[] getDetails() { return new Pair[] { new Pair<>("name", "Ryan"), new Pair<>("age", 25), new Pair<>("gender", 'M') }; } // Retorna vários valores de um método em Java 8 e superior public static void main(String[] args) { Pair[] person = getDetails(); for (int i = 0; i < person.length; i++) { System.out.println("{" + person[i].getKey() + " : " + person[i].getValue() + "}"); } } } |
Resultado:
{name : Ryan}
{age : 25}
{gender : M}
3. Retornar uma array de tipo específico ou uma array de objetos
Essa é a abordagem mais simples até agora, mas não oferece segurança de tipo (para uma array de objetos) ou passa informações de campo para o chamador. Para argumentos do mesmo tipo, podemos fazer algo como:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import java.util.Arrays; class Main { public static int[] getDetails() { int v1 = 30; int v2 = 50; int v3 = 100; return new int[] { v1, v2, v3 }; } // Retorna vários valores de um método em Java public static void main(String[] args) { int[] ints = getDetails(); System.out.println(Arrays.toString(ints)); } } |
Resultado:
[30, 50, 100]
Para argumentos de vários tipos, podemos retornar uma array de objetos, conforme mostrado abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import java.util.Arrays; class Main { public static Object[] getDetails() { String name = "Ryan"; int age = 25; char gender = 'M'; long income = 100000; return new Object[] { name, age, gender, income }; } // Retorna vários valores de um método em Java public static void main(String[] args) { Object[] person = getDetails(); System.out.println(Arrays.toString(person)); } } |
Resultado:
[Ryan, 25, M, 100000]
4. Devolva uma coleção
Em vez de retornar um array, também podemos retornar um Collection
. Por exemplo, o programa a seguir usa um List
em vez de uma array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.Arrays; import java.util.List; class Main { public static List<Object> getDetails() { String name = "Ryan"; int age = 25; char gender = 'M'; long income = 100000; return Arrays.asList(name, age, gender, income); } // Retorna vários valores de um método em Java public static void main(String[] args) { List<Object> person = getDetails(); System.out.println(person); } } |
Resultado:
[Ryan, 25, M, 100000]
Usando um List
não passa informações de campo para o chamador. Em vez disso, podemos criar um mapa para passar o nome do campo e seu valor como pares chave-valor, conforme mostrado abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import java.util.AbstractMap; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { public static Map<String, String> getDetails() { return Stream.of( new AbstractMap.SimpleEntry<>("name", "Ryan"), new AbstractMap.SimpleEntry<>("age", "25"), new AbstractMap.SimpleEntry<>("gender", "Male"), new AbstractMap.SimpleEntry<>("income", "100000$") ) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } // Retorna vários valores de um método em Java public static void main(String[] args) { Map<String, String> person = getDetails(); for (String key: person.keySet()) { System.out.println(key + " is " + person.get(key)); } } } |
Resultado:
income is 100000$
gender is Male
name is Ryan
age is 25
5. Usando um delimitador
Aqui, a ideia é retornar uma string composta por todos os valores separados por um delimitador. Em seguida, precisamos dividir a string usando o mesmo delimitador antes de usar os valores dentro do método chamador.
Essa abordagem não é tão elegante, mas ainda é amplamente usada em muitos projetos legados para transferir dados entre o modelo e a visualização.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Main { public static String getDetails() { return "George" + "~" + "Martin"; } // Retorna vários valores de um método em Java public static void main(String[] args) { String[] name = getDetails().split("~"); for (String s: name) { System.out.println(s); } } } |
Resultado:
George
Martin
Isso é tudo sobre como retornar vários valores de um método em Java.
Veja também: