起因:在寫java的時候,經常遇到函數需要返回2個值或者3個值,java必須編寫一個Object,來封裝,但很多應用場景只是臨時使用,構建對象感覺殺雞用宰牛刀,而其他語言有比較好的實現方法。(當然通過指針引用可以解決一部分問題)
如:一般寫法:

public class Tt
{

public static void main(String[] args)
{
Tt t = new Tt();
User user = t.getUser();
long id = user.getId();
String name = user.getName();
// TODO .. do something
}

public User getUser()
{
// 測試
User user = new User();
user.setId(1L);
user.setName("hello");
return user;
}

class User
{
private long id;
private String name;

public long getId()
{
return id;
}

public void setId(long id)
{
this.id = id;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}
}
}

使用Tuple來實現:

public class Tt
{

public static void main(String[] args)
{
Tt t = new Tt();
Tuple2<Long, String> user = t.getUser();
long id = user._1();
String name = user._2();
// TODO ..do something
}


private Tuple2<Long, String> getUser()
{
long id = 1L;
String name = "hello";
return Tuple.tuple(id, name);
}
}

Tuple類:
import java.io.Serializable;


public abstract class Tuple implements Serializable
{


/** *//**
* gen by eclipse
*/
private static final long serialVersionUID = -8719929625763890308L;


public static <A, B> Tuple2<A, B> tuple(A a, B b)
{
return new Tuple2<A, B>(a, b);
}


public static <A, B, C, D, E> Tuple3<A, B, C> tuple(A a, B b, C c)
{
return new Tuple3<A, B, C>(a, b, c);
}


public static final class Tuple2<A, B> extends Tuple implements Serializable
{


/** *//**
* gen by eclipse
*/
private static final long serialVersionUID = 7263645006696591635L;
private A a;
private B b;


private Tuple2(A a, B b)
{
this.a = a;
this.b = b;
}


public A _1()
{
return this.a;
}


public B _2()
{
return this.b;
}
}


public static final class Tuple3<A, B, C> extends Tuple implements Serializable
{


/** *//**
* gen by eclipse
*/
private static final long serialVersionUID = 482545776907024160L;

private A a;
private B b;
private C c;


private Tuple3(A a, B b, C c)
{
this.a = a;
this.b = b;
this.c = c;
}


public A _1()
{
return this.a;
}


public B _2()
{
return this.b;
}


public C _3()
{
return this.c;
}
}
}

note: 1、這里只是寫了2,3,如果有需要直接擴展實現就可以了
2、這里的Tuple類其實沒多大用處,都可以直接使用Tuple2, Tuple3,但為了方便統一從Tuple入口出去,創建了靜態方法。這樣寫更具擴展性。
Tuple:
用來表示一組單獨的數據,比如數據庫中的一條記錄;這一點很好理解哈,Tuple的每個Item就像一條記錄的每個字段。
當我們希望函數返回多個值的時候,我們可以使用Tuple類型作為函數的返回值,這樣我們就可以不用ref來定義多個參數了
Python中的Tuple類型 介紹:
Tuple 是不可變 list。 一旦創建了一個 tuple 就不能以任何方式改變它。
Tuple 與 list 的相同之處
- 定義 tuple 與定義 list 的方式相同, 除了整個元素集是用小括號包圍的而不是方括號。
- Tuple 的元素與 list 一樣按定義的次序進行排序。 Tuples 的索引與 list 一樣從 0 開始, 所以一個非空 tuple 的第一個元素總是 t[0]。
- 負數索引與 list 一樣從 tuple 的尾部開始計數。
- 與 list 一樣分片 (slice) 也可以使用。注意當分割一個 list 時, 會得到一個新的 list ;當分割一個 tuple 時, 會得到一個新的 tuple。
Tuple 不存在的方法
- 不能向 tuple 增加元素。Tuple 沒有 append 或 extend 方法。
- 不能從 tuple 刪除元素。Tuple 沒有 remove 或 pop 方法。
- 您不能在 tuple 中查找元素。Tuple 沒有 index 方法。
- 然而, 您可以使用 in 來查看一個元素是否存在于 tuple 中。
用 Tuple 的好處
- Tuple 比 list 操作速度快。如果定義了一個值的常量集,并且唯一要用它做的是不斷地遍歷它,請使用 tuple 代替 list。
- 如果對不需要修改的數據進行 “寫保護”,可以使代碼更安全。使用 tuple 而不是 list 如同擁有一個隱含的 assert 語句,說明這一數據是常量。如果必須要改變這些值,則需要執行 tuple 到 list 的轉換。
Tuple 與 list 的轉換
Tuple 可以轉換成 list,反之亦然。內置的 tuple 函數接收一個 list,并返回一個有著相同元素的 tuple。而 list 函數接收一個 tuple 返回一個 list。從效果上看,tuple 凍結一個 list,而 list 解凍一個 tuple。
Tuple 的其他應用
一次賦多值
>>> v = ('a', 'b', 'e')
>>> (x, y, z) = v
解釋:v 是一個三元素的 tuple, 并且 (x, y, z) 是一個三變量的 tuple。將一個 tuple 賦值給另一個 tuple, 會按順序將 v 的每個值賦值給每個變量。
Microsoft在MSDN中對Tuple的描述是“A tuple is a data structure that has a specific number and sequence of values.”,由于E文水平有限,我理解的大概意思就是:Tuple是具有指定數量和順序的值的一種數據結構。針對這種數據結構,.Net4.0中提供了一組Tuple類型,具體如下:
Tuple |
|
Tuple<T> |
|
Tuple<T1, T2> |
|
Tuple<T1, T2, T3> |
|
Tuple<T1, T2, T3, T4> |
|
Tuple<T1, T2, T3, T4, T5> |
|
Tuple<T1, T2, T3, T4, T5, T6> |
|
Tuple<T1, T2, T3, T4, T5, T6, T7> |
|
Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> |
|
通過這些Tuple類型的聲明我們可以看出.Net4.0中提供了從包含1個值到最多8個值的Tuple,我們可以通過第一個Tuple的靜態方法 Create來創建一個泛型Tuple<>的實例,例如Tuple<string, int> t = Tuple.Create("key", 789); 也可以使用泛型Tuple的構造函數來創建實例,例如Tuple<string, int> t = new Tuple<string, int>("key", 324);
知道了Tuple類型的定義后,我們什么時候會用到它呢?對于Tuple<T>來說,我覺得我們大多數時候都不會使用這樣一個數據類型將一個實際要用的類型包裝起來,然后進行調用。(有些人提到Tuple類型用來和F#等語言進行交互,我不是很了解關于F#的細節,或許是在與F#交互的時候能夠用到吧),拋開Tuple<T>不說,其它的Tuple<>類型為我們的程序開發帶來了極大的方便。以前當我們需要處理若干相關數據的時候,例如員工ID、員工年齡和員工入職時間,為了編程的結構合理,我們會定義一個新的員工類,讓它包含ID、年齡和入職時間等屬性(當然,你也可以分別聲明3個變量),現在,我們只需要聲明一個Tuple<string, int, DateTime>的對象即可,省去了定義一個新類的步驟,當然,我們這么做是以犧牲代碼的可讀性為代價的,畢竟我們訪問Tuple對象的時候是通過類似Item這樣的沒有實際含義的屬性來訪問它的成員的。