装箱和拆箱

Java 语言中的每种原语类型都有一个对应的 JDK 类,如表 1 所示。

表 1. 原语和对应的 JDK 类

原语

对应的 JDK 类

boolean

java.lang.Boolean

byte

java.lang.Byte

char

java.lang.Character

short

java.lang.Short

int

java.lang.Integer

long

java.lang.Long

float

java.lang.Float

double

java.lang.Double

每个 JDK 类都提供了相应方法来解析它的内部表示,并将其转换为相应的原语类型。例如,下面这段代码将十进制值 238 转换为一个 Integer

int value = 238;         
         Integer boxedValue = Integer.valueOf(value);

此技术称为装箱,因为您将原语放在一个包装器或箱子中。

类似地,要将 Integer 表示转换为对应的 int 类,可以对它执行拆箱:

Integer boxedValue = Integer.valueOf(238);         
     int intValue = boxedValue.intValue();

自动装箱和自动拆箱

严格地讲,您不需要显式装箱和拆箱原语。可以使用 Java 语言的自动装箱和自动拆箱特性:

int intValue = 238;         
       Integer boxedValue = intValue;         
     //         
        intValue = boxedValue;

但是,建议您避免使用自动装箱和自动拆箱,因为它们可能导致代码可读性问题。装箱和拆箱代码段中的代码比自动装箱的代码更加一目了然,因此可读性更高;我相信投入这些额外工作是值得的。

解析和转换装箱的类型

您已经了解了如何获取一个装箱的类型,但如何将一个您怀疑拥有装箱类型的数字 String

String characterNumeric = "238";         
      Integer convertedValue = Integer.parseInt(characterNumeric);

也可以将 JDK 包装类型的内容转换为 String

Integer boxedValue = Integer.valueOf(238);         
       String characterNumeric = boxedValue.toString();

请注意,在 String 表达式中使用串联运算符时(您应该已在对 Logger 的调用中看到过),原语类型已自动装箱,而且包装器类型会自动在它们之上调用 toString()。非常方便。

列表

List 是一种有序集合,也称为序列。因为 List 是有序的,所以您能够完全控制项目进入 List 中的何处。Java List 集合只能包含对象(不能包含像 int,而且它为其行为方式定义了严格的契约。List 是一个接口,所以不能直接实例化它。这里将使用它的最常用实现 ArrayList。可通过两种方式执行声明。第一种方式使用显式语法:

List<          String          > listOfStrings = new ArrayList<          String          >();

第二种方式使用 “菱形” 运算符(在 JDK 7 中引入):

List<          String          > listOfStrings = new ArrayList<>();

请注意,ArrayList请注意,我将 ArrayList 对象赋给了一个 List 类型的变量。在 Java 编程中,可以将某种类型的变量赋给另一种类型,只要被赋值的变量是赋值变量所实现的超类或接口。在后面的单元中,将进一步介绍这些变量赋值类型的约束规则。

正式类型

前面的代码段中的 <Object> 被称为正式类型。<Object> 告诉编译器,这个 List 包含一个 Object 类型的集合,这意味着您可将您喜欢的任何实体放在该 List如果您想对能或不能放入 List

现在您的 List 仅能包含 Person

使用列表

使用 List(一般来讲就像使用 Java 集合一样)非常简单。以下是可对 List

  • 将实体放入 

List

  • 询问 

List

  • 从 

List要将实体放在 List 中,可调用 add()

List<          Integer          > listOfIntegers = new ArrayList<>();         
       listOfIntegers.add(Integer.valueOf(238));

add() 方法将元素添加到 List要询问 List 有多大,可调用 size()

List<          Integer          > listOfIntegers = new ArrayList<>();         
       listOfIntegers.add(Integer.valueOf(238));         
      Logger l = Logger.getLogger("Test");         
      l.info("Current List size: " + listOfIntegers.size());

要从 List 中检索某一项,可调用 get()

List<          Integer          > listOfIntegers = new ArrayList<>();         
         listOfIntegers.add(Integer.valueOf(238));         
        Logger l = Logger.getLogger("Test");         
         l.info("Item at index 0 is: " listOfIntegers.get(0));

在真实的应用程序中,一个 List 将包含记录或业务对象,您可能希望在处理过程中查看所有这些对象。您通常如何实现此目的?答案:您希望迭代 该集合,您可以这么做是因为 List 实现了java.lang.Iterable

迭代变量 (Iterable)

如果一个集合实现了 java.lang.Iterable,那么该集合被称为迭代变量集合。您可从一端开始,逐项地处理集合,直到处理完所有项。在 循环 单元中,我简要提及了迭代实现 Iterable

for (objectType varName : collectionReference) {         
               // Start using objectType (via varName) right away...         
          }

之前的代码比较抽象,这是一个更真实的示例:

List<          Integer          > listOfIntegers = obtainSomehow();         
      Logger l = Logger.getLogger("Test");         
        for (Integer i : listOfIntegers) {         
                    l.info("Integer value is : " + i);         
       }

这个小代码段所做的事情与下面这个长代码段相同:

List<          Integer          > listOfIntegers = obtainSomehow();         
      Logger l = Logger.getLogger("Test");         
     for (int aa = 0; aa < listOfIntegers.size(); aa++) {         
                Integer I = listOfIntegers.get(aa);         
                l.info("Integer value is : " + i);         
       }

第一个代码段使用了简写语法:它没有 index 变量(在本例中为 aa)要初始化,也没有调用 List 的get()因为 List 扩展了 java.util.Collection(它实现 Iterable),所以可以使用简写语法来迭代任何List

集 (Set)

根据定义,Set 是一种包含唯一元素的集合结构 — 即没有重复元素。List 可包含同一个对象数百次,而Set 仅可包含某个特定实例一次。Java Set因为 Set,所以不能直接实例化它。我最喜欢的实现之一是 HashSet,它很容易使用且类似于 List。以下是可对 Set

  • 将实体放入 

Set

  • 询问 

Set

  • 从 

SetSet

Set<          Integer          > setOfIntegers = new HashSet<          Integer          >();         
       setOfIntegers.add(Integer.valueOf(10));         
          setOfIntegers.add(Integer.valueOf(11));         
          setOfIntegers.add(Integer.valueOf(10));         
      for (Integer i : setOfIntegers) {         
               l.info("Integer value is: " + i);         
       }

您可能已料到,该 Set 中有 3 个元素,但它仅有两个,因为包含值 10 的 Integer在迭代 Set

Set<          Integer          > setOfIntegers = new HashSet();         
      setOfIntegers.add(Integer.valueOf(10));         
          setOfIntegers.add(Integer.valueOf(20));         
      setOfIntegers.add(Integer.valueOf(30));         
      setOfIntegers.add(Integer.valueOf(40));         
     setOfIntegers.add(Integer.valueOf(50));         
       Logger l = Logger.getLogger("Test");         
       for (Integer i : setOfIntegers) {         
                l.info("Integer value is : " + i);         
       }

对象可能按照不同于添加它们的顺序打印出来,因为 Set 可以确保唯一性,但不保证顺序。如果您将前面的代码粘贴到您的 Person 类的 main()