【问题标题】:Using a ListIterator使用 ListIterator
【发布时间】:2017-05-05 18:41:23
【问题描述】:

我有一项很难完成的任务。这是一个两部分的实验,演示 LinkedList 和 Queue 类。我必须使用 offer() 方法和迭代器来完成我遇到问题的部分。我编写了一个名为 BasketBallPlayer 的类,并使用 add 将几个该类型的对象添加到linkedList。然后我使用了一个迭代器来列出这些对象。但是,当我使用 offer() 方法时,我无法用我的代码列出对象。 这是引发并发修改异常的sn-p

LinkedList<BasketBallPlayer> list = 
    new LinkedList<BasketBallPlayer>();
    Iterator listIterator = list.iterator();
    list.offer(kyrie);
    list.offer(kat) ;
    list.offer(julius);
    list.offer(kawhi) ; 
    list.offer(devin);

    while(listIterator.hasNext())
        System.out.println(listIterator.next());

这是那个 sn-p 的整个班级。

import java.util.Iterator;
public class Queue {


    public static void main (String[] args) 
    {
        BasketBallPlayer kyrie = new BasketBallPlayer(
        "Kyrie Irving", 1, "Cavaliers");
        BasketBallPlayer kat = new BasketBallPlayer(
        "Karl Anthony Towns", 5, "Timberwolves");
        BasketBallPlayer julius = new BasketBallPlayer(
        "Julius Randle", "Power Forward", "Lakers");
        BasketBallPlayer kawhi = new BasketBallPlayer(
        "Kawhi Leanord", "Small Forward", "Spurs");
        BasketBallPlayer devin = new BasketBallPlayer(
        "Devin Booker", "Shooting Guard", "Suns");
        System.out.println(kyrie);

        LinkedList<BasketBallPlayer> list = 
        new LinkedList<BasketBallPlayer>();
        Iterator listIterator = list.iterator();
        list.offer(kyrie);
        list.offer(kat) ;
        list.offer(julius);
        list.offer(kawhi) ; 
        list.offer(devin);
        Iterator iterator = list.iterator();
        while(iterator.hasNext())
        {
            Object player = listIterator.next();
            System.out.println(player);
        }

        System.out.println("Which player is first?");
        System.out.println(list.peek());
        for(Object player: list)
        {
            System.out.println(list.getFirst());
            list.poll();
        }

    }
}

最后,BasketballPlayer 类。本课程包含作业的第 1 部分。这里我演示linkedList 方法。这部分有效。我不确定为什么第 1 部分中的迭代器没有抛出异常,而第 2 部分中的迭代器尽管使用几乎完全相同。谁能教我如何改正我的错误?

import java.util.Locale;
import java.util.LinkedList;
import java.util.ListIterator;

public class BasketBallPlayer
{
    private String name = "" , position = ""; String team = "";
    private int positionNumber = 0;
    public BasketBallPlayer()
    {
        name = "noName";
        position = "noPosition";
        team = "noTeam";
        positionNumber = 0;
    }
    public BasketBallPlayer(String playersName,  int thePositionNumber,
                             String theTeam)
    {


setName(playersName); setPositionNumber(thePositionNumber);
        setTeam(theTeam);
    }
    public BasketBallPlayer(String playersName, String playersPosition,
                            String theTeam)
    {
        setName(playersName);
        setPosition(playersPosition);
        setTeam(theTeam

);
    }
    public void setName(String theName)
    {
        this.name = theName;
    }
    public void setTeam(String theTeam)
    {
        this.team = theTeam;
    }
    public void setPosition(String playerPosition)
    {
    this.position = playerPosition;
    if(playerPosition.contains("oint"))
    this.positionNumber = 1;
    else if(playerPosition.contains("hoot"))
    this.positionNumber = 2;
    else if(playerPosition.contains("mall"))
    this.positionNumber = 3;
    else if(playerPosition.contains("ower"))
    this.positionNumber = 4;
    else if(playerPosition.contains("enter"))
    this.positionNumber = 5;
}
public void setPositionNumber(int thePositionNumber)
{
    this.positionNumber = thePositionNumber;
    switch(thePositionNumber){
    case 1: setPosition("Point Guard");
            break;
    case 2: setPosition("Shooting Guard");
            break;
    case 3: setPosition("Small Forward");
            break;
    case 4: setPosition("Power Forward");
            break;
    case 5: setPosition("Center");
            break;          
                            }
}
public String getName()
{
    return name;
}
public String getPosition()
{
    return position;
}
public int getPositionNumber()
{
    return positionNumber;
}
public String getTeam()
{
    return team;
}
public boolean equals(Object other)
{
    BasketBallPlayer objectToCompare;
    if(other != null && other.getClass() == getClass())
    objectToCompare = (BasketBallPlayer) other;
    else
    return false;
    return( 
    (getPositionNumber() == objectToCompare.getPositionNumber()) &&
    (getName() == objectToCompare.getName()) && 
    getTeam() == objectToCompare.getTeam()) ;
}
public String toString()
{
    if(getTeam().equals("Retired"))
    return  getName() + " is retired.";
    else
    return  getName()+ " plays for the " + getTeam();
}
public static void main (String[] args) 
{
    // five basketball player objects
    BasketBallPlayer kobe = new BasketBallPlayer("Kobe Bryant",
                               "Shooting Guard", "Retired");
    BasketBallPlayer ben = new BasketBallPlayer(
                              "Ben Wallace", 5, "Retired");
    BasketBallPlayer otto = new BasketBallPlayer("Otto Porter", 3,
                                                "Wizards");
    BasketBallPlayer andre = new BasketBallPlayer("Andre Drummond",
                                      "Center", "Pistons");
    BasketBallPlayer thomas = new BasketBallPlayer("Isaiah Thomas",
                                             1, "Celtics");
    BasketBallPlayer isaiah = new BasketBallPlayer("Isaiah Thomas",
                                  "Point Guard", "Pistons");  
    // initialize LinkedList and add three players                                       
    LinkedList list = new LinkedList();
    list.add(kobe); list.add(otto); 
    list.add(thomas); 
    // display the first one
    System.out.println("First player on the list");
    System.out.println(list.peek());
    System.out.println();
    System.out.println(kobe.getName() + 
    " is retired so let's remove him.");
    // remove object at index 0
    list.remove(0);
    System.out.println();
    // add andre to the top of the list
    list.addFirst(andre);
    // add ben to the end
    list.addLast(ben);
    System.out.println("New first player on the list");
    System.out.println(list.peek());
    // first create an Object[] which acts as a BasketBallPlayer[]
    System.out.println(
    "Any other retired players? Printing entire list:");
    // using toArray()
    Object[] other = list.toArray();
    for(Object player: other)
    // display each player in the array
    System.out.println(player);

    // demonstrate contains()
    if(list.contains(ben))
    list.remove(ben);
    System.out.println();
    System.out.println("Let's remove the retired player");
    System.out.println("Is " + ben.getName() + 
    " still on the list?");
    if(list.contains(ben))
    System.out.println(ben.getName() + " is still on the list");
    else
    {
        System.out.println(ben.getName() + " is not on the list");
        System.out.println("How many players after removing? " 
        + list.size());
    }
    System.out.println();
    System.out.println(otto.getName() + " is " + 
    // demonstrate indexOf()
    (list.indexOf(otto) + 1) +  " on the list");
    // create an iterator
    ListIterator listIterator = list.listIterator();
    System.out.println("Printing list using iterator:");
    // print out the list using the iterator
    while(listIterator.hasNext())
    {
        Object player = listIterator.next();
        System.out.println(player);
    }

}

【问题讨论】:

  • 如果如您所说,这是一个作业,您最好只从您的教授、课程助理或其他课程文件中获得帮助,以避免潜在的剽窃指控。跨度>
  • @JohnGallagher 不,在这里寻求帮助是可以的,只要明确说明这是一个作业,以便人们可以推荐正确的方向,可以找到解决方案而不给实际的代码,所以没有实际做 OP 的作业。见softwareengineering.meta.stackexchange.com/questions/6166/…
  • 很公平,我确实已经问过我的导师,但我不明白他的回答。他告诉我我需要使用第二个迭代器,因为“有时使用一个迭代器进行更新并尝试使用 hasNext() 来使用同一个迭代器是行不通的。”不过我不明白他的解释,在我的代码中,我在哪里使用迭代器来更新列表?
  • 听起来很合理 - 只是在涉及到此类事情时最好谨慎行事。

标签: java linked-list listiterator


【解决方案1】:

Java(以及 C#)中的标准集合的一个问题是您在迭代它们时可能无法修改它们。

如果没有采取额外的步骤,而且如果你运气不好,你可能不会遇到异常,只是程序行为不稳定。为了解决这个问题,java 实际上采取了额外的步骤:迭代器实际上会检查以确保您在迭代时不会修改集合,如果您这样做,则在您这样做后尽快抛出 ConcurrentModificationException

此功能称为“快速失败”迭代器,这是一个您可以查找的术语。

因此,从您实例化迭代器的那一刻起,直到您停止使用它,您都不能修改创建迭代器的集合。

你能在你的代码中找到你这样做的地方吗?

另外,关于你的教授说的话:要么你不明白你的教授说了什么,要么他们说的是错误的。提供在迭代时修改集合的方法的迭代器确实有效。例如,您可以使用iterator.remove() 删除当前元素。这是可行的,因为如果您通过迭代器修改集合,则迭代器负责,因此它可以采取任何必要的措施来防止数据损坏。什么不起作用,是通过直接在集合本身上调用任何 mutator 方法来修改集合,而迭代器在集合上处于活动状态,因为在这种情况下,迭代器不知道集合正在被修改的那一刻的事实集合被修改。迭代器稍后会抛出 ConcurrentModificationException,当它被调用执行任何操作时,它会发现集合同时已被修改。

【讨论】:

  • 还有几点值得注意:最好 a) 发布说明问题所需的尽可能少的代码,b) 不使用一些“第 1 部分”和“第 2 部分”令人困惑且难以跟踪,并且 c) 正确格式化了您的代码。下次发帖时请记住这一点。
  • 太好了,我会确保以后的帖子更简洁。我编辑了我的代码,以便在我提供对象后实例化迭代器。这解决了我的错误。感谢您的有益批评和有用的建议。
  • 没错。干杯!
猜你喜欢
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2015-08-23
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多