You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java LinkedList迭代器卡顿:无法遍历列表及前进后退方法失效

问题:LinkedList迭代器遍历异常,前进/后退功能失效

我开发的Java程序采用LinkedList存储PlacesToVisit对象,按距离升序排列后,无法遍历完整的城镇列表,迭代器卡在索引1的位置。尝试调用previous()和next()方法移动游标,但前进(moveForward)和后退(moveBack)方法均无法正常执行,其中后退方法完全没有响应。


原始代码

Main类

import java.util.LinkedList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        var places = new LinkedList<PlacesToVisit>();

        addPlaces(places, new PlacesToVisit("Adelaide", 1374));
        addPlaces(places, new PlacesToVisit("Brisbane", 917));
        addPlaces(places, new PlacesToVisit("Perth", 3923));
        addPlaces(places, new PlacesToVisit("Alice Springs", 2771));
        addPlaces(places, new PlacesToVisit("Darwin", 3723));
        addPlaces(places, new PlacesToVisit("Melbourne", 877));

        addPlaces(places, new PlacesToVisit("Sydney", 0));

        System.out.println("First place to go is " + places.getFirst());

        boolean flag = true;

        while (flag) {
            Scanner sc = new Scanner(System.in);
            chooseOptions();
            switch (sc.next().toUpperCase().substring(0, 1)) {
                case "M" -> printMenu(places);
                case "F" -> moveForward(places);
                case "B" -> moveBack(places);
                case "L" -> System.out.println(places);
                case "Q" -> flag = false;
            }
        }
    }

    private static void chooseOptions() {
        String options = ("""
                Available actions (Select word or letter)
                (F)orward
                (B)acward
                (M)enu
                (L)ist places
                (Q)uit""");
        System.out.println(options + " ");
    }

    private static void printMenu(LinkedList<PlacesToVisit> list) {
        System.out.println(list);
    }

    private static void moveForward(LinkedList<PlacesToVisit> list) {
        var iterator = list.listIterator();
        if (iterator.hasNext()) {
            iterator.next();
            if (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }
    }

    private static void moveBack(LinkedList<PlacesToVisit> list) {
        var iterator = list.listIterator();
        if (iterator.hasPrevious()) {
            iterator.previous();
            if (iterator.hasPrevious()) {
                System.out.println(iterator.previous());
            }
        }
    }

    private static void addPlaces(LinkedList<PlacesToVisit> list, PlacesToVisit place) {
        if (list.contains(place)) {
            System.out.println("Found duplicate " + place);
            return;
        }
        for (PlacesToVisit p : list) {
            if (p.getName().equalsIgnoreCase(place.getName())) {
                System.out.println("Duplicate found" + place);
                return;
            }
        }
        int matchIndex = 0;
        for (var listPlace : list) {
            if (place.getDistance() < listPlace.getDistance()) {
                list.add(matchIndex, place);
                return;
            }
            matchIndex++;
        }
        list.add(place);
    }
}

PlacesToVisit类

public class PlacesToVisit {
    private String name;
    private int distance;
    public PlacesToVisit(String name, int distance) {
        this.name = name;
        this.distance = distance;
    }
    public String getName() {
        return name;
    }
    public int getDistance() {
        return distance;
    }
    @Override
    public String toString() {
        return String.format("%s distance = %d", name, distance);
    }
}

问题根源与修复方案

核心问题

  1. 迭代器状态丢失:每次调用moveForward/moveBack时,都会创建新的ListIterator,新迭代器初始位置永远在列表开头,导致前进每次只能走到第二个元素,后退时因初始位置无前置元素完全不执行。
  2. 移动逻辑错误:moveForward连续调用两次next(),直接跳过元素;moveBack的前置判断逻辑完全无效。
  3. 重复元素判断失效:PlacesToVisit未重写equals方法,list.contains(place)无法正确识别重复项。

修复后完整代码

Main类
import java.util.LinkedList;
import java.util.Scanner;
import java.util.ListIterator;

public class Main {
    // 迭代器作为成员变量,保持游标状态
    private static ListIterator<PlacesToVisit> iterator;

    public static void main(String[] args) {
        var places = new LinkedList<PlacesToVisit>();

        addPlaces(places, new PlacesToVisit("Adelaide", 1374));
        addPlaces(places, new PlacesToVisit("Brisbane", 917));
        addPlaces(places, new PlacesToVisit("Perth", 3923));
        addPlaces(places, new PlacesToVisit("Alice Springs", 2771));
        addPlaces(places, new PlacesToVisit("Darwin", 3723));
        addPlaces(places, new PlacesToVisit("Melbourne", 877));
        addPlaces(places, new PlacesToVisit("Sydney", 0));

        System.out.println("First place to go is " + places.getFirst());
        // 初始化迭代器并定位到第一个元素
        iterator = places.listIterator();
        if (iterator.hasNext()) {
            iterator.next();
        }

        boolean flag = true;
        Scanner sc = new Scanner(System.in);
        while (flag) {
            chooseOptions();
            String input = sc.next().toUpperCase().substring(0, 1);
            switch (input) {
                case "M" -> printMenu(places);
                case "F" -> moveForward();
                case "B" -> moveBack();
                case "L" -> System.out.println(places);
                case "Q" -> flag = false;
                default -> System.out.println("无效输入,请重新选择");
            }
        }
        sc.close();
    }

    private static void chooseOptions() {
        String options = """
                Available actions (Select word or letter)
                (F)orward
                (B)ackward
                (M)enu
                (L)ist places
                (Q)uit""";
        System.out.println(options);
    }

    private static void printMenu(LinkedList<PlacesToVisit> list) {
        System.out.println(list);
    }

    private static void moveForward() {
        if (iterator.hasNext()) {
            System.out.println("当前位置:" + iterator.next());
        } else {
            System.out.println("已到列表末尾,无法前进");
        }
    }

    private static void moveBack() {
        if (iterator.hasPrevious()) {
            System.out.println("当前位置:" + iterator.previous());
        } else {
            System.out.println("已到列表开头,无法后退");
        }
    }

    private static void addPlaces(LinkedList<PlacesToVisit> list, PlacesToVisit place) {
        if (list.contains(place)) {
            System.out.println("发现重复项:" + place);
            return;
        }
        int matchIndex = 0;
        for (var listPlace : list) {
            if (place.getDistance() < listPlace.getDistance()) {
                list.add(matchIndex, place);
                return;
            }
            matchIndex++;
        }
        list.add(place);
    }
}
PlacesToVisit类
public class PlacesToVisit {
    private String name;
    private int distance;

    public PlacesToVisit(String name, int distance) {
        this.name = name;
        this.distance = distance;
    }

    public String getName() {
        return name;
    }

    public int getDistance() {
        return distance;
    }

    @Override
    public String toString() {
        return String.format("%s distance = %d", name, distance);
    }

    // 重写equals,基于名称(忽略大小写)和距离判断重复
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PlacesToVisit that = (PlacesToVisit) o;
        return distance == that.distance && name.equalsIgnoreCase(that.name);
    }

    // 重写hashCode,与equals逻辑一致
    @Override
    public int hashCode() {
        return name.toLowerCase().hashCode() + distance;
    }
}

内容的提问来源于stack exchange,提问作者Felix Mbugua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:02:39