Java/优先级队列和构造函数和类型

Posted

技术标签:

【中文标题】Java/优先级队列和构造函数和类型【英文标题】:Java/Priority queue and constructors and type 【发布时间】:2015-04-24 08:07:48 【问题描述】:

我对下一行的一些事情并不了解

PriorityQueue<D> myList = new ImplementPriorityQueue<D>(K + 1);

PriorityQueue&lt;D&gt; 是一个对象,例如一个整数,它是一个“PriorityQueue”,一个具有类型 D 元素的链表(因为 )(D 是一个通用术语)。而ImplementPriorityQueue是构造函数,也是链表? 但是对象和构造函数不应该同名吗?

此外,构造函数允许您构造对象,然后能够使用构造函数中编写的函数?对吗?

【问题讨论】:

PriorityQueue&lt;D&gt; 是变量的类型。 ImplementPriorityQueue&lt;D&gt; 是正在创建的对象的类型。 Object o = "test"一样,在这种情况下对象本身只是一个String的超类,其中PriorityQueue似乎是ImplementPriorityQueue的超类 但是 并不意味着它是一个链表? @christinejakotte &lt;&gt; 只是一个运算符,它告诉你该类期待一个泛型,这不是只有LinkedList 使用的东西。你也可以在任何基础类中自己实现它 【参考方案1】:

这称为多态性,Java 使用继承来定义彼此的子类,以便在整个类中提供一致性。在这种情况下,PriotityQueue 是声明的类型,ImplementPriorityQueue 是分配给此声明的实例。这允许灵活使用 ImplementPriorityQueue。

E.G - 可以像这样创建一个数组列表

集合列表 = new ArrayList();

这是因为 arraylist 扩展了集合类。这反过来又可以帮助您编写代码,允许您在以后更改列表实现。

E.G

集合列表 = new LinkedList();

这将使您之前的所有代码与您的链表保持一致,因为之前的数组列表受限于 Collection 的规则

【讨论】:

所以基本上,使用“集合”,我可以将我的对象“列表”从 arraylist 更改为linkedlist juste,因为linkedlist 是超类集合的一部分? 一个对象可以被实例化为上面任何超类的声明,包括它自己。 E.G String 是 Object 的子类。所以可以像这样创建一个字符串 Object str = new String("JAVA");【参考方案2】:

来自Javadocs:

强制转换展示了在继承和实现允许的对象中使用一种类型的对象代替另一种类型。例如,如果我们写

Object obj = new MountainBike(); // or Object obj = new String();

然后 obj 既是 Object 又是 MountainBike(或 String 用于后面的情况) - 直到 obj 被分配另一个不是 MountainBike 的对象。这称为隐式转换

另外一个例子,除了正常的方式:

Child c = new Child(); // or Parent p = new Parent();

我们也可以使用(根据我们的要求偏离航线)

Parent p = new Child();

这里的Child 类可以扩展Parent 类或其任何子类。 注意 - 在这种情况下,Polymorphism 会出现,它的常规规则将适用。

【讨论】:

但在那个例子中有 public MountainBike myBike = new MountainBike(); ;但是我们不能输入public Bycicle myBike = new MountainBike();,因为 MountainBike 是 Bycicle 的子类,这意味着同样的事情吗?就像这里我们不能放ImplementPriorityQueue&lt;D&gt; myList = new ImplementPriorityQueue&lt;D&gt;(K + 1); 吗? 当然,我们可以写。基本上,您需要通过 Javadocs 的多态性和继承。我也编辑了我的答案。 但是,到目前为止,在您的示例中 p=c 不是吗?至少我们可以说它们是同一种类型的对象? 你可以写 p = c (用于分配)。可以使用父类型的引用代替子类型。【参考方案3】:

PriorityQueue 是一个类,而不是一个对象。

myListPriorityQueue 类型的对象,泛型类型为 D

ImplementPriorityQueue 是对象的实际类型,在本例中是PriorityQueue 的子类。

new ImplementPriorityQueue&lt;D&gt;(K + 1) 使用签名为ImplementPriorityQueue(int) 的构造函数实例化分配给myList 的对象。

顺便说一句,你为什么要调用队列myListmyQueue 可能不会那么混乱。

编辑 回应关于 myList 有两种类型的评论......

PriorityQueue 是声明的类型,因此这就是您的代码将其视为的类型。它有peekcontains等方法,这些方法都可以被你的代码访问。

ImplementPriorityQueue 是 myList 的实际类型。它可能具有诸如explodemakeIceCream 等方法,但您的代码将可以访问这些方法,因为它将 myList 视为PriorityQueue - 和PriorityQueue 中不存在这些方法。

尽可能通用总是一个好主意 - 但在构建代码时不要更通用。让我们看一个循环遍历字符串列表并打印值的方法示例。

public void printValues(ArrayList<String> list) 
    for (String s : list) 
        System.out.println(s);
    

你可以通过传递一个 ArrayList 来调用这个方法:

ArrayList<String> list = new ArrayList<>();
printValues(list);

这可以正常工作...但是如果您的代码中也有 LinkedLists 怎么办?以下代码无法编译,因为 printValues 需要一个 ArrayList。

LinkedList<String> list = new LinkedList<>();
printValues(list);  <--- compilation error here

为此设计的方法是使用更通用的 ArrayList 和 LinkedList 版本。这两个类都扩展了 AbstractList,所以我们可以把它改成这个。

public void printValues(AbstractList<String> list) 
    for (String s : list) 
        System.out.println(s);
    

现在,我们可以传递 LinkedLists、ArrayLists 和任何其他扩展 AbstractList 的东西。 不过,我们可以进一步改进这一点,因为AbstractList 确实是一个实现细节。我们真正关心的是列表,因此我们真正应该关注的是定义类列表行为的接口。这是 java.util.List,我们的最终版本的方法看起来像这样。

public void printValues(List<String> list) 
    for (String s : list) 
        System.out.println(s);
    

现在,因为我们使用的是定义而不是实际类型,所以我们有一个更有用的方法,它将采用任何实现 List 的东西。

这种行为称为多态性——只要它们之间存在父/子关系,我们就可以将 A 类型的对象视为 B 类型的对象。这就是为什么您可以将任何事物视为对象的原因,因为对象是一切事物的父对象。

至于尽可能通用的东西,但不再可能 - List 与列表一样通用。例如,您不会说“嗯,Object 更通用!”。

【讨论】:

但是为什么 myList 有两种类型 PriorityQueue 和 ImplementPriorityQueue ?这就像说一个对象是一个字符串和一个双精度的例子......我不明白这部分 myList 有一个声明的类型,它是PriorityQueue 和一个实际的类型,它是ImplementPriorityQueue。我会更新我的详细答案。 所以ImplementPriorityQueuePriorityQueue 的子类型? @christinejakotte 是的 - 请参阅更新的答案。您可以将ImplementPriorityQueue 视为ArrayList,将PriorityQueue 视为AbstractList,将List 视为Queue(队列是您正在使用的队列类型实现的接口)。 谢谢。 public static &lt;E extends Comparable&lt;E&gt;&gt; MyList&lt;E&gt; 在课程开始时是什么意思?这意味着 E 将始终是一个通用元素,我们可以将 Comparable 类的方法应用于它?

以上是关于Java/优先级队列和构造函数和类型的主要内容,如果未能解决你的问题,请参考以下文章

Java数据结构及算法实战系列012:Java队列06——数组实现的优先级阻塞队列PriorityBlockingQueue

Java数据结构及算法实战系列012:Java队列06——数组实现的优先级阻塞队列PriorityBlockingQueue

堆和优先级队列1:堆概念和构造过程

Java之优先队列

Java数据结构及算法实战系列011:数组实现的优先级队列PriorityQueue

Java数据结构及算法实战系列011:数组实现的优先级队列PriorityQueue