Возврат нескольких значений из метода Java: почему нет объектов с n-кортежами? - PullRequest
47 голосов
/ 19 сентября 2011

Почему не существует (стандартного, сертифицированного Java) решения, как части самого языка Java, для возврата нескольких значений из метода Java, а не разработчиков, использующих собственные средства, такие как Карты, Списки,Пары и т. Д.?Почему Java не поддерживает объекты с n-кортежами?

Особенно в отношении простых тривиальных методов, которые могут модифицировать два объекта вместе (в тандеме), и в этом случае типизированный объект в качестве возврата звучит излишне.

Ответы [ 6 ]

51 голосов
/ 19 сентября 2011

Я предполагаю, что OP означает «Почему Java не поддерживает объекты с n-кортежами?».Python, Haskell, Lisp, ML и т. Д. Имеют гетерогенные возможности n-кортежей.Также часто способность явно возвращать несколько объектов в языке является синтаксическим сахаром (т. Е. В python возвращают 'a', 'b').

Причина, конечно, заключается в проектировании и согласованности языка.Java предпочитает быть очень явным и не любит анонимные структуры данных (хотя я хотел бы, чтобы у нас были анонимные замыкания).

Например, в Java нет способа сказать, что я хотел бы получить обратный вызов, который принимает параметры этого типа и возвращаетэтот.Некоторые люди чувствуют эту огромную слабость, другие как последовательность и ясность.

ИМХО, хотя это раздражает, я часто борюсь с этой проблемой, делая статические встроенные классы:

private static class Combo {
   String name;
   int weight;
}

Да, это утомительно, но потомЯ часто использую и реорганизую эти классы, делая их на высшем уровне и добавляя поведение.Фактически, одним из преимуществ использования этого маршрута является то, что гораздо проще добавлять новые поля, где есть анонимная структура данных (как в языках FP), и добавлять поле становится намного сложнее (в итоге вы меняете тонну кода).

Следует отметить, что для двух кортежей некоторые люди используют (или злоупотребляют) java.util.Map.Entry, поскольку в Java 6 java.util.AbstractMap.SimpleEntry. Также некоторые люди теперь используют Поддержка пар Commons Lang3 (2-кортеж) .

Scala имеет поддержку n-кортежей в виде мошенничества и имеет целую связку из 2-16 интерфейсов кортежей, которые являются стандартными в языке и синтаксически скрыты от программиста.

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

ОБНОВЛЕНИЕ: для Java 8

Java 8 будет / возможно (так вот мой номер ... позвоните мне, может быть) поддерживает интерфейс под названием java.lang.BiValue с конкретной реализацией, которую вы можете использовать, под названием java.lang.BiVal.Эти классы предназначены для поддержки новой функциональности лямбды.Но обратите внимание, что это только для 2-х кортежей.

ОБНОВЛЕНИЕ: для 2015 года

Java 8 не получила поддержку для кортежей.

ОБНОВЛЕНИЕ: от автора 2015

Если вам все еще нужна поддержка кортежей, есть три библиотеки, которые хорошо поддерживают кортежи:

  • javatuples - поддерживает JDK 5 и выше.До 10-ти кортежей.
  • JOOλ - от автора jOOQ, но требует JDK 8.
  • Commons Lang 3 - теперь поддерживает Triple(3 кортежа) и поддерживает JDK 6 и выше.
9 голосов
/ 19 сентября 2011

Java-методы возвращают ровно ноль или одно значение; что является стандартом для Java. Если вам нужно вернуть несколько значений, создайте объект с несколькими значениями и верните его.

4 голосов
/ 19 сентября 2011

Если вы хотите вернуть два объекта, вы обычно хотите вернуть один объект, который вместо этого инкапсулирует два объекта.

3 голосов
/ 19 сентября 2011

Существует множество хакерских способов сделать это, один из способов - вернуть Object[], но тогда вам нужно беспокоиться о индексах, а проверка нулевого указателя - это просто неприятно. Другой способ - вернуть String, но тогда вам нужно разобрать его, и это становится неприятным.

Я думаю, что реальный вопрос в том, почему?

Вот в чём суть - если бы я работал с вами над проектом и увидел такой тип поведения, я бы переписал его, чтобы вы могли видеть, как с ним следует обращаться. Если вы предоставите пример кода, я перепишу его для иллюстрации.

Напишите ваши методы с единственной ответственностью: если им нужно вернуть больше данных, чем они могут, вам, вероятно, следует либо использовать объект, либо разбить его на более мелкие методы.

1 голос
/ 23 мая 2015

Доступен новый стиль шаблона, который соответствует природе "все асинхронно", которую можно встретить в таких языках, как JavaScript.

Сегодня мой код выглядит так: -)

public class Class1 {

    public interface Callback {
       void setData(String item1, String item2);
    }
    public void getThing(Callback callback) {
        callback.setData("a", "b");
    }
}

public class Class2 {

    public void doWithThing(Class1 o) {
        o.getThing(new Class1.Callback() {
            public void setData(String item1, String item2) {
                ... do something with item 1 and item 2 ...
            }
        });
    }

}

Нет новых объектов для создания и не так много дополнительных классов, так как интерфейс является внутренним классом объекта.

Это то, что делает Swift таким классным. Код может выглядеть так:

o.getThing({ item1, item2 -> Void in
    ... do something with item 1 and item 2 ...
});

И поскольку единственным аргументом является блок, даже это:

o.getThing { item1, item2 -> Void in
    ... do something with item 1 and item 2 ...
};

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

1 голос
/ 19 сентября 2011

Поскольку возврат нескольких значений из метода не рекомендуется (в Java).

Если вам нужны несвязанные значения из метода, вам нужна другая структура данных, например объект, содержащий эти значения.Если вам нужно несколько экземпляров одного и того же класса (т.е. несколько строк), вам нужно вернуть либо массив, либо некоторую коллекцию в зависимости от ваших потребностей.

Возвращение нескольких значений на других языках (например, Go) используется, например, для возврата кода ошибки, но Java была разработана по-другому с использованием исключений.

...