Java 使用节点时,构造函数节点不能应用于给定类型
我正在编写一个代码,如果MyStack中的新元素是唯一的,那么它会在MyStack中添加新元素。我必须复制并粘贴节点的起始代码,所以我遇到了一个问题。我一直收到两条错误消息,即使在尝试了各种解决方法之后,我也不太明白为什么。我甚至尝试过使用一些我以前使用过的助手函数,所以我特别困惑。 我经常遇到的两个错误是: -无法推断MyStack.Node的类型参数(实际参数和形式参数长度不同) -构造函数节点不能应用于给定类型。必需,无参数,找到:任何 这是我的密码:Java 使用节点时,构造函数节点不能应用于给定类型,java,linked-list,enqueue,Java,Linked List,Enqueue,我正在编写一个代码,如果MyStack中的新元素是唯一的,那么它会在MyStack中添加新元素。我必须复制并粘贴节点的起始代码,所以我遇到了一个问题。我一直收到两条错误消息,即使在尝试了各种解决方法之后,我也不太明白为什么。我甚至尝试过使用一些我以前使用过的助手函数,所以我特别困惑。 我经常遇到的两个错误是: -无法推断MyStack.Node的类型参数(实际参数和形式参数长度不同) -构造函数节点不能应用于给定类型。必需,无参数,找到:任何 这是我的密码: public class M
public class MyStack<Anything>
{
private Node first, last;
private class Node<Anything>
{
Anything item;
Node next;
}
public boolean contains(Anything value)
{
for (Node curr = first; curr != null; curr = curr.next)
{
if (value.equals(curr.item)) {
return true;
}
}
return false;
}
public void add(Anything value)
//method that adds a new value to the end of the list
//COMPLETE
{
Node temp = first;
while(temp.next!=null){ //finds the end
temp=temp.next;
}
temp.next=new Node(value, null); //assigns new value
}
public void enqueue(Anything info){
if (this.contains(info)==true) { //if the info is already present
System.out.println("the stack already contains this value");
return;
}
//if we actually need to add the info
if (first == null) { //if there is nothing in the stack
Node temp= first;
first = new Node<>(info,temp);
first = temp;
return;
}
if (first != null) { //if there is already stuff
Node temp = first;
while (temp.next == null)
{ Node newNode= new Node<>(info, temp);
temp.next = newNode;
}
return;
}
}
}
公共类MyStack
{
首先是私有节点,最后是私有节点;
私有类节点
{
任何项目;
节点下一步;
}
公共布尔值包含(任何值)
{
for(节点curr=first;curr!=null;curr=curr.next)
{
if(值等于(当前项目)){
返回true;
}
}
返回false;
}
公共无效添加(任何值)
//方法将新值添加到列表的末尾
//完整的
{
节点温度=第一;
while(temp.next!=null){//查找结束
温度=下一个温度;
}
temp.next=新节点(值,null);//分配新值
}
公共无效排队(任何信息){
if(this.contains(info)==true){//如果信息已经存在
System.out.println(“堆栈已包含此值”);
返回;
}
//如果我们真的需要添加信息
if(first==null){//如果堆栈中没有任何内容
节点温度=第一;
第一个=新节点(信息、温度);
第一个=温度;
返回;
}
if(first!=null){//如果已经有东西了
节点温度=第一;
while(temp.next==null)
{Node newNode=新节点(info,temp);
temp.next=newNode;
}
返回;
}
}
}
正如@Andreas已经指出的,节点需要一个构造函数
代码中还有一些其他缺陷:
使用泛型
对于您的代码,您只能存储类任何对象,这严重限制了它的可重用性。改用泛型,您可以为更多目的重用此类
链接列表
我建议您使用双链接列表的范例。这样,您就不需要找到最后一个节点
来向堆栈添加内容<代码>节点现在有一个指向其上一个和下一个元素的指针
使用最后一个
对象
您拥有最后一个对象,但从未使用过它。要确定当前对象是否是最后一个将值与null
进行比较的对象。这样做的效果是,存储null
值将破坏您的列表。相反,与对象last
相比,此对象是唯一的,并保证您位于列表的末尾。first
和last
都是不包含值的节点,仅用于标记列表的开始/结束
添加元素
使用上述更改,方法enqueue(T value)
中的代码变得非常简单:您只需检查是否包含(value)
并决定是否将值添加到列表中
所有这些更改都会导致以下代码:
public class MyStack<T extends Object> {
private Node first, last;
public MyStack() {
first = new Node(null, null, null);
last = new Node(null, null, first);
first.next = last;
}
private class Node {
T item;
Node next;
Node previous;
public Node(T item, Node next, Node previous) {
this.item = item;
this.next = next;
this.previous = previous;
}
}
public boolean contains(T value) {
for (Node curr = first.next; curr != last; curr = curr.next) {
if (value.equals(curr.item)) {
return true;
}
}
return false;
}
/**
* method that adds a new value to the end of the list
*/
public void add(T value)
{
Node secondLast = last.previous;
Node added = new Node(value, last, secondLast);
secondLast.next = added;
last.previous = added;
}
/**
* only adds value if it is not already contained by the Stack
*/
public void enqueue(T value) {
if (this.contains(value) == true) { // if the info is already present
System.out.println("the stack already contains this value");
}
else {
add(value);
}
}
public static void main(String[] args) {
MyStack<String> test = new MyStack<>();
test.add("foo");
test.add("bar");
test.add("baz");
System.out.println(test.contains("bar"));
System.out.println(test.contains("new"));
test.enqueue("baz");
test.enqueue("MyStack");
}
}
公共类MyStack{
首先是私有节点,最后是私有节点;
公共MyStack(){
第一个=新节点(null,null,null);
last=新节点(null,null,first);
first.next=last;
}
私有类节点{
T项;
节点下一步;
节点前向;
公共节点(T项、下一个节点、上一个节点){
this.item=项目;
this.next=next;
this.previous=先前;
}
}
公共布尔包含(T值){
for(节点curr=first.next;curr!=last;curr=curr.next){
if(值等于(当前项目)){
返回true;
}
}
返回false;
}
/**
*方法将新值添加到列表的末尾
*/
公共无效添加(T值)
{
节点secondLast=last.previous;
添加的节点=新节点(值、最后一个、第二个);
secondLast.next=已添加;
last.previous=已添加;
}
/**
*仅当堆栈尚未包含该值时才添加该值
*/
公共无效排队(T值){
if(this.contains(value)==true){//如果信息已经存在
System.out.println(“堆栈已包含此值”);
}
否则{
增加(价值);
}
}
公共静态void main(字符串[]args){
MyStack测试=新MyStack();
测试。添加(“foo”);
测试。添加(“条”);
测试。添加(“baz”);
System.out.println(测试包含(“条”));
System.out.println(test.contains(“new”));
测试排队(“baz”);
测试排队(“MyStack”);
}
}
命名
正如你们可能已经注意到的,在我的解释中,我把这个类称为列表。这是因为它满足了列表的更多特性。堆栈通常只提供方法push
将某些内容放在堆栈顶部,以及pop
移除并返回最顶部的对象。(可选)peek
可以返回最顶端的对象,而无需将其从堆栈中移除
还考虑重命名方法<代码> eNeave>代码>:队列中使用队列(很明显),队列不允许添加两个相等的对象。所以这个名字是有误导性的。我将这种方法称为
addIfN