2、Pair,成双成对罗。

严肃的说,就是:
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还可以省去实体的一个字段,避免打破原有结构。

    个人认为有以下情况: