Java 如何同時(shí)返回多個(gè)不同類(lèi)型
Java 同時(shí)返回多個(gè)不同類(lèi)型
前言
雖然對(duì)于這種需求不常用,且比較冷門(mén),但是還是有其存在的價(jià)值,再次做一下整理。我們常用的return語(yǔ)句只允許返回單個(gè)對(duì)象,相對(duì)的解決辦法就是創(chuàng)建一個(gè)對(duì)象,用它來(lái)持有想要返回的多個(gè)對(duì)象。
實(shí)現(xiàn)這種功能,還要?dú)w功于Java1.5的新特性-泛型,我們利用泛型,可以一次性地解決該問(wèn)題,以后再也不用在這個(gè)問(wèn)題上浪費(fèi)時(shí)間了,并且,我們可以再編譯期就能夠確保類(lèi)型安全。
你也許已經(jīng)想到使用集合可以實(shí)現(xiàn)我們的需求,但是雖然一次可以返回多個(gè)值,但是其類(lèi)型都是相同的,并不完全符合我們的需求。
我們需要引入一個(gè)概念:元組(tuple),元組也稱(chēng)為數(shù)據(jù)傳送對(duì)象或信使。元組是將一組對(duì)象直接打包存儲(chǔ)于其中的一個(gè)單一對(duì)象,這個(gè)容器對(duì)象允許讀取其中元素,但是不允許向其中存放新的對(duì)象。
通常,元組可以具有任意長(zhǎng)度,同時(shí)元組中的對(duì)象可以是任意不同的類(lèi)型。我們能夠?yàn)槊恳粋€(gè)對(duì)象指明其類(lèi)型,并且可以正確讀取到數(shù)據(jù),這就是元組可以提供的功能。我們要處理不同長(zhǎng)度的問(wèn)題,需要?jiǎng)?chuàng)建多個(gè)不同的元組。
首先我們創(chuàng)建一個(gè)2維元組
//: net/mindview/util/TwoTuple.java(Java編程思想_代碼_目錄)
package net.mindview.util;
public class TwoTuple<A, B> {
public final A first;
public final B second;
public TwoTuple(A a, B b) {
first = a;
second = b;
}
public String toString() {
return "(" + first + ", " + second + ")";
}
}
構(gòu)造器捕獲了要存儲(chǔ)的對(duì)象,而toString()方法是一個(gè)便利函數(shù),用來(lái)顯示列表中的值。
注意:元組隱含地保持了其中元素的次序。
閱讀上面的代碼,以及根據(jù)元組的定義,你一定會(huì)感到詫異,設(shè)計(jì)思路不是應(yīng)該將first和second聲明為private,然后生成這兩個(gè)變量的get方法嗎?
以上是我們大多數(shù)人的思維,但是我們仔細(xì)分析上面的代碼,可以發(fā)現(xiàn)完全符合我們的要求。首先我們可以讀取first和second,并且因?yàn)槭褂昧薴inal聲明,我們就無(wú)法在修改其值。我們對(duì)比這兩種寫(xiě)法,很顯然,上面給出的代碼更加合理,更加簡(jiǎn)潔明了。
還有另一種設(shè)計(jì)考慮,即你確實(shí)希望允許客戶(hù)端程序員改變first或second所引用的對(duì)象。然而,采用上面的形式無(wú)疑是更安全的做法,這樣的話(huà),如果程序員想要使用具有不同元素的元組,就強(qiáng)制要求他們另外創(chuàng)建一個(gè)新的TwoTuple對(duì)象。
我們可以利用繼承機(jī)制實(shí)現(xiàn)長(zhǎng)度更長(zhǎng)的元組
//: net/mindview/util/ThreeTuple.java
package net.mindview.util;
public class ThreeTuple<A,B,C> extends TwoTuple<A,B> {
public final C third;
public ThreeTuple(A a, B b, C c) {
super(a, b);
third = c;
}
public String toString() {
return "(" + first + ", " + second + ", " + third +")";
}
}
//: net/mindview/util/FourTuple.java
package net.mindview.util;
public class FourTuple<A,B,C,D> extends ThreeTuple<A,B,C> {
public final D fourth;
public FourTuple(A a, B b, C c, D d) {
super(a, b, c);
fourth = d;
}
public String toString() {
return "(" + first + ", " + second + ", " +
third + ", " + fourth + ")";
}
}
//: net/mindview/util/FiveTuple.java
package net.mindview.util;
public class FiveTuple<A,B,C,D,E>
extends FourTuple<A,B,C,D> {
public final E fifth;
public FiveTuple(A a, B b, C c, D d, E e) {
super(a, b, c, d);
fifth = e;
}
public String toString() {
return "(" + first + ", " + second + ", " +
third + ", " + fourth + ", " + fifth + ")";
}
}
為了使用元組,你只需定義一個(gè)長(zhǎng)度適合的元組,將其作為方法的返回值,然后在return語(yǔ)句中創(chuàng)建該元組,并返回即可。
實(shí)例
//: generics/TupleTest.java
import net.mindview.util.*;
class Amphibian {
}
class Vehicle {
}
public class TupleTest {
static TwoTuple<String, Integer> f() {
// Autoboxing converts the int to Integer:
return new TwoTuple<String, Integer>("hi", 47);
}
static ThreeTuple<Amphibian, String, Integer> g() {
return new ThreeTuple<Amphibian, String, Integer>(new Amphibian(), "hi",
47);
}
static FourTuple<Vehicle, Amphibian, String, Integer> h() {
return new FourTuple<Vehicle, Amphibian, String, Integer>(new Vehicle(),
new Amphibian(), "hi", 47);
}
static FiveTuple<Vehicle, Amphibian, String, Integer, Double> k() {
return new FiveTuple<Vehicle, Amphibian, String, Integer, Double>(
new Vehicle(), new Amphibian(), "hi", 47, 11.1);
}
public static void main(String[] args) {
TwoTuple<String, Integer> ttsi = f();
System.out.println(ttsi);
// ttsi.first = "there"; // Compile error: final
System.out.println(g());
System.out.println(h());
System.out.println(k());
}
}
輸出結(jié)果:
(hi, 47)
(Amphibian@15db9742, hi, 47)
(Vehicle@6d06d69c, Amphibian@7852e922, hi, 47)
(Vehicle@4e25154f, Amphibian@70dea4e, hi, 47, 11.1)
由于有了泛型,你可以很容易地創(chuàng)建元組,令其返回一組任意類(lèi)型的對(duì)象。而你所要做的,只是編寫(xiě)表達(dá)式而已。
通過(guò)ttsi.first = "there";語(yǔ)句的錯(cuò)誤,我們可以看出,final聲明確實(shí)能夠保護(hù)public元素,在對(duì)象被構(gòu)造出來(lái)之后,聲明為final的元素便不能被再賦予其他值了。
java return返回多個(gè)值或多種類(lèi)型的值方法(list;Map)
1、在寫(xiě)方法的時(shí)候
有時(shí)候需要返回多個(gè)值,有時(shí)候返回的多個(gè)值的類(lèi)型還不同,依據(jù)不同情況以下提供了三種方法返回多個(gè)值。
2、具體思路都在代碼注釋里了
如果返回的多個(gè)值類(lèi)型相同,可以用方法一和方法二;如果返回的多個(gè)值類(lèi)型不同,可以用方法三。
import java.util.*;
public class Demo {
//方法1:返回list
public static List<int[]> returnList(){
List<int[]> list=new ArrayList<>();
list.add(new int[]{1});
list.add(new int[]{1, 2});
list.add(new int[]{1, 2, 3});
return list;
}
//方法2:返回Map,一個(gè)Map只能有一種數(shù)據(jù)類(lèi)型
public static Map<String, Integer> returnMap(){
Map<String,Integer> map = new HashMap<>();
map.put("age",1); //”age“是key,類(lèi)似于索引,1是索引對(duì)應(yīng)的int值
map.put("high",30);
//System.out.println(map.get("age"));
Map<String,int[]> map1 = new HashMap<>();
map1.put("array", new int[]{1, 2, 3});
//System.out.println(Arrays.toString( map1.get("array") ));
return map;
}
//方法3:一次性返回兩種類(lèi)型的數(shù)據(jù),結(jié)合了Map和list
public static List<Map> returnMapList(){
Map<String,Integer> map = new HashMap<>();
map.put("age",1);
map.put("high",30);
Map<String,int[]> map1 = new HashMap<>();
map1.put("array", new int[]{1, 2});
List<Map> listMap = new ArrayList<Map>();
listMap.add(map);
listMap.add(map1);
return listMap;
}
//測(cè)試代碼
public static void main(String[] args){
//返回list
List<int[]> list1 = returnList();
System.out.println(Arrays.toString(list1.get(0)) + Arrays.toString(list1.get(1)) + Arrays.toString(list1.get(2)) + "\nreturnlist結(jié)束\n");
//返回Map,一個(gè)Map只能有一種數(shù)據(jù)類(lèi)型
Map<String,Integer> mapTest = returnMap();
System.out.println("age = " + mapTest.get("age") +", high = " + mapTest.get("high") + "\nreturnMap結(jié)束\n");
//一次性返回兩種類(lèi)型的數(shù)據(jù),結(jié)合了Map和list
List<Map> list2 = returnMapList();
System.out.println(list2.get(0) +" , " + list2.get(1) + "\nreturnMapList結(jié)束");//list2.get(1)是數(shù)組的地址
System.out.print("調(diào)用返回的int和int[]:");
Map map0 = list2.get(0);
Map map1 = list2.get(1);
System.out.println( "age = " + map0.get("age") );
System.out.println("array = " + Arrays.toString((int[]) map1.get("array")));
// System.out.println(Arrays.toString((int[]) list2.get(1).get("array"))); //調(diào)用過(guò)程也可以這樣寫(xiě)
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用HttpClient實(shí)現(xiàn)Post請(qǐng)求實(shí)例
本篇文章主要介紹了Java使用HttpClient實(shí)現(xiàn)Post請(qǐng)求實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
Java數(shù)據(jù)庫(kù)連接池技術(shù)的入門(mén)教程
這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)庫(kù)連接池技術(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
SpringBoot整合Kafka完成生產(chǎn)消費(fèi)的方案
網(wǎng)上找了很多管理kafka整合springboot的教程,但是很多都沒(méi)辦法應(yīng)用到生產(chǎn)環(huán)境,很多配置都是缺少,或者不正確的,只能當(dāng)個(gè)demo,所以本文給大家介紹了SpringBoot整合Kafka完成生產(chǎn)消費(fèi)的方案,需要的朋友可以參考下2024-12-12
Spring?Boot?中使用@KafkaListener并發(fā)批量接收消息的完整代碼
kakfa是我們?cè)陧?xiàng)目開(kāi)發(fā)中經(jīng)常使用的消息中間件。由于它的寫(xiě)性能非常高,因此,經(jīng)常會(huì)碰到讀取Kafka消息隊(duì)列時(shí)擁堵的情況,這篇文章主要介紹了Spring?Boot?中使用@KafkaListener并發(fā)批量接收消息,需要的朋友可以參考下2023-02-02
idea新建maven項(xiàng)目沒(méi)有src目錄的操作方法
這篇文章主要介紹了idea新建maven項(xiàng)目沒(méi)有src目錄的兩種操作方法,需要的朋友可以參考下2018-03-03
JavaFX Metro UI 和 開(kāi)發(fā)庫(kù)使用簡(jiǎn)介
這篇文章主要介紹了JavaFX Metro UI 和 開(kāi)發(fā)庫(kù)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
使用Java實(shí)現(xiàn)Excel轉(zhuǎn)PDF的示例詳解
在實(shí)際的開(kāi)發(fā)過(guò)程中,我們常常會(huì)遇到需要將 Excel 文件轉(zhuǎn)換為 PDF 文件的需求,本文為大家介紹一種Java中的常見(jiàn)實(shí)現(xiàn)方式,需要的可以參考一下2025-02-02
Java代碼實(shí)現(xiàn)對(duì)properties文件有序的讀寫(xiě)的示例
本篇文章主要介紹了Java代碼實(shí)現(xiàn)對(duì)properties文件有序的讀寫(xiě)的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

