Kembalikan beberapa nilai dari metode Java: mengapa tidak ada objek n-tuple?

Mengapa tidak ada solusi (standar, bersertifikat Java), sebagai bagian dari bahasa Java itu sendiri, untuk mengembalikan beberapa nilai dari metode Java, daripada pengembang harus menggunakan cara mereka sendiri, seperti Peta, Daftar, Pasangan, dll .? Mengapa Java tidak mendukung objek n-tuple?

Terutama memikirkan metode pribadi sepele yang dapat memodifikasi dua objek bersama-sama (bersama-sama), dan dalam hal ini objek yang diketik sebagai pengembalian terdengar berlebihan.


person Saket    schedule 19.09.2011    source sumber
comment
Hm............? Menggunakan struktur data seperti itu apakah standarnya, bukan?   -  person mrkhrts    schedule 19.09.2011
comment
Karena belum ada yang melakukan upaya untuk mengambil salah satu solusi khusus tersebut dan menstandarkannya, tentu saja!   -  person Donal Fellows    schedule 19.09.2011
comment
Ada cara standarnya: disebut objek.   -  person toto2    schedule 19.09.2011
comment
ya, itu adalah struktur data standar, tetapi bukankah ada cara untuk menjadikannya sebagai bagian dari konstruksi bahasa daripada membungkusnya dalam koleksi? analogi sederhananya, jika boleh, adalah Anda dapat meneruskan beberapa argumen ke suatu metode dengan dua cara: (a). Miliki variabel parameter tunggal yang merupakan Daftar‹?› dan ekstrak masing-masing parameter darinya atau (b). memiliki variabel parameter yang berbeda untuk setiap argumen. Hanya berpikir keras...   -  person Saket    schedule 19.09.2011
comment
Apa yang Anda coba lakukan tidak standar. Pendekatan standar mencakup penggunaan peta, daftar, atau objek khusus!   -  person adarshr    schedule 19.09.2011
comment
@adarshr - mungkin kedengarannya 'tidak standar' karena belum standarnya, itulah yang saya coba cari :) Sekali lagi, saya hanya mencoba membuka diskusi.   -  person Saket    schedule 19.09.2011
comment
Kemungkinan duplikat stackoverflow.com/questions/457629/   -  person Raedwald    schedule 19.09.2011
comment
Saya memang melihat postingan di atas, yang membahas tentang bagaimana melakukan ini. Namun yang ingin saya ungkapkan adalah mengapa cara seperti itu diperlukan.   -  person Saket    schedule 19.09.2011
comment
Saya hanya mencoba membuka diskusi: diskusi bukanlah gaya yang direkomendasikan di sini. Lihat stackoverflow.com/faq#dontask   -  person Raedwald    schedule 19.09.2011
comment
@Raedwald - 'diskusi'...tidak secara harfiah :). Saya mencoba (dan mungkin beberapa orang lain juga) memahami/mempelajari teori di baliknya.   -  person Saket    schedule 19.09.2011
comment
Lihat juga: stackoverflow.com/questions/457775/does-java-need-tuples   -  person Raedwald    schedule 19.09.2011
comment
Mungkin Java melakukannya untuk memaksa Anda menggunakan nilai pengembalian gaya bernama, jadi tidak ada kebingungan tentang apa yang mulai dikembalikan...   -  person rogerdpack    schedule 17.04.2013
comment
Bahasa lain melakukan ini dengan memiliki sintaks pass-by-reference (atau pseudo pass-by-reference, seperti menggunakan & (operator alamat) di C atau C++. Begitulah cara orang mengatasinya di masa lalu. I Saya mencoba memutuskan bagaimana melakukan ini untuk sesuatu dan saya dapat memilih kelas statis privat yang dijelaskan di bawah sebagai jawaban yang dipilih.   -  person titania424    schedule 09.10.2013
comment
Mengapa tidak membuat kelas Tuple Anda sendiri seperti di pertanyaan ini ?   -  person jk7    schedule 10.01.2018


Jawaban (6)


Saya berasumsi OP berarti "Mengapa Java tidak mendukung objek n-tuple?". Python, Haskell, Lisp, ML dll memiliki kemampuan n-tuple yang heterogen. Seringkali juga kemampuan untuk mengembalikan beberapa objek dalam suatu bahasa adalah gula sintaksis (yaitu dalam python return 'a','b').

Alasannya tentu saja adalah desain dan konsistensi bahasa. Java lebih suka bersikap sangat eksplisit dan tidak menyukai struktur data anonim (walaupun saya berharap kami memiliki penutupan anonim).

Misalnya di Java tidak ada cara untuk mengatakan saya ingin panggilan balik yang mengambil parameter tipe ini dan mengembalikannya. Beberapa orang merasakan ini sebagai kelemahan besar, sementara yang lain menyukai konsistensi dan kejelasan.

IMHO meskipun menjengkelkan, saya sering mengatasi masalah ini dengan membuat kelas inline statis:

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

Ya, itu membosankan tetapi kemudian saya sering menggunakan kembali dan memfaktorkan ulang kelas-kelas tersebut sehingga menjadikannya tingkat atas dan menambahkan perilaku. Faktanya, salah satu keuntungan menggunakan rute ini adalah lebih mudah untuk menambahkan bidang baru di mana struktur data anonim (seperti dalam bahasa FP) menjadi jauh lebih sulit untuk menambahkan bidang (Anda akhirnya mengubah banyak kode).

Saya harus mencatat bahwa untuk 2-tupel beberapa orang menggunakan (atau menyalahgunakan) java.util.Map.Entry karena ada java.util.AbstractMap.SimpleEntry di Java 6. Juga Beberapa orang sekarang menggunakan Dukungan Pasangan Commons Lang3 (2-tuple).

Scala memiliki dukungan n-tuple dengan semacam kecurangan dan memiliki sejumlah 2-16 antarmuka tupel yang standar dalam bahasa tersebut dan secara sintaksis tersembunyi dari pemrogram.

Untuk alasan pendidikan semata, Anda mungkin ingin melihat bagaimana bahasa lain mencapai hal ini.

PEMBARUAN: untuk Java 8

Java 8 akan/mungkin (jadi ini nomor saya... hubungi saya mungkin) mendukung antarmuka bernama java.lang.BiValue dengan implementasi konkret yang dapat Anda gunakan disebut java.lang.BiVal . Kelas-kelas ini untuk membantu mendukung fungsionalitas lambda baru. Namun perhatikan ini hanya untuk 2 tupel.

PEMBARUAN: untuk tahun 2015

Java 8 tidak mendapatkan dukungan untuk tupel.

PEMBARUAN: dari penulis 2015

Jika Anda masih menginginkan dukungan tupel, ada tiga perpustakaan yang mendukung tupel dengan baik:

  • javatuples - Mendukung JDK 5 ke atas. Hingga 10 tupel.
  • JOOλ - Dari penulis jOOQ tetapi membutuhkan JDK 8.
  • Commons Lang 3 - Sekarang mendukung Triple (3-tuple) dan mendukung JDK 6 dan di atas.
person Adam Gent    schedule 19.09.2011
comment
Map.Entry adalah favorit saya. Mengapa membuat objek bernama untuk tugas sederhana yang dapat dilakukan bahasa lain dengan cepat? - person Erel Segal-Halevi; 26.02.2013
comment
Mungkin ada masalah konkurensi dengan pola ini (publikasi aman). Pola yang dijelaskan dalam jawaban untuk pertanyaan serupa (final + konstruktor) harus mengatasi masalah ini. - person Bruno; 10.10.2013
comment
Ya, saya hanya mencantumkan hal di atas untuk singkatnya dan bukan untuk digunakan kembali sepenuhnya. Objek yang tidak dapat diubah selalu merupakan pilihan yang baik. - person Adam Gent; 10.10.2013
comment
Bagaimana jika saya harus mengembalikan 3 objek? - person Dejell; 17.12.2013
comment
+1 untuk kembali dan benar-benar memperbarui jawaban dalam menghadapi perubahan kondisi. Saya berharap lebih banyak orang melakukan ini. - person Chris Warth; 12.06.2015
comment
Saya tidak melihat java.lang.BiValue dibangun di Java 8 seperti yang disarankan di atas. Mungkin hapus penyebutannya. - person matanster; 05.04.2018

Metode Java mengembalikan nilai nol atau satu; yang merupakan standar untuk Java. Jika Anda memerlukan beberapa nilai yang dikembalikan, buat objek dengan beberapa nilai dan kembalikan.

person DwB    schedule 19.09.2011
comment
satu-satunya hal adalah untuk metode (pribadi) yang sangat sepele, terkadang terdengar berlebihan... - person Saket; 19.09.2011
comment
void adalah tipe pengembalian di java, btw. - person Buhake Sindi; 19.09.2011
comment
@The Elite Gentleman Omong-omong, Anda juga dapat membuang null yang berarti null harus menjadi pengecualian :) - person Adam Gent; 19.09.2011
comment
Ini bukan jawaban atas pertanyaan Mengapa tidak ada di sana - person Alexey; 03.07.2015
comment
Pertanyaan kenapa tidak ada sama bermaknanya dengan bagaimana monyet? Itu adalah pertanyaan konyol. Tidak ada beberapa nilai kembalian untuk java. - person DwB; 03.02.2016

Jika Anda ingin mengembalikan dua objek, Anda biasanya ingin mengembalikan satu objek yang merangkum kedua objek tersebut.

person Psychologist    schedule 19.09.2011

Ada banyak cara hackish untuk mencapai hal ini, salah satu caranya adalah dengan mengembalikan Object[], tapi kemudian Anda punya indeks yang perlu dikhawatirkan, dan pemeriksaan penunjuk nol, itu menjadi buruk. Cara lain adalah mengembalikan String, tetapi kemudian Anda harus menguraikannya, dan hasilnya menjadi buruk.

Saya rasa pertanyaan sebenarnya adalah mengapa?

Inilah intinya - Jika saya sedang mengerjakan sebuah proyek dengan Anda, dan saya melihat perilaku seperti ini, saya akan menulis ulang sehingga Anda dapat melihat bagaimana hal itu harus ditangani. Jika Anda memberikan contoh kode, saya akan menulis ulang untuk mengilustrasikannya.

Tulis metode Anda dengan satu tanggung jawab, jika metode tersebut perlu mengembalikan lebih banyak data daripada kemampuan mereka, sebaiknya Anda menggunakan objek, atau memecahnya menjadi metode yang lebih kecil.

person Travis    schedule 19.09.2011
comment
Argumen yang bagus dengan tanggung jawab tunggal - person Wivani; 19.09.2011
comment
menggunakan suatu objek dan memecah menjadi metode yang lebih kecil adalah pendekatan yang sangat baik seperti yang dijelaskan dalam jawaban. - person Jayy; 19.09.2011
comment
@Travis katakanlah kita memiliki objek cache disk dengan metode yang mengembalikan nilai cache dan anotasinya (misalnya waktu modifikasi terakhir). Beberapa nilai pengembalian jauh lebih bersih dibandingkan menggunakan objek pembungkus. Kita tidak dapat menggunakan dua pemanggilan metode, karena cache dapat berubah antar pemanggilan metode. - person fhucho; 16.03.2013
comment
@fhucho Ini adalah kasus yang dapat diterapkan, itu masuk akal. Yang Anda cari adalah tulisan terakhir dan detail/metadatanya. Mengapa ini tidak diringkas dalam suatu objek? - person Travis; 18.03.2013
comment
@Travis Saya pikir ini akan menghasilkan kode yang sedikit lebih bersih dan lebih mudah dipahami. Juga, tidak perlu kelas pembungkus. Tapi menurutku, ini hanya masalah opini. - person fhucho; 19.03.2013

Ada gaya pola baru yang tersedia, dan cocok dengan sifat "asinkron" yang mungkin Anda lihat dalam bahasa seperti JavaScript.

Banyak kode saya terlihat seperti ini saat ini :-)

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 ...
            }
        });
    }

}

Tidak ada objek baru untuk dibuat dan tidak banyak kelas tambahan karena antarmuka adalah kelas dalam objek.

Inilah yang membuat Swift begitu mengagumkan. Kodenya bisa terlihat seperti ini:

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

Dan karena satu-satunya argumen adalah blok, ini pun:

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

Java perlu diperbaiki untuk membuat kode yang berisi panggilan balik lebih mudah dibaca.

person Paul Hamilton    schedule 23.05.2015

Karena mengembalikan beberapa nilai dari suatu metode bukanlah praktik yang disarankan (di Java).

Jika Anda memerlukan nilai yang tidak terkait dari suatu metode, Anda memerlukan struktur data berbeda seperti objek yang berisi nilai tersebut. Jika Anda memerlukan beberapa instance dari kelas yang sama (yaitu beberapa Strings), Anda perlu mengembalikan array, atau beberapa koleksi tergantung pada kebutuhan Anda.

Mengembalikan beberapa nilai dalam bahasa lain (misalnya Go) digunakan misalnya untuk mengembalikan kode kesalahan, tetapi Java dirancang berbeda menggunakan pengecualian.

person OscarRyz    schedule 19.09.2011