Java元组Tuple介绍与使用
一、元組介紹
?
僅僅一次方法調(diào)用就可以返回多個(gè)對(duì)象,你應(yīng)該經(jīng)常需要這樣的功能吧.可以return語(yǔ)句只允許返回單個(gè)對(duì)(可能有人說(shuō)返回一個(gè)集合就可以了,請(qǐng)記住,一個(gè)集合也只是一個(gè)對(duì)象而已)因此,解決辦法就是創(chuàng)建一個(gè)對(duì)象,用它來(lái)持有想要返回的對(duì)象.當(dāng)然,可以在每次需要的時(shí)候,專門創(chuàng)建一個(gè)類來(lái)完成這樣的工作.可是有了泛型,我們就能夠一次性的解決問(wèn)題,以后再也不用再這種問(wèn)題上浪費(fèi)時(shí)間了.同時(shí),我們?cè)倬幾g器就可以確保類型安全.
上述概念稱為元組(tuple),它是將一組對(duì)象直接打包存儲(chǔ)與其中的一個(gè)單一對(duì)象.這個(gè)容器對(duì)象允許讀取其中的元素.但是不允許向其中存放新的對(duì)象.(這個(gè)概念也稱為數(shù)據(jù)傳送對(duì)象,或信使)
通常元素具有任意長(zhǎng)度,同時(shí),元組中的對(duì)象可以是任何不同的類型.不過(guò),我們希望能夠?yàn)槊恳粋€(gè)對(duì)象指明其類型,并且從容器中讀取出來(lái)時(shí),能夠得到正確的類型.要處理不同長(zhǎng)度的問(wèn)題,我們需要?jiǎng)?chuàng)建不同的元組.采用下面的編碼形式無(wú)疑是更安全的做法,這樣的話,如果程序員想要使用具有不同元素的元組,就強(qiáng)制要求他們創(chuàng)建一個(gè)新的元組對(duì)象.并且可以利用繼承機(jī)制實(shí)現(xiàn)長(zhǎng)度更長(zhǎng)的元組.
元組和列表list一樣,都可能用于數(shù)據(jù)存儲(chǔ),包含多個(gè)數(shù)據(jù);但是和列表不同的是:列表只能存儲(chǔ)相同的數(shù)據(jù)類型,而元組不一樣,它可以存儲(chǔ)不同的數(shù)據(jù)類型,比如同時(shí)存儲(chǔ)int、string、list等,并且可以根據(jù)需求無(wú)限擴(kuò)展。比如說(shuō)在web應(yīng)用中,經(jīng)常會(huì)遇到一個(gè)問(wèn)題就是數(shù)據(jù)分頁(yè)問(wèn)題,查詢分頁(yè)需要包含幾點(diǎn)信息:當(dāng)前頁(yè)數(shù)、頁(yè)大小;查詢結(jié)果返回?cái)?shù)據(jù)為:當(dāng)前頁(yè)的數(shù)據(jù)記錄,但是如果需要在前臺(tái)顯示當(dāng)前頁(yè)、頁(yè)大小、總頁(yè)數(shù)等信息的時(shí)候,就必須有另外一個(gè)信息就是:數(shù)據(jù)記錄總數(shù),然后根據(jù)上面的信息進(jìn)行計(jì)算得到總頁(yè)數(shù)等信息。這個(gè)時(shí)候查詢某一頁(yè)信息的時(shí)候需要返回兩個(gè)數(shù)據(jù)類型,一個(gè)是list(當(dāng)前也的數(shù)據(jù)記錄),一個(gè)是int(記錄總數(shù))。當(dāng)然,完全可以在兩個(gè)方法、兩次數(shù)據(jù)庫(kù)連接中得到這兩個(gè)值。事實(shí)上在查詢list的時(shí)候,已經(jīng)通過(guò)sql查詢得到總計(jì)錄數(shù),如果再開(kāi)一個(gè)方法,再做一次數(shù)據(jù)庫(kù)連接來(lái)查詢總計(jì)錄數(shù),不免有點(diǎn)多此一舉、浪費(fèi)時(shí)間、浪費(fèi)代碼、浪費(fèi)生命。言重了~在這種情況下,我們就可以利用二元組,在一次數(shù)據(jù)庫(kù)連接中,得到總計(jì)錄數(shù)、當(dāng)前頁(yè)記錄,并存儲(chǔ)到其中,簡(jiǎn)單明了!(http://www.cnblogs.com/davidwang456/p/4514659.html)
?
二、使用介紹
?
二元組常見(jiàn)代碼形式可以如下所示:
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 + ")"; } }?
利用繼承機(jī)制實(shí)現(xiàn)長(zhǎng)度更長(zhǎng)的元組.將上述二元組擴(kuò)展為三元組代碼形式可以如下所示: 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 + ")"; } } 利用繼承機(jī)制實(shí)現(xiàn)長(zhǎng)度更長(zhǎng)的元組.將上述三元組擴(kuò)展為四元組代碼形式可以如下所示: 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 + ")"; } }為了使用元組,你只需定義一個(gè)長(zhǎng)度適合的元組,將其作為方法的返回值,然后在return語(yǔ)句中創(chuàng)建該元組,并返回即可.例如下面使用方式:
使用方式實(shí)例一:
/*** 由于有了泛型,你可以很容易的創(chuàng)建元組,令其返回一組任意類型的對(duì)象,而你所要做的,只是編寫(xiě)表達(dá)式而已.*/ public class TupleTest { static TwoTuple<String, Integer> f(){ //Autoboxing conveerts 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); } public static void main(String[] args) { TwoTuple<String, Integer> ttsi = f(); System.out.println(ttsi); System.out.println(g()); System.out.println(h()); } } class Amphibian {} class Vehicle {}使用方式實(shí)例二:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map;public class DynamicProxyMixin {public static void main(String[] args) { Object mixin = MixinProxy.newInstance(new TwoTuple(new BasicImpl(), Basic.class), new TwoTuple(new TimeStampedImp(), TimeStamped.class), new TwoTuple(new SerialNumberedImpl(), SerialNumbered.class)); Basic b = (Basic) mixin; TimeStamped t = (TimeStamped) mixin; SerialNumbered s = (SerialNumbered) mixin; b.set("hello"); System.out.println(b.get()); System.out.println(t.getStamp()); System.out.println(s.getSerialNumber()); } } class MixinProxy implements InvocationHandler{ Map<String, Object> delegatesByMethod; public MixinProxy(TwoTuple<Object, Class<?>>... pairs){ delegatesByMethod = new HashMap<String, Object>(); for(TwoTuple<Object, Class<?>> pair : pairs){ for(Method method : pair.second.getMethods()){ String methodName = method.getName(); if(!delegatesByMethod.containsKey(methodName)){ delegatesByMethod.put(methodName, pair.first); } } } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); Object delegate = delegatesByMethod.get(methodName); return method.invoke(delegate, args); } public static Object newInstance(TwoTuple... pairs){ Class[] interfaces = new Class[pairs.length]; for(int i = 0; i < pairs.length; i++){ interfaces[i] = (Class) pairs[i].second; } ClassLoader cl = pairs[0].first.getClass().getClassLoader(); return Proxy.newProxyInstance(cl, interfaces, new MixinProxy(pairs)); } } interface TimeStamped{ long getStamp(); } class TimeStampedImp implements TimeStamped{ private final long timeStamp; public TimeStampedImp() { timeStamp = new Date().getTime(); } @Override public long getStamp() { return timeStamp; } } interface SerialNumbered{ long getSerialNumber(); } class SerialNumberedImpl implements SerialNumbered{ private static long counter = 1; private final long serialNumber = counter++; public long getSerialNumber(){ return serialNumber; } } interface Basic{ public void set(String val); public String get(); } class BasicImpl implements Basic{ private String value; public void set(String val){ value = val; } @Override public String get() { return value; } }總結(jié)
以上是生活随笔為你收集整理的Java元组Tuple介绍与使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何查找rpm方式安装的软件路径
- 下一篇: [译] 如何在东南亚拓展您的应用业务