Java元組Tuple介紹與使用


一、元組介紹

 

僅僅一次方法調用就可以返回多個對象,你應該經常需要這樣的功能吧.可以return語句只允許返回單個對(可能有人說返回一個集合就可以了,請記住,一個集合也只是一個對象而已)因此,解決辦法就是創建一個對象,用它來持有想要返回的對象.當然,可以在每次需要的時候,專門創建一個類來完成這樣的工作.可是有了泛型,我們就能夠一次性的解決問題,以后再也不用再這種問題上浪費時間了.同時,我們再編譯器就可以確保類型安全.

上述概念稱為元組(tuple),它是將一組對象直接打包存儲與其中的一個單一對象.這個容器對象允許讀取其中的元素.但是不允許向其中存放新的對象.(這個概念也稱為數據傳送對象,或信使)

通常元素具有任意長度,同時,元組中的對象可以是任何不同的類型.不過,我們希望能夠為每一個對象指明其類型,並且從容器中讀取出來時,能夠得到正確的類型.要處理不同長度的問題,我們需要創建不同的元組.采用下面的編碼形式無疑是更安全的做法,這樣的話,如果程序員想要使用具有不同元素的元組,就強制要求他們創建一個新的元組對象.並且可以利用繼承機制實現長度更長的元組.

元組和列表list一樣,都可能用於數據存儲,包含多個數據;但是和列表不同的是:列表只能存儲相同的數據類型,而元組不一樣,它可以存儲不同的數據類型,比如同時存儲int、string、list等,並且可以根據需求無限擴展。比如說在web應用中,經常會遇到一個問題就是數據分頁問題,查詢分頁需要包含幾點信息:當前頁數、頁大小;查詢結果返回數據為:當前頁的數據記錄,但是如果需要在前台顯示當前頁、頁大小、總頁數等信息的時候,就必須有另外一個信息就是:數據記錄總數,然后根據上面的信息進行計算得到總頁數等信息。這個時候查詢某一頁信息的時候需要返回兩個數據類型,一個是list(當前也的數據記錄),一個是int(記錄總數)。當然,完全可以在兩個方法、兩次數據庫連接中得到這兩個值。事實上在查詢list的時候,已經通過sql查詢得到總計錄數,如果再開一個方法,再做一次數據庫連接來查詢總計錄數,不免有點多此一舉、浪費時間、浪費代碼、浪費生命。言重了~在這種情況下,我們就可以利用二元組,在一次數據庫連接中,得到總計錄數、當前頁記錄,並存儲到其中,簡單明了!(http://www.cnblogs.com/davidwang456/p/4514659.html)

 

二、使用介紹

 

二元組常見代碼形式可以如下所示:

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 + ")"; } }

 

利用繼承機制實現長度更長的元組.將上述二元組擴展為三元組代碼形式可以如下所示:
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 + ")"; } }
利用繼承機制實現長度更長的元組.將上述三元組擴展為四元組代碼形式可以如下所示:
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 + ")"; } }

為了使用元組,你只需定義一個長度適合的元組,將其作為方法的返回值,然后在return語句中創建該元組,並返回即可.例如下面使用方式:

使用方式實例一:

/** * 由於有了泛型,你可以很容易的創建元組,令其返回一組任意類型的對象,而你所要做的,只是編寫表達式而已. */ 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 {}

使用方式實例二:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM