【问题标题】:Why is my if-else-if statement not working in my arraylist? [duplicate]为什么我的 if-else-if 语句在我的数组列表中不起作用? [复制]
【发布时间】:2016-12-21 04:30:33
【问题描述】:

以下是我的代码。当我编译它时,程序可以工作。但它给了我错误的输出。当我使用循环打印出 arrayList 的元素时,它会打印出错误的输出。例如,“Greenville, SC”被打印出来,而它应该被排除在第一个 if 语句中。 arraylist 具有重复的值。

for (int i = 0; i < NoUber_cities.size(); i++)

{

    if ((NoUber_cities.get(i)).equalsIgnoreCase("Greenville, SC"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Pensacola, FL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Peoria, IL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Asheville, NC"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Hattiesburg, MS"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Portland, ME"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Portland, ME"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Huntsville, AL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Reading, PA"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Birmingham, AL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Bloomington, IN"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Bowling Green, KY"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Lafayette, LA"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Central Atlantic Coast, FL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Lancaster, PA"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Charleston, SC"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Charleston, WV"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("San Juan, PR"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("London, Ont"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Springfield, IL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Columbia, MO"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Columbia, SC"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Montgomery, AL"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Morgantown, WV"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Fayetteville, AR"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Wilmington, NC"))
    {
        NoUber_cities.remove(i);
    }

    else if ((NoUber_cities.get(i)).equalsIgnoreCase("Outer Banks, NC"))
    {
        NoUber_cities.remove(i);
    }
}

【问题讨论】:

  • 输入是什么?即:NoUber_cities。此外,使用 for-each 语句或直接使用 List 的 removeAll 方法将使您的代码更具可读性。
  • “程序可以运行,但输出错误”...您可能需要查找“工作”的定义。
  • 没有输入,我只是尝试从数组列表中删除这些字符串,但没有成功。

标签: java if-statement for-loop arraylist string-comparison


【解决方案1】:

您的代码的问题是,一旦您从列表中删除一个项目,所有剩余的项目都会更改索引,但您的代码没有考虑到这一点。

例如,假设您的列表包含:

0 - AAA
1 - BBB
2 - CCC
3 - DDD

如果 i = 1 并且您决定删除 BBB,则列表现在如下所示:

0 - AAA
1 - CCC
2 - DDD

但是您的循环随后会增加 i 并继续检查 - 现在 i = 2 并且您错过了移入索引 1 的 CCC 项目。

有很多方法可以解决这个问题。一种方法是在删除项目时减少索引:

for (int i = 0; i < NoUber_cities.size(); i++)
{

    if ((NoUber_cities.get(i)).equalsIgnoreCase("Greenville, SC")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Pensacola, FL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Peoria, IL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Asheville, NC")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Hattiesburg, MS")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Portland, ME")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Portland, ME")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Huntsville, AL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Reading, PA")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Birmingham, AL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Bloomington, IN")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Bowling Green, KY")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Lafayette, LA")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Central Atlantic Coast, FL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Lancaster, PA")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Charleston, SC")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Charleston, WV")
        || (NoUber_cities.get(i)).equalsIgnoreCase("San Juan, PR")
        || (NoUber_cities.get(i)).equalsIgnoreCase("London, Ont")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Springfield, IL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Columbia, MO")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Columbia, SC")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Montgomery, AL")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Morgantown, WV")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Fayetteville, AR")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Wilmington, NC")
        || (NoUber_cities.get(i)).equalsIgnoreCase("Outer Banks, NC"))
    {
        NoUber_cities.remove(i);
        i--;
    }
}

另一种方法是在 Java 8 中使用流:

List<String> citiesToRemove = Arrays.asList(
        "greenville, sc",
        "pensacola, fl",
        "peoria, il",
        "asheville, nc",
        "hattiesburg, ms",
        "portland, me",
        "huntsville, al",
        "reading, pa",
        "birmingham, al",
        "bloomington, in",
        "bowling green, ky",
        "lafayette, la",
        "central atlantic coast, fl",
        "lancaster, pa",
        "charleston, sc",
        "charleston, wv",
        "san juan, pr",
        "london, ont",
        "springfield, il",
        "columbia, mo",
        "columbia, sc",
        "montgomery, al",
        "morgantown, wv",
        "fayetteville, ar",
        "wilmington, nc",
        "outer banks,nc");

List<String> filteredListOfCities = NoUber_cities.stream()
        .filter(item -> !citiesToRemove.contains(item.toLowerCase()))
        .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    向后工作:

    for (int i = NoUber_cities.size() - 1; i >= 0; i--)
    

    这样前面项目的索引不会移动,您可以毫无问题地删除索引i处的项目。最好从索引集合中向后删除项目。

    说明

    假设你有一个清单

    0: AAA
    1: BBB
    2: CCC
    3: DDD
    4: EEE
    5: FFF
    6: GGG
    

    如果您删除索引 3 处的 DDD,则列表将如下所示:

    0: AAA
    1: BBB
    2: CCC
    3: EEE
    4: FFF
    5: GGG
    

    如您所见,具有更高索引的项目将向下移动并获得新索引。 较低索引处的项目将保持不变。

    现在,如果您迭代 forward,并且当前索引为 3,那么下一个索引为 4,在删除之后,它指向 FFF。这意味着您从未检查过EEE

    OTOH,如果你迭代向后,下一个索引是 2,它仍然包含CCC。 (请注意,您已经检查了更高的索引,因此这些索引是否获得新索引并不重要)。数组的大小发生了变化,但低于删除点的索引项的索引没有变化。

    【讨论】:

    • 为什么不会引起任何问题?即使我从列表中向后删除元素,arraylist 的大小在删除元素时也会不断变化。
    • 因为正如我所说,preceding 项(即较低索引的项)不会向下移动,因此该索引在下一次迭代中仍然有效。试试吧。这是一个非常简单且众所周知的原则。
    • @RonLi:如果你移动向前,并且^是当前索引,那么A B C ^D E F G将变为A B C ^E F G,在下一次迭代中, index 将指向F,这意味着您跳过了E。但是当您向后 时,索引将指向C,就像您没有删除D 一样,这很好。数组列表的大小只在循环开始时被查询一次。尝试一下,看看它是否有效。
    【解决方案3】:

    删除原始元素后,您正在从列表中跳过元素;因为元素在移除原始元素后向上移动。

    您可以考虑使用iterator 以及其他给定答案的替代方案:

    List<String> citiesToRemove = new ArrayList<String>();
        citiesToRemove.add("greenville, sc");
        citiesToRemove.add("pensacola, fl");
        citiesToRemove.add("peoria, il");
        citiesToRemove.add("greenville, sc");
        citiesToRemove.add("asheville, nc");
        citiesToRemove.add("greenville, sc"); --Duplicate element
        System.out.println(citiesToRemove);
        Iterator<String> itr = citiesToRemove.iterator();
        while (itr.hasNext())
            if (itr.next().equalsIgnoreCase("greenville, sc")||
                    itr.next().equalsIgnoreCase("peoria, il"))
                itr.remove();
    
        System.out.println(citiesToRemove);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-05
      • 1970-01-01
      • 2018-07-30
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多