Android 表示一对“组元素”的Pair类

一、Pair初认识

打开词典,输入Pair,我们会得到这样的解释

Paste_Image.png

解释是:一副, 一条, 一把; 一双, 一对。
噢噢,成双成对罗。
什么,你看到的解释的是最后一行?罢了罢了,开始吧。

还是先看一下官网怎么说吧

Paste_Image.png

1、API 5 就有了,老兵啊
2、Pair<F,S>,成双成对罗。

严肃的说,就是:
Pair是一个容器,作用是轻便地对两个对象组成的元素组进行传递。这个对象提供了一个合理的equals()方法,如果两个对象的first和second值相等则返回true。

二、认识API

  • 1、Pair(F first, S second),一个Pair容器里面有2个元素,他们成组存在。
  • 2、Pair里面两个元素都是final的
  • 3、Pair的equals是值比较,不是地址比较

实例化方式

        Pair p1 = new Pair(18,"张三"); // 通过 构造函数 实例化对象
        Pair p2 = Pair.create(20, "李四");//通过 create方法以泛型的方式 实例化对象

Pair的equals

先看Pair自己的equals源码

        //android.util下的Pair equals
        public boolean equals (Object o){
            if (!(o instanceof Pair)) {
                return false;
            }
            Pair<?, ?> p = (Pair<?, ?>) o;
            return Objects.equal(p.first, first) && Objects.equal(p.second, second);
        }

        //这个是android.support.v4.util下的Pair equals
        public boolean equals (Object o){
            if (!(o instanceof Pair)) {
                return false;
            }
            Pair<?, ?> p = (Pair<?, ?>) o;
            return objectsEqual(p.first, first) && objectsEqual(p.second, second);
        }

        private static boolean objectsEqual (Object a, Object b){
            return a == b || (a != null && a.equals(b));
        }

无疑值比较。

实践代码

        String PAIR = "PAIR";

        Pair p1 = new Pair(18, "张三"); // 通过 构造函数 实例化对象
        Pair p2 = Pair.create(20, "李四");//通过 create方法 实例化对象
        Pair p3 = new Pair(18, "张三"); // 通过 构造函数 实例化对象

        boolean e1 = p1.equals(p2);
        Log.d(PAIR, "RESULT: " + e1); // false
        // Pair的 equals 不是地址比较

        boolean e2 = p1.equals(p3);
        Log.d(PAIR, "RESULT: " + e2);  //true
        // Pair的 equals 是值比较,而不是地址比较,当且仅当元素值一致时返回true

        boolean e3 = p1.equals("18");
        Log.d(PAIR, "RESULT: " + e3); // false

        boolean e4 = p1.equals(18);
        Log.d(PAIR, "RESULT: " + e4); // false

输出:

04-21 11:20:39.161 25404-25404/? D/PAIR: RESULT: false
04-21 11:20:39.161 25404-25404/? D/PAIR: RESULT: true
04-21 11:20:39.161 25404-25404/? D/PAIR: RESULT: false
04-21 11:20:39.161 25404-25404/? D/PAIR: RESULT: false

取值

  • 通过 对象.first 取出该组的第一个元素值
  • 通过 对象.second 取出该组的第一个元素值
        String PAIR = "PAIR";

        Pair p1 = new Pair(18, "张三"); // 通过 构造函数 实例化对象
        Log.d(PAIR, "取 first 数据: " + p1.first + "   " + p1.first.getClass()); // 取出
        Log.d(PAIR, "取 second 数据: " + p1.second + "   " + p1.second.getClass()); // 取出

.
.
输出:

04-21 11:24:12.583 27027-27027/? D/PAIR: 取 first 数据: 18   class java.lang.Integer
04-21 11:24:12.583 27027-27027/? D/PAIR: 取 second 数据: 张三   class java.lang.String
注意:Pair存储的“对元素”都是final,一旦复制,值不可改变,所以初始化一次赋值,不可修改。

关于API的部分就说到这里,因为实在简单,没有其他的特殊的了。有兴趣可以查看官方文档

三、Pair 有什么用

那问题就来了,Pair有什么用呢?

特性上面已经说了,Pair就是一组元素,他们是成对存在,你可能会想那不就是键值对吗,key和value吗?
有点类似,但是他们不一样,键值对的有一个关键的key让我们完成比较和取value等一系列操作。
但是Pair不一样,它就几乎只有3个方法,1个equals,一个取first值,一个取second。
道理摆在这里,具体怎么用,就看我们自己发挥了。

例子

比如我们知道,List和Map这两个集合容器是有很大不同的,但是如果在某些情况下,我们想用到List有的但是map没有的特性,但是我们数据又有一定关联成对出现或者说需要捆绑,那么我们是不是利用一下Pair呢?

再具体一点,比如我们现在在做一个IM软件,就以微信而言吧,会话列表肯定是根据最近联系人排序的,然后这是我们想用List实现,那么是不是可以这样创建一个List

List<Pair<Long, MyConversation>> sortList = new ArrayList<Pair<Long, MyConversation>>();

像这样,first我们存储时间戳,second我们存储比如名为MyConversation这个实体,那我们是不是就可以在得到数据后利用first进行排序了呢,肯定可以的。

当然了,你要是说我可以在MyConversation添加一个时间戳的字段的,那这样没办法好好聊天了,我们这里是为了示例,而且如果用Pair还可以省去实体的一个字段,避免打破原有结构。

用处

个人认为有以下情况:

  • 1、利用Pair和既有数据组成 组元素,不破坏原有结构的同时让两个数据产生绑定关系。
  • 2、利用Pair和List结合,形成类似Map的效果。

其他的,就看我们开发所需了。

本篇完。

推荐阅读更多精彩内容