Java'da birden çok değer nasıl döndürülür?


11

Bazen bir işlevden birden çok değer döndürmek istersiniz. Bu normalde Java ile nasıl yapılır?

Bir seçenek, bir liste veya grup döndüren bu Python snippet'i gibi bir dizi kullanmaktır:

value, success = read_unreliably()
if success:
    print value

Başka bir seçenek de şu JavaScript örneğinde olduğu gibi bir karma / dict döndürmektir:

var result = readUnreliably()
if (result.success) {
    alert(value);
}

Bunlardan biri, bu Java örneği gibi, yalnızca bu amaç için özel bir nesne oluşturmak olacaktır:

ReadUnreliablyResult result = readUnreliably()
if (result.getSuccess()) {
    System.out.println(result.getValue());
}

Elbette, bazı şeyleri depolamak yerine ihtiyacınız olan şeyleri saklamak için bazı küresel değişkenleri de kullanabilirsiniz, ancak bunun bir seçenek olmadığını söyleyelim.


"Gerçek" java insanlar gerçekten böyle küçük iç sınıflarda alanları gizlemek için kamu alıcıları ve ayarlayıcıları kullanma zahmetinden geçiyor mu? Sadece merak.
Chris Farmer

3
Evet, çoğu. Birçok çerçeve JavaBean standardını beklediğinden, alıcılara ve ayarlayıcılara sahip olmadığınızdan pişman olabilirsiniz. Her durumda, IDE'niz bunları sizin için üretecektir.
Eric Wilson

3
Ya da YAGNI prensibine dayanarak onları dışarıda bırakabilirsiniz. Ancak bu beklenildiği kadar sık ​​gerçekleşmiyor gibi görünüyor.
MatrixFrog

@FarmBoy: Sanırım fasulye ve benzeri için anlıyorum, ancak OP bunun sadece birden fazla değer döndürmek için tasarlanmış bir kerelik bir sınıf olduğunu ima ediyor.
Chris Çiftçi

@ChrisFarmer Sanırım bu bağlamda, 'gerçek' bir Java programcısının bu amaçla bir sınıf oluşturduğunu hiç görmedim.
Eric Wilson

Yanıtlar:


26

Bu normalde Java ile nasıl yapılır?

Acı.

Bir seçenek, bir liste veya grup döndüren bu Python snippet'i gibi bir dizi kullanmaktır ...

Başka bir seçenek de bu JavaScript örneği gibi bir karma / dict döndürmek olacaktır ...

Bu teknikler Java'da iyi sonuç vermez; değerlerin Object'den indirilmesi gerekir.

Bir tane daha, bu Java örneği gibi, sadece bu amaç için özel bir nesne oluşturmak olacaktır ...

Bu en yaygın olanıdır, ancak tüm bu küçük sınıfları oluşturmak sıkıcıdır. C ++ 'da std :: pair kullanımı yaygındır, ancak bu genellikle Java'da yapılmaz.

Lombok ile küçük özel nesneler oluşturmak oldukça kolaydır:

@RequiredArgsConstructor
public class X {
  private final boolean status;
  private final byte[] data;

}


10
"Bu normalde Java'da nasıl yapılır?" "Acı". Java geliştiricisi olarak lol Bunun için +
1'lemeliyim

Kompakt değişmez yapıya benzer bir sınıf kullanmak o kadar acı verici değil ... Gerçekten bir C yapısı yazmak gibi ...
Guillaume

1
@Guillaume - tabii, ama tüm bu küçük şeyler hem zaman hem de mekanda toplanıyor. Java topluluğunun neden "class Pair <T1, T2> {public T1; public T2 second; ...}" gibi standart bir jenerik seti benimsemediğini bilmiyorum. modern dillerde "a, b" yi döndürürsünüz; ve sonra "x, y = f ()" yazın;
kevin cline

1
Eminim bazı 'eski' dil de bunu yapabilir :) IMHO Birden fazla dönüş değerinin toplam karışıklığa yol açabileceğini buldum ve başka bir dönüş alanı eklemeniz gerekiyorsa, sadece sınıf gibi yapınızı güncellemeden güncellemelisiniz. yöntem imzanızı değiştirin.
Guillaume

1
Bu "Acı verici." Bana sert vurdu, evet benzer durumlarla karşılaştığımda tam olarak Java geliştiricisi olarak hissettiğim şey.
artjom

13

Evet, Java'da struct/ tuple/ oluşturmanın yolu recordbir sınıf oluşturmaktır. Sadece dahili kullanım içinse, kamusal alanlarla küçük, değişmez, yapı benzeri bir sınıf kullanmayı tercih ederim.

Örnekler:

public class Unreliably {
    public final boolean success;
    public final int value;
    public Unreliably(boolean success, int value) {
        this.success = success; this.value = value;
    }
}

Scala'da bunu yapmak çok daha kolay:

case class Unreliably(success: Boolean, value: Int)

8
Aslında, Scala'da muhtemelen genellikle a Tuple2[Boolean, Int]. Bu belirli örnekte de bir Option[Int].
Jörg W Mittag

2
Bu, Chris Farmer'ın (Q'nun yorumlarında) gerçek Java kullanıcılarının küçük iç sınıflar için mutlaka alıcılar ve ayarlayıcılar oluşturmadığı sorusunu cevaplıyor. "Gerçek" bir Java'lısınız, değil mi?
Mike M. Lin

2
Diğer yandan gerçek İskoçyalı yoktur.
Joseph Weissman

5

Verdiğiniz örnek için, bir istisna atmak bunun üstesinden gelmenin en standart yolu olacaktır:

try {
    result = readUnreliably();
    System.out.println(result);
} (catch IOException e) {
    System.out.println("Could not read file");
}

Ayrıca, "Bir Şey Yap" işlevlerine sahip olmak için çabalarsanız, birden fazla değer döndürme özelliği, bazen uygun olsa da, daha az gereklidir.


4

A'nın bir örneğini ve B'nin bir örneğini saklayabilecek bir Pair genel sınıfımız var. Muhtemelen aynı şekilde Üçlü veya Dörtlü oluşturabilirsiniz.

public class Pair<A, B>
{
    ...
}

1
bu olsa gerçekten okunamayan bazı kod yapar. bir yöntem geri dönerse Pair<String, Integer>, bu ne anlama geliyor? bu değerler neyi temsil ediyor? yöntemin uygulanmasını okumadan muhtemelen bunu bilemezsiniz.
sara

1

Java'da işleviniz bir nesneyi döndürür (veya bir hata durumunda belki de null olur). Bu şekilde, birden fazla veri parçası döndürülebilir.


1

Java'da birden çok değişkeni döndürmenin açık bir yolu yoktur, ancak birkaç yaklaşım vardır:

  1. Birincisi dizinin yoluna gitmek. Bu, yalnızca aynı veri türünde her şeye sahipseniz veya bunları geçici olarak bir türe dönüştürebiliyorsanız gerçekten işe yarar.
  2. İkinci yol, birden çok değişken türünü aktarmak amacıyla bir sınıf oluşturmaktır. Çalışmamda bunlara DTO'lar veya Veri Aktarım Nesneleri diyoruz.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.