zoukankan      html  css  js  c++  java
  • 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个以及更多的对象容器,作为方法返回参数类型。

  • 相关阅读:
    html 中 #include file 的用法
    人人网FED CSS编码前端开发规范
    (转载)css垂直水平居中的整理
    CSS负边距自适应布局三例
    (转载)无缝滚动图片的js和jquery两种写法
    用css3实现鼠标移进去当前亮其他变灰
    应急响应
    扫描工具介绍
    入侵检测
    安全防护与加固
  • 原文地址:https://www.cnblogs.com/duanxz/p/3645058.html
Copyright © 2011-2022 走看看