Tuple是一種資料結構(data structure),是多個不同型別物件的有序集合,集合中的元素間不必有關連,但把這些元素擺在一起通常具有某種意義。
例如["Java", 1.8, "Windows"]
裡面的元素彼此沒有關係,但擺在一起就看得出來是指Java的系統版本。
Java本身並沒有這種資料結構,所以要用類別來模擬Tuple。而Python則有Tuple,例如下面設定並印出Tuple的內容。
Python定義Tuple用小括弧()
將元素包起,每個元素用逗號,
分隔。
>>> tuple1 = ("hello", "world")
>>> tuple2 = ("Toyota", 2000, "2017")
>>> tuple3 = (1,3,5,7,9)
>>> print(tuple1)
('hello', 'world')
>>> print(tuple2)
('Toyota', 2000, '2017')
>>> print(tuple3)
(1, 3, 5, 7, 9)
Tuple雖然和List很像,都是裝載多個物件的有序集合,其差異如下:
- Tuple中可包含多個不同型別的物件;List中為多個相同型別的物件。
- Tuple是不可變的(Immutable),元素及結構不可被修改;List是可變的(Mutable),元素及結構可以被修改。
例如下面定義了一個Python的Tuple變數,然後試圖修改其元素內容。
>>> tuple1 = ("iPhone X", 20000)
>>> tuple1[1] = 18000
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
因為Tuple是不可變的,所以若修改內容會出現錯誤訊息。
在Java除了自己定義類別來實做Tuple,可以直接用javatuples套件,Maven依賴如下。
<!-- https://mvnrepository.com/artifact/org.javatuples/javatuples -->
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version>
</dependency>
javatuples提供了以下Tuple類別,分別裝載1到10個指定型別的元素。
Unit<A>
(1 element)Pair<A,B>
(2 elements)Triplet<A,B,C>
(3 elements)Quartet<A,B,C,D>
(4 elements)Quintet<A,B,C,D,E>
(5 elements)Sextet<A,B,C,D,E,F>
(6 elements)Septet<A,B,C,D,E,F,G>
(7 elements)Octet<A,B,C,D,E,F,G,H>
(8 elements)Ennead<A,B,C,D,E,F,G,H,I>
(9 elements)Decade<A,B,C,D,E,F,G,H,I,J>
(10 elements)
例外提供兩個與Pair一樣裝載兩個元素的類別,其名稱比較符合意義。
KeyValue<A,B>
(1 element)LabelValue<A,B>
(2 elements)
javatuples的Tuple類別具有以下特色:
- 型別安全(Typesafe)
- 不可變的(Immutable)
- 可遍歷(Iterable)
- 可序列化(Serializable)
- 可比較,實作了
Comparable
- 實作了
equals()
及hashCode()
- 實作了
toString()
以下為Tuple類別的一些簡單用法,可以用建構式或工廠方法with()
來產生物件。
Unit<Integer> unit = new Unit<>(1);
Pair<String, String> pair = Pair.with("hello", "world");
Triplet<String, Integer, String> triplet = new Triplet<>("Toyota", 2000, "Japan");
Quartet<Integer, Integer, Integer, Integer> quartet = Quartet.with(1, 2, 3, 5);
System.out.println(unit); // [1]
System.out.println(pair); // [hello, world]
System.out.println(triplet); // [Toyota, 2000, Japan]
System.out.println(quartet); // [1, 2, 3, 5]
System.out.println(pair.getValue0()); // hello
System.out.println(pair.getValue(1)); // world
pair = pair.setAt1("tuple"); // 回傳新的物件
System.out.println(pair); // [hello, tuple]
由於Tuple類別是不可變的,所以呼叫setAtX()
方法回傳的是新的Tuple物件。
不過在Java使用Tuple前,仔細想想為什麼Java沒有提供Tuple呢?因為Java的類別本身就是一種可以讓你自由定義任何型別的一種"Tuple"容器,因為這樣所以Java其實不用特別去使用Tuple,直接用定義好的類別就好了。
參考:
沒有留言:
張貼留言