Java 的 Tuple 元組數據類型


元組類型,即 Tuple 常在腳本語言中出現,例如 Scala 的 ("Unmi", "china@qq.com", "blahbla")。元組可認為是象數組一樣的容器,它的目的是讓你方便構造和引用,例如 Pair 可認為是一個只能存兩個元素的元組,像是個 Map; 真正的元組應該是可以任意多個元素的容器,繞來繞去,它還是數組,或列表,所以我們實現上還是要借助於數組或是列表。

先看 Scala 中什么是元組:

val tuple = ("Unmi", "fantasia@sina.com", "blahblah...")
println(tuple._1)  //輸出 Unmi

Scala 中訪問從 1 開始,用 ._1 方式來訪問其中的元素。

 

場景:當在一個方法中, 你需要返回幾個對象,這幾個對象的類型一致,你可以返回一個數組;如果幾個對象的類型不同呢,當然你可以返回一個Object[]數組,可是這樣在使用結果數組的時候,就需要強轉對象的類型,會導致類型不安全;也可以定義一個dto,當多個場景下需要使用的不同,需要定義多個dto,這樣會類爆炸,而且重用率極低;在非常接近Java語言的Scala里有元組的定義:val t = (1, 3.14, "Fred"),就是一個不同類型的數據放到一個線性集合里,在Java里我們可以模擬出一個類似的結構,以適合上面的場景。

示例一:

參照於此,寫出一個 Java 版本的 Tuple,為增長你的鍵盤的使用壽命,我們把方法名也縮短了,例如 make 縮寫為 mk,引用元素的方法名為 _,仍然保持 Java 的習慣,索引從 0 開始:

package com.sf.tuple;

/**
 * A simple java tuple
 */
public class Tuple<A> {

    /**
     * 靜態方法
     * 
     * @param args
     * @return
     */
    public static <A> Tuple mk(A... args) {
        return new Tuple(args);
    }

    private A[] items;

    /**
     * 私有構造函數
     * 
     * @param items
     */
    private Tuple(A[] items) {
        this.items = items;
    }

    public A _(int index) {
        if (index < 0 || items == null || index > items.length - 1) {
            return null;
        }
        return items[index];
    }

    public static void main(String[] args) {
        Tuple<String> t = Tuple.mk("Unmi", "china@qq.com");
        System.out.println(t._(0)); // 輸出 Unmi
        System.out.println(t._(1)); // 輸出 china@qq.com
    }
}

結果:

Unmi
china@qq.com

代碼間加了一個 main 測試方法,上面的代碼輸出什么無需多說了。

這樣就實現了 Tuple.mk()  后接任意多個參數來構造一個 Tuple 對象。

示例二:

package com.sf;

import com.google.common.base.Optional;

abstract class Tuple {  
  
    public static void main (String[] args) {  
        Tuple tuple2 = Tuple.<String, Integer>of("hello", 1);  
        Tuple tuple3 = Tuple.<String, Integer, String>of("hello", 1, "hi");  
        System.out.println(tuple2._1().get() + "|" + tuple2._2().get());  
        System.out.println(tuple3._1().get() + "|" + tuple3._2().get() + "|" + tuple3._3().get());  
  
    }  
  
    public static  <E, T> Tuple of (E e, T t) {  
        return new Tuple2(e, t);  
    }  
  
    public static  <E, T, K> Tuple of (E e, T t, K k) {  
        return new Tuple3(e, t, k);  
    }  
  
    public abstract <E> Optional<E> _1 ();  
  
    public abstract <E> Optional<E> _2 ();  
  
    public abstract <E> Optional<E> _3 ();  
  
}  
  
class Tuple2<E, T> extends Tuple {  
    private E e;  
    private T t;  
  
    Tuple2 (E e, T t) {  
        this.e = e;  
        this.t = t;  
    }  
  
    @Override  
    public Optional<E> _1 () {  
        return Optional.of(e);  
    }  
  
    @Override  
    public Optional<T> _2 () {  
        return Optional.of(t);  
    }  
  
    @Override  
    public <E> Optional<E> _3() {  
        return Optional.absent();  
    }  
}  
  
class Tuple3<E, T, K> extends Tuple {  
    private E e;  
    private T t;  
    private K k;  
  
    Tuple3 (E e, T t, K k) {  
        this.e = e;  
        this.t = t;  
        this.k = k;  
    }  
  
    public Optional<E> _1 () {  
        return Optional.of(e);  
    }  
  
    public Optional<T> _2 () {  
        return Optional.of(t);  
    }  
  
    public Optional<K> _3 () {  
        return Optional.of(k);  
    }  
} 

結果:

hello|1
hello|1|hi

上面的代碼中定義了三個類,父類為抽象類Tuple,此父類就是定義了一些模板方法,方法名有點不像Java方法名的命名規范,那是模仿scala里的方法命名,Tuple類沒有其他作用,只是提供靜態方法,創建Tuple的之類充當容器,提供多個容器的入口;

 Tuple2<E,T>可以充當兩個對象的容器,該容器內保持兩個對象的引用,通過方法_1(), _2()獲取第一個和第二個對象的值,在此並沒有直接返回對象,而是返回一個Optional對象,這是提醒使用返回值的方法做非Null檢查;

 Tuple3<E,T,K>原理類似Tuple2,類似的可以做針對4個以及更多的對象容器,作為方法返回參數類型。

 


免責聲明!

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



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