2013-12-10 3 views
0

Это скорее логический вопрос, чем конкретный код, у меня есть около двадцати функций, каждая функция вычисляет два значения моего интереса. Однако я могу только вернуть одно значение из функции. Теперь у меня есть другой способ: создать класс и реализовать сеттер и getter с глобальными переменными. Я хочу знать, насколько это целесообразно и рекомендуется? Или есть лучший способ сделать это?Как вернуть несколько значений из функции.

ответ

3

Не используйте глобальные переменные! Используйте некоторый класс, который имеет ваши данные как частные файлы, и предоставляет для него геттеры. Как в

class Pair<A,B> { 
    final A one; 
    final B two; 
    public Pair(A fst, B snd) { one = fst; two = snd; } 
    public A getFst() { return one; } 
    public B getSnd() { return two; } 
} 

Тогда вы можете в другом месте что-то вроде:

return new Pair(42, "a result"); 
+0

Лучшее предложение для сохранения нескольких типов. + 1 :) – Sage

+0

Пойду с этим. – User3

1

Верните Collection из вашей функции, содержащей ваши ценности.

+1

список Массив вы имеете в виду? Таким образом, мне не нужно разбить его на два класса. Хотя я мог бы задуматься о безопасности типов. – User3

+0

Зависит от того, что вы намерены вернуть. Если они являются уникальным значением, вы можете использовать Set или если они являются ключевыми, вы можете использовать Map. –

1

Вы должны вернуть List или array.

Но если return разных размеров, вы можете создать собственный класс и использовать его как возвращаемый тип.

Пример

public class Result { 
    private String name; 
    private int age; 

    // getters and setters; 
} 

Теперь вы можете иметь некоторые вещи, как следующий

public static Result getInfo(){ 
    Result result=new Result(); 
    result.setName("name"); 
    result.setAge(10); 
    return result;//now you can have String and int values return from the method 
} 
+0

Я думаю, что в моем случае предпочтительнее второй вариант, мои типы данных очень разнообразны, а разница в плавающей запятой может вызвать у меня проблемы. – User3

1

В зависимости от проблемы. Но 2 решения:

  1. Сделайте новый класс, экземпляры которого будут возвращены всеми этими функциями. У этого класса было бы 2 атрибута для каждого необходимого ответа.
  2. Возвращаемый массив или коллекция с этими 2 ответами.
0

Вы можете даже вернуть значения, разделенные специальным символом, сказать «~», если вы уверены, что «~» не будет отображаться в ваших результатах.

+1

Уродливый хак - возможно, COBOL представил записи более полувека назад! –

1

Вы можете сделать это

long[] function() { 
    long[] ret = { a, b }; 
    return ret; 
} 

или

long[] a = { 0 }, b = { 0 }; 

void function(long[] a, long[] b) { 
    a[0] = ... 
    b[0] = ... 

или добавить свойства к объекту.

private long a,b; 

void function() { 
    a = ... 
    b = ... 
} 

в последнем случае вы можете оценить.

class Results { 
    public final long a; 
    public final Date b; // note: Date is not immutable. 
    // add constructor 
} 

public Results function() { 
    long a = ... 
    Date b = ... 
    return new Results(a, b); 
} 
+0

Тип безопасности - проблема. – User3

+0

@ user2822178 Каковы ваши расчетные типы? –

+1

Я хотел бы отказать против # 2, т. Е. Повлиять на состояние объекта. Конечно, это может быть уместно в определенных контекстах, но в целом его, вероятно, следует избегать. – Smallhacker

1

Я думаю, что делает запись класс является наиболее подходящим.

public class Record { 
    public final int a; 
    public final int b; 

    public Record(final int a, final int b) { 
     this.a = a; 
     this.b = b; 
    } 
} 

Тогда ваши функции могут возвращать тип Record, и вы можете получить к нему доступ, скажем record.a и record.b.

Это также один из немногих случаев, когда переменные public и никакие геттеры и сеттеры не могут быть оправданы.

UPDATE: Реализован предложенное изменение, теперь все final, что означает, что Record не может быть изменен, когда вы получите его обратно, что, кажется, в соответствии с ожиданиями. Вы только хотите результаты и использовать их.

+1

Я бы избегал конструктора no-arg и делал поля 'final', но в противном случае пользовательская запись является самым чистым решением ... –

+0

@GyroGearless Правда, исправлено это, это действительно так, если все, что вам нужно, это иметь два возвращаемые значения. – skiwi

1

Существует множество способов: коллекции, массивы ... На мой взгляд, единственный способ - определить класс с этими значениями. вам не нужны методы получения и установки, если вам не нужно регулировать видимость содержимого

class MyReturnValue { 
    public int a; 
    public int b; 
} 

в вашем коде:

... 
MyReturnValue result=new MyReturnValue(); 
result.a=5; 
result.b=6; 

return result; 
1

Лучше сделать класс и реализовать сеттер и getter с глобальными переменными, а не с возвратом коллекции, это зависит от вашего использования.

1

насчет принятия varargs с общей вспомогательной функцией для получения вокруг числа возвращения переменного ограничения: В этом решении мы не должны объявить новый класс каждый раз, когда число возвращения переменного изменяется.

class Results 
{ 
    private final Object[] returnedObj; 

    public Results(Object... returnedObj) 
    { 
     this.returnedObj = returnedObj; 
    } 

    public <E> E getResult(int index) 
    { 
     return (E)returnedObj[index]; 
    } 


} 

Тестовый пример:

public static Results Test() 
{ 
     return new Results(12, "ABCD EFG", 12.45); 
      // or return larger number of value 
} 

//// And then returning the result 

Results result = Test(); 
String x = result.<String>getResult(1); 
System.out.println(x); // prints "ABCD EFG" 
+0

Отличное решение! – User3

Смежные вопросы