Возвращает несколько значений из метода Java: почему нет объектов n-кортежей?

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

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

Ответ 1

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

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

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

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

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

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

Я должен отметить, что для 2-х наборов некоторые люди используют (или злоупотребляют) java.util.Map.Entry, поскольку в Java есть java.util.AbstractMap.SimpleEntry. Также некоторые люди теперь используют Поддержка Commang Lang3 Pair (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 и выше.

Ответ 2

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

Ответ 3

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

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

Здесь rub - Если бы я работал над проектом с вами, и я видел этот тип поведения, я бы переписал его, чтобы вы могли видеть, как его обрабатывать. Если вы предоставите образец кода, я переписал его для иллюстрации.

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

Существует новый стиль шаблона, доступный и соответствующий "асинхронному" характеру, который вы можете видеть на таких языках, как 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 нуждается в работе, чтобы сделать загруженный код обратного вызова намного легче читать.