0

我在学习数据结构课程,并且有大约一年半的 JAVA 经验。我试图理解书中没有明确定义的代码。在以下行中:

 Queue<Integer> encodingQueue = new LinkedList<Integer>();

我知道我们正在创建一个 Queue 类型的新 LinkedList 对象。我的问题是:

  1. 与 Integer 一起使用的 <> 是做什么用的?为什么它也与 LinkedList 对象而不是在参数中?
  2. 为什么使用 Integer 这个词而不是 int?

谢谢!

4

8 回答 8

3

http://docs.oracle.com/javase/tutorial/java/generics/

  1. 用于指定类型参数。这是您将类型传递给类的方式。列表/队列拥有它们,因为它是列表包含的对象类型。

  2. 使用整数而不是整数,因为整数不是对象。Integer 只是它的包装类。

于 2013-09-13T17:41:10.217 回答
3

祝你的数据结构课好运!

泛型

在 Java 中,这些数据结构(即 Queue、LinkedList、...)可以保存任何类型的对象。但是,通常情况下,给定的 Queue 或 LinkedList 实例将包含相同类型的集合(此处为整数)。

尖括号语法用于指定在此特定集合实例中允许哪些类型。

所以,阅读方式:

Queue<Integer> encodingQueue = new LinkedList<Integer>();

是...

“创建一个仅包含整数的新链表,并将该实例分配给引用变量'encodingQueue',该变量将被视为仅包含整数的队列。”

您正在使用的此功能称为“泛型”。你可以在这里阅读更多关于它的信息:http ://en.wikipedia.org/wiki/Generics_in_Java

自动装箱

在 Java 中,有两种类型:原语和对象引用。“int”是一个基元,“Integer”是一个类。

您不能在 Java 中创建对原语的引用,并且集合(如 LinkedList)仅包含对象引用。因此,您不能将原语填充到集合中(例如,您不能将“int”放入 LinkedList)。这就是 Java 为原语提供等效对象的原因:这样您就可以创建整数、浮点数、布尔值等事物的集合。

当您第一次开始使用原语时,可能会有些困惑;当明确需要时,Java 将尝试自动将原语转换为对象引用(反之亦然)。此功能称为“自动装箱”。

List myList = new LinkedList<Integer>();
myList.add(2);

这里,2 是一个基元。但是编译器知道你需要一个对象引用,而不是一个原语。因此,它通过(在后台)创建 Integer 类的新实例并将其值设置为 2 来自动“装箱”该值。

所以,这相当于(这就是实际发生的情况):

List myList = new LinkedList<Integer>();
myList.add(Integer.valueOf(2));

Integer.valueOf() 首先在内部缓存中查找该值的实例是否已经存在。如果是,则返回该值,否则为该值创建一个新的 Integer 对象。(谢谢鲍里斯指出这一点)

于 2013-09-13T17:57:06.727 回答
2

Integer 是原始“int”的基于对象的包装器版本。这允许基本类型在面向对象语言中很好地发挥作用。在这里阅读更多:

它们可以互换地使用本机和包装器,这称为“自动装箱/拆箱” http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

<> 是 Java 泛型的一部分(一种告诉编译器您希望使用什么对象的方法),更多信息在这里:

http://docs.oracle.com/javase/tutorial/java/generics/

快乐学习!

于 2013-09-13T17:41:54.480 回答
0

与 Integer 一起使用的 <> 是做什么用的?为什么它也与 LinkedList 对象而不是在参数中?

如果您有一个参数化集合Queue<Integer>而不是原始类型Queue ,则它确保不会将除整数以外的任何对象添加到集合中。

此功能是从 Java 1.5 引入的

为什么使用 Integer 这个词而不是 int?

集合处理对象而不是原语。



考虑来自Effective Java Item 23的这个例子

// Now a raw collection type - don't do this!
/**
* My stamp collection. Contains only Stamp instances.
*/
private final Collection stamps = ... ;

如果您不小心将一枚硬币放入您的邮票收藏中,错误的插入将编译并运行而不会出现错误:

// Erroneous insertion of coin into stamp collection
stamps.add(new Coin( ... ));

在您从邮票收藏中检索硬币之前,您不会收到错误消息:

// Now a raw iterator type - don't do this!
for (Iterator i = stamps.iterator(); i.hasNext(); ) {
Stamp s = (Stamp) i.next(); // Throws ClassCastException
... // Do something with the stamp
}

参数化示例

// Parameterized collection type - typesafe
private final Collection<Stamp> stamps = ... ;

从这个声明中,编译器知道 stamps 应该只包含 Stamp 实例并保证是这种情况,假设您的整个代码库是使用 1.5 或更高版本的编译器编译的,并且所有代码编译时都没有发出(或抑制;参见第 24 项)任何警告。当使用参数化类型声明 stamps 时,错误的插入会生成一个编译时错误消息,告诉您究竟出了什么问题:

Test.java:9: add(Stamp) in Collection<Stamp> cannot be applied to (Coin)
stamps.add(new Coin());
于 2013-09-13T17:50:37.753 回答
0
  1. 这推断要存储在队列中的对象的类型。您需要研究Java 泛型

  2. 集合存储对象,int 是原始类型,Integer 是 Java 对象表示。编译器会将您尝试放入队列中的任何整数自动装箱为整数。

于 2013-09-13T17:43:39.417 回答
0

1)<Integer>用于在编译时指定包含在您的对象中的对象Collection将是Integers,因此例如这不会编译:

Double d = 10d;
encodingQueue.add(d); <-- Compilation error

Integer2)使用而不是的原因int是您不能将原始数据类型存储到集合中,但您必须使用对象;由于 Integers 中的 int 自动装箱,您仍然可以编写encodingQueue.add(10),但是当您声明类型化集合(或者,通常是参数化类)时,您必须使用扩展Object作为参数的类。

于 2013-09-13T17:44:02.787 回答
0

<Integer>指定对象要保存的数据的类型。它是 Integer 而不是 int,因为 LinkedList 旨在保存 Object 而不是原语。所以

Queue<Integer> q = new LinkedList<Integer>();

意味着我们正在创建一个包含 Integer 类型对象的 LinkedList 对象,并且我们使用 Queue 引用变量来引用它。

于 2013-09-13T17:44:26.917 回答
0

它们是一种通用类型(请参阅@JTigger 的回答),这意味着它们可以是任何 Java 对象(包括自定义 Java 对象)的队列/列表,这允许您在 Java 内部的任何东西上使用队列/列表函数,而无需重新发明轮子。

示例:假设我们有自定义对象“planet”:

public Class Planet {
    private String name;
    public Planet(String name) { this.name = name; }
    public String getName() { return name; }
}

我们想将行星列表放入队列中。我们可以创建所述队列,并使用已经构建的 add() 和 remove() 方法。如果 Queue 不是通用类,我们将不得不构建自己的 add() 和 remove() 函数。因此,使用泛型我们可以列出太阳系中所有行星的名称:

public static void main (String args[]) {
    Queue<Planet> solarSystem = new LinkedList<Planet>();

    solarSystem.add(new Planet("Mercury"));
    solarSystem.add(new Planet("Venus"));
    solarSystem.add(new Planet("Earth"));
    solarSystem.add(new Planet("Mars"));
    solarSystem.add(new Planet("Jupiter"));
    solarSystem.add(new Planet("Saturn"));
    solarSystem.add(new Planet("Uranus"));
    solarSystem.add(new Planet("Neptune"));
    solarSystem.add(new Planet("Pluto")); //For Nostalgia's sake

    for (int i = 0; i < 9; i++) {
        System.out.println(solarSystem.element().getName());
        solarSystem.remove();
    }
}
于 2013-09-13T17:59:30.020 回答