知识大全 为Java创建Pair类

Posted

篇首语:落花踏尽游何处,笑入胡姬酒肆中。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 为Java创建Pair类相关的知识,希望对你有一定的参考价值。

为Java创建Pair类  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Java中对于多个返回参数的选项是有限制的 一种方法只能返回一个对象 数组或原始函数 和其他语言不同的是它不会提供一种简易方式来消耗方法调用中的参数 实际上我们的选择是返回一个对象数组 一个集合 仅为返回的参数创建一个类 或者最终将其发送到你打算替换的对象中 所有这些方法都存在缺陷

  使用对象数组

  如果我们能够幸运地获取一套同类的返回参数 那么对象的数组就会是一个带有例外的选项 当我们打开这些对象时需要能分辨出每个参数 从另一方面来说 如果我们正在返回多个参数的不同类型 我们需要使用所有超类对象的数组 最有可能的就是对象本身 然后我们要抛出每一个打开的参数 我们已经丢失了类型安全性且返回参数命令出错的机会也可能增加

  使用集合

  与使用数组的方法类似 我们或许也能创造一个集合来实现返回 在集合之上使用数组主要是因为创建集合所需要代码的数量要比这段代码短

         List< Object> retVal = new ArrayList< Object>();

  retVal add(string );

  retVal add(num );

  retVal add(object );

  return retVal;

  而创建集合的代码要高于使用数组初始化设置

  return new Object[] string num object

  事实上在数组之上使用集合没有什么真正的优势 除非我们要使用映射以便通过名称或其他要素来返回值

  首次创建Java时 其简单程度是对日趋复杂的c++的一种颠覆 指针和内存管理被简化了 包括去除参数间接 常量 函数指针以及其他功能强大但容易混淆的性能 在c++中 我们可以用值或参照传递参数 这样可以对方法中的参照进行重新分配 并为你提供参数或返回更多值的方式

  使用JavaBeans

  C++也支持的structs允许简单结构化的数据包 当然 Java类可以简单完成双倍于structs的任务 但通常习惯以大量模板来扩大源码

  使用类和JavaBeans惯例的时候还存在一个问题 即对象本质上是易变的 这些对象有可能被方法的调用者和方法调用的类共享 这样就会导致易变状态的共享 而这中情况无益于多线程系统

  在Java中 你能用值传递的只剩下方法参数了 而且还不能是outparams 同时方法只能返回一个参数 看一下任意代码库就会发现大量的实例 不过却不是十分有效

  改进Java Beans方式

  那么应该怎样做呢?Java类选项事实上才是解决方案的关键以及对其方式进行改进 这些类可以成为structs更好的替代物

  让我们为返回的类确定两个参数 名称和出生日期

         public class PersonNameDOB

  private String name;

  private Date dob;

  public Date getDob()

  return dob;

  

  public void setDob(Date dob)

  this dob = dob;

  

  public String getName()

  return name;

  

  public void setName(String name)

  this name = name;

  

  

  显然这是一个人为的例子 我们有机会拥有一个已经定义的Person类 大家肯定也会有类似的例子 需要从方法中返回两个不同的对象 但是却没有已经为其定义的类 或者是返回的类夹带多余的信息 或许是比这更糟的情况 例如 如果有人调用了你的方法来使用或修改返回对象中的值

  上述情况所需代码更多 因此我们可以做一些简单的修改

         public class PersonNameDOB

  public final String name;

  public final Date dob;

  public PersonNameDOB(String name Date dob)

  this name = name;

  this dob = dob;

  

  

  其结果要短一些且更适合这项任务 值已经返回了 因此不需要setters了 我们只要在返回对象建成后创建值就可以了 它们不需要更改 由于它们位于构造器中 因此具有决定性作用 现在任务已经完成 将类的属性设为公开也没有风险了 同理 可以处理getters了 其结果更短 更易于使用

         PersonNameDOB personNameDOB = SSNLookup lookupBySSN( );

  System out println(personNameDOB name);

  System out println(personNameDOB dob);

  lookupBySSN方法

  public PersonNameDOB lookupBySSN(String ssn)

   Find the person record in the DB etc

  return new PersonNameDOB(person getName() person getDOB());

  

  如果这些太显而易见 请耐心看下去 我喜欢用这个方法来简化对象的返回 这种类型是安全的 因此在返回后不需要将对象抛出数组 而最后属性的修改意味着这些返回的对象不会被滥用 它们只是为了传输数据

  为了安全起见 建议你复制对象或使用不可改变的对象以应付值的意外修改 在我们的例子中 字符串是不可改变的 但是日期可以复制

         public PersonNameDOB lookupBySSN(String ssn)

   Find the person record in the DB etc

  return new PersonNameDOB(person getName() new Date(person getDOB() getTime()));

  

  这可以阻止调用者做接下来的操作

         PersonNameDOB personNameDOB = SSNLookup lookupBySSN( );

  personNameDOB dob setTime( );

  成对的需求

  以上的模式是笔者经常在Java应用程序接口调用中用来替代structs的方法 但是如果我们只是想返回两个类型对象 这些就还不够 看上去是唾手可得的东西其实仍然从JavaSE标准分配中神秘失踪 而这就是被原始化的Pair类 看看我们如何从上述模式来建立Pair类

  首先 值要比名称和出生日期都普遍 最普遍的是在将域名定为first和second

         public class Pair

  public final String first;

  public final Date second;

  public Pair(String first Date second)

  this first = first;

  this second = second;

  

  

  现在拥有了一个可以返回Strings和Dates对的通用类 但还不包括其他类型 将其扩展为通用类型

         public class Pair< A B>

  public final A first;

  public final B second;

  public Pair(A first B second)

  this first = first;

  this second = second;

  

  

  这样就好多了 没必要担心代表了一对返回类型快捷方式的通配符 这个类现在可以作为通用类型对来使用 如

         public static Pair< String Date> lookupBySSN(String ssn)

  // find the person in the DB

  return new Pair(person getName() new Date(person getDOB() getTime()));

  

  开始使用          Pair< String Date> personNameDOB = SSNLookup lookupBySSN( );

  System out println(personNameDOB first);

  System out println(personNameDOB second);

  Pair类还未完成 我们还要考虑类型是否真具有普遍性

   我们不想其他人扩展或更改Pair类 因为这可能破坏类的最初意图

   新的new Pair()是可以的 但是看上去有些不雅 我们可以改进一下

   Pair对于返回值是很有效的 但是如果要作为映射中的关键要素就有些勉为其难

   拥有用于调试或其他toString()用途的Pair字符串代表形式是非常好的

   最后 允许Pair和包含的对象可被序列化 其内容也被假定为可以序列化了

  因此 让我们看看它是如何改变Pair执行的

         public final class Pair< A B> implements Serializable

  private static final long serialVersionUID = L; // shouldn t

  // need to change

  public final A first;

  public final B second;

  private Pair (A first B second)

  this first = first;

  this second = second;

  

  public static < A B> Pair< A B> of (A first B second)

  return new Pair< A B>(first second);

  

  @Override

  public boolean equals(Object obj)

  if (obj == null)

  return false;

  

  if (getClass() != obj getClass())

  return false;

  

  final Pair other = (Pair) obj;

  if (this first != other first &&

  (this first == null || !this first equals(other first)))

  return false;

  

  if (this second != other second &&

  (this second == null || !this second equals(other second)))

  return false;

  

  return true;

  

  @Override

  public int hashCode()

  int hash = ;

  hash = * hash + (this first != null ?

  this first hashCode() : );

  hash = * hash + (this second != null ? this second hashCode() : );

  return hash;

  

  @Override

  public String toString ()

  return String format( Pair[%s %s] first second);

  

  

  这样就已经将构造器私有化 但是提供了一个看起来更适合的静态of()方法

  return Pair of(person getName() new Date(person getDOB() getTime()));

  Pair类已经完成 因此没有人可以取代它或改变类的原始意图 它看上去很严格 但却可以用于广泛的使用 如果有人想让Pair以不同方式运作 就应该写出适合自己的执行代码 并对其进行求证

  equals()和hash()方法意味着这个类不止可以用来返回值 它们还可以成为映射的关键 此处对使用该模式返回对象给出的建议是让IDE为我们创建equals和hashCode方法 IDE往往都有可插入的模板 其中包含已定义的最佳方法 因此我们只需让NetBeans创建就可以了

  toString()给出了pair的合适形式 如 Pair[FredJones Sun Mar : : PDT ] 这对于调试弹出很有用

  这一个类现在执行Serializable 相信此处我们的选择令人怀疑 但是集合是可序列化的 Pair应该也可以 如果Pair中的类不能序列化那么就如果集合中的类不能序列化一样糟糕 而Pair不应该阻止类中间的序列化

  完成了吗?

  既是又不是 这个类现在在Navigenics中使用 毫无疑问在其他Java应用程序中也存在类似的执行 那我们完成了没有呢?从 最具预见性 的角度来讲 我们完成了 从 任何时候都需要 的角度来说恐怕还没完成

  例如 这类Pairs不能做比较 增加一个pareTo()方法使之可比 但是要注意应对复杂的通用类设计 通常 比较第一个值很容易 如果它们相等 就要比较第二个值 这可能是最合适的行为 但是Pair的每次使用都正确吗?我们要检查一下作比较的类是否具有可比性 如果不具备 该怎么办?

  结论

cha138/Article/program/Java/hx/201311/26974

相关参考

知识大全 创建Java内部类的编译错误处理

创建Java内部类的编译错误处理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在创建非静态内部

知识大全 java里面如何创建一个内部类的实例?

  要想使用new生成一个内部类的实例需要先指向一个外部类的实例也就是先生成外部类的实例因为内部类可以调用外部类的人员成员当没有外部类实例的时候也就没有这些成员的内存空间内部类在实例化的时候调用外部类

知识大全 用Thread类创建线程

Java多线程初学者指南(2):用Thread类创建线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 用Thread类创建线程

初学Java多线程:用Thread类创建线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在J

知识大全 创建自己的违例

  并不一定非要使用Java违例这一点必须掌握因为经常都需要创建自己的违例以便指出自己的库可能生成的一个特殊错误——但创建Java分级结构的时候这个错误是无法预知的  为创建自己的违例类必须从一个现有

知识大全 java中 接口与抽象类的区别

  语法层次上的区别  ()创建方法  viewplainprint?  abstractclass 抽象类名{  }interface接口名{  }  ()内容  抽象类里面可以有属性和方

知识大全 将eclipse创建的java转化为web项目

  FinishedNowyourjavaprojecthasbeenconvertedintoawebprojectcha138/Article/program/Java/ky/20131

知识大全 java线程简介(线程的生命)

  创建线程      在Java程序中创建线程有几种方法每个Java程序至少包含一个线程主线程其它线程都是通过Thread构造器或实例化继承类Thread的类来创建的    Java线程可以通过直接

知识大全 打破Java定律:无需创建对象

打破Java定律:无需创建对象  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  我们知道在Java

知识大全 Java多线程如何创建多个线程

Java多线程如何创建多个线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线程的同