[Java基础] 2个Pair工具类比较

2024-05-14 07:38
文章标签 java 基础 工具 比较 pair

本文主要是介绍[Java基础] 2个Pair工具类比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

之前再开发过程中, 发现有2个Pair类, 2个Pair类之间还是有一些差别和联系的, 将考究内容记录于此.
PS: 后续, 我们可以探究下Tuplate 三元组和多元组.


Pair类解析

javafx.util.Pair Java原生Pair类

基本使用Demo.

package com.yanxml.util.pair.demo;import javafx.util.Pair;/*** Pair 相关使用. Demo1* @author seanYanxml* @date 2022-02-28 00:00:00*/
public class PairInstanceDemo1 {public static void main(String[] args) {// 创建Pair createPair = new Pair<String, String>("abc","bcd");// 获取左边值System.out.println("key:" + createPair.getKey());// 获取右边值System.out.println("Value:" + createPair.getValue());// Pair 创建完成后. 无法修改.}
}

预计输出:

key:abc
Value:bcd
详解

在这里插入图片描述
通过结构, 我们可以发现. 这个类就这些基本成员和方法. 其中最主要的就是 构造函数 getKeygetValue 这3个方法.

package javafx.util;import java.io.Serializable;
import javafx.beans.NamedArg;/*** <p>A convenience class to represent name-value pairs.</p>* @since JavaFX 2.0*/
public class Pair<K,V> implements Serializable{/*** Key of this <code>Pair</code>.*/private K key;/*** Gets the key for this pair.* @return key for this pair*/public K getKey() { return key; }/*** Value of this this <code>Pair</code>.*/private V value;/*** Gets the value for this pair.* @return value for this pair*/public V getValue() { return value; }/*** Creates a new pair* @param key The key for this pair* @param value The value to use for this pair*/public Pair(@NamedArg("key") K key, @NamedArg("value") V value) {this.key = key;this.value = value;}/*** <p><code>String</code> representation of this* <code>Pair</code>.</p>** <p>The default name/value delimiter '=' is always used.</p>**  @return <code>String</code> representation of this <code>Pair</code>*/@Overridepublic String toString() {return key + "=" + value;}/*** <p>Generate a hash code for this <code>Pair</code>.</p>** <p>The hash code is calculated using both the name and* the value of the <code>Pair</code>.</p>** @return hash code for this <code>Pair</code>*/@Overridepublic int hashCode() {// name's hashCode is multiplied by an arbitrary prime number (13)// in order to make sure there is a difference in the hashCode between// these two parameters://  name: a  value: aa//  name: aa value: areturn key.hashCode() * 13 + (value == null ? 0 : value.hashCode());}/*** <p>Test this <code>Pair</code> for equality with another* <code>Object</code>.</p>** <p>If the <code>Object</code> to be tested is not a* <code>Pair</code> or is <code>null</code>, then this method* returns <code>false</code>.</p>** <p>Two <code>Pair</code>s are considered equal if and only if* both the names and values are equal.</p>** @param o the <code>Object</code> to test for* equality with this <code>Pair</code>* @return <code>true</code> if the given <code>Object</code> is* equal to this <code>Pair</code> else <code>false</code>*/@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o instanceof Pair) {Pair pair = (Pair) o;if (key != null ? !key.equals(pair.key) : pair.key != null) return false;if (value != null ? !value.equals(pair.value) : pair.value != null) return false;return true;}return false;}}

通过上述代码可以发现, Pair的左右都是通过2个Object来完成的, 和我们平常使用的类定义的成员变量并无区别.

但是, 值得注意的是. Pair是无修改方法的, 也就是说. 当Pair声明后, 其中的变量就不可变了.


org.apache.commons.lang3.tuple.Pair lang3包内的Pair类

看过了Java元素的Pair包, 我们再看下lang3的Pair类是如何定义的.

  • demo方法
package com.yanxml.util.pair.demo;import org.apache.commons.lang3.tuple.Pair;/*** Pair 相关使用. Demo2* @author seanYanxml* @date 2022-02-28 00:00:00*/
public class PairInstanceDemo2 {public static void main(String[] args) {Pair<String, String> demoPair = Pair.of("hello", "world");// 获取System.out.println("Key:" + demoPair.getKey());System.out.println("Value:" + demoPair.getValue());// 左右获取System.out.println("Left:" + demoPair.getLeft());System.out.println("Right:" + demoPair.getRight());// 更新值 会抛出异常.demoPair.setValue("123");}
}
  • 测试结果
Key:hello
Value:world
Left:hello
Right:world
Exception in thread "main" java.lang.UnsupportedOperationExceptionat org.apache.commons.lang3.tuple.ImmutablePair.setValue(ImmutablePair.java:100)at com.yanxml.util.pair.demo.PairInstanceDemo2.main(PairInstanceDemo2.java:24)

通过测试结果我们可以发现. 此Pair类, 除了声明的方式不同外, 其与原生的Pair毫无区别.
并且, 我们试图修改Pair内的对象时, 还会抛出异常.

org.apache.commons.lang3.tuple.Pair 源码解析

  • org.apache.commons.lang3.tuple.Pair
    在这里插入图片描述
  • org.apache.commons.lang3.tuple.ImmutablePair
    在这里插入图片描述
    下面我们分别看下源码. 会看到一个非常有意思的地方.
package org.apache.commons.lang3.tuple;import java.io.Serializable;
import java.util.Map.Entry;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.builder.CompareToBuilder;public abstract class Pair<L, R> implements Entry<L, R>, Comparable<Pair<L, R>>, Serializable {private static final long serialVersionUID = 4954918890077093841L;public Pair() {}public static <L, R> Pair<L, R> of(L left, R right) {return new ImmutablePair(left, right);}public abstract L getLeft();public abstract R getRight();public final L getKey() {return this.getLeft();}public R getValue() {return this.getRight();}public int compareTo(Pair<L, R> other) {return (new CompareToBuilder()).append(this.getLeft(), other.getLeft()).append(this.getRight(), other.getRight()).toComparison();}public boolean equals(Object obj) {if (obj == this) {return true;} else if (!(obj instanceof Entry)) {return false;} else {Entry<?, ?> other = (Entry)obj;return ObjectUtils.equals(this.getKey(), other.getKey()) && ObjectUtils.equals(this.getValue(), other.getValue());}}public int hashCode() {return (this.getKey() == null ? 0 : this.getKey().hashCode()) ^ (this.getValue() == null ? 0 : this.getValue().hashCode());}public String toString() {return "" + '(' + this.getLeft() + ',' + this.getRight() + ')';}public String toString(String format) {return String.format(format, this.getLeft(), this.getRight());}
}
package org.apache.commons.lang3.tuple;public final class ImmutablePair<L, R> extends Pair<L, R> {private static final long serialVersionUID = 4954918890077093841L;public final L left;public final R right;public static <L, R> ImmutablePair<L, R> of(L left, R right) {return new ImmutablePair(left, right);}public ImmutablePair(L left, R right) {this.left = left;this.right = right;}public L getLeft() {return this.left;}public R getRight() {return this.right;}public R setValue(R value) {throw new UnsupportedOperationException();}
}

在Pair方法内, 我们可以看到其构造函数主要有2个.

# Pair 类public Pair() {}public static <L, R> Pair<L, R> of(L left, R right) {return new ImmutablePair(left, right);}# ImmutablePair 类
public final class ImmutablePair<L, R> extends Pair<L, R> {private static final long serialVersionUID = 4954918890077093841L;public final L left;public final R right;public static <L, R> ImmutablePair<L, R> of(L left, R right) {return new ImmutablePair(left, right);}public ImmutablePair(L left, R right) {this.left = left;this.right = right;}}

其实我们经常使用的Pair.of(), 真实的实例化使用的是ImmutablePair, 也就是不可变的Pair类. 这也解释了为什么我们在执行set方法时, 会抛出异常.

# ImmutablePair 类 中public R setValue(R value) {throw new UnsupportedOperationException();}

还有一处比较有意思的一点是, 这个Pair类, 虽然提供了set方法, 但是执行此方法, 会给我们抛出异常. 这也是我们之前测试代码中的相关异常.


总结

本章, 主要介绍了2种Pair类的相关使用方式, 并且查看了相关源码. 我们可以得出如下差异点:

共同点
  • 使用泛型进行定义. class Pair<K,V>, 这样可以体现泛型的好处, 容易扩展.
  • 定义后的Pair内, 只有get方法, 而无set方法.
不同点
  • 声明对象的方式有所不同. 其实本质并无差别.
    • Java原生的Pair类, 需使用new Pair<K,V> (key,value)这样的方式进行声明.
    • Lang3的Pair类, 常使用Pair.of(key,value)进行声明.
  • Lang3的Pair类, 除getKey/getValue 方法外, 会额外提供 getLeft/getRight 这一对方法.

Reference

[源码] [javafx.util.Pair]
[源码] [org.apache.commons.lang3.tuple.Pair]

这篇关于[Java基础] 2个Pair工具类比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/988153

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听