【问题标题】:Problems with adding to an ArrayList while keeping a sorted order在保持排序顺序的同时添加到 ArrayList 的问题
【发布时间】:2016-02-23 22:05:57
【问题描述】:

所以我在做这个家庭作业时遇到了麻烦。本质上,我们必须创建扩展 java.util.ArrayList 的类 SortedArrayList,并覆盖 ArrayList 的默认添加方法,以便我们可以维护从最低到最高的整数排序列表。

这是我的教授给班级测试我们方法的代码:

package Asg3;

import java.util.ArrayList;

import myUtil.SortedArrayList;

public class Asg3 {



    public static void testInteger() {
        SortedArrayList<Integer> sorted= new SortedArrayList<Integer>();

        for (int i=0;i<20;i++) {
            sorted.add((int)(Math.random()*1000));
        }
        int bad=0;
        for (int i=0;i<20;i++) {
            try {
                sorted.add((int)(Math.random()*1000)%sorted.size(),(int)(Math.random()*1000));
            } catch (IllegalArgumentException e) {
                System.out.print(".");
                bad++;
            }
        }

        System.out.println("\nsize: "+sorted.size()+"  bad insertions: "+bad);
        System.out.println(sorted.toString());
    }



    }

    public static void main(String[] args) {

        testInteger();



    }

}

到目前为止,这是我要重写的 add 方法,以便它们维护一个排序的数组列表。

package myUtil;

public class SortedArrayList<T extends Comparable<T>>extends java.util.ArrayList<T>
{
    public SortedArrayList()
    {

    }

    public SortedArrayList(int capacity)
    {

    }

    @Override
    public boolean add(T item)
    {
        int index=this.size()-1;

    //checks to see if item is greater than or equivalent to the last element in the list   
    if(item.compareTo(this.get(index))>=0||this.get(index)==null)
    {
        //creates a new element at the end of the list and sets the value of item to it
        this.set(index+1,item);

    }
    return true;
    }



    @Override
    public void add(int i, T item)
    {
        //check to see if item is greater than the previous element, and less than the next element
        if(item.compareTo(this.get(i-1))<0 && item.compareTo(this.get(i+1))>0)
        this.set(i, item);  
    }

}

我收到一条错误消息:线程“主”ArrayIndexOutOfBoundsException 中的异常:-1

在 myUtil.SortedArrayList.add(SortedArrayList.java:21)

SortedArrayList 的第 21 行是 boolean add 方法中的 if 语句。

抱歉,如果这似乎是一个愚蠢的问题,我的教授在过去 2 天的办公时间内没有出现,所以我真的没有其他地方可以寻求帮助。一如既往地感谢大家提前回复。

【问题讨论】:

  • 那么,当你的列表最初是空的,然后你添加一个元素时会发生什么?
  • 更新您的代码并添加带有名称的完整类,以便我将完全相同的代码复制粘贴到我的 IDE 上运行并为您解决问题。
  • @Waqas Ahmed,好的,只需复制并粘贴完整的代码,感谢您提出的任何解决方案。
  • (旁注:这是一个非常令人讨厌的任务,因为它告诉你故意违反List合同。)
  • @LouisWasserman 你说的违反清单合同是什么意思?我只是好奇而已。

标签: java sorting arraylist


【解决方案1】:

问题是您从现有的 ArrayList 中检索“上一个”和“下一个”元素进行比较,而不检查这些元素是否确实存在。要考虑的特殊情况是:列表为空;在第一个元素之前插入,或者在最后一个元素之后添加。

一旦您尝试的插入通过了排序检查,您就可以使用super.add(value)super.add(position, value) 进行实际操作。据我所知,在任何时候都不需要使用 set() 方法。

(由于这是家庭作业,我很犹豫是否提供(伪)代码,至少没有给您机会自己考虑特殊情况。)

【讨论】:

  • ahhhh 好的,谢谢,所以为了澄清,我必须检查一下我正在检查的索引是否首先存在正确?是的,别再给我那个伪代码了。
  • 没错。如果您通过解释新的 add(value) 和 add(position, value) 的确切预期来扩展您的问题,这将有所帮助 - 我觉得新的 add(value) 应该进行一些主动排序好吧(向@louis-wasserman 提个醒)
  • 是的,我设法让程序运行,只需使用我和@SalvatoreElia 都认为我的教授希望我首先使用的 try/catch 块。我仍然会在晚上晚些时候实施一些排序检查,因为我肯定会看到我的代码在当前状态下是如何存在一些问题的。无论如何,感谢您抽出时间来帮助我。是时候好好休息一下了。
【解决方案2】:

我相信问题出在列表最初为空时,因此 index = -1。在这种情况下,一种可能的解决方案是在 if 语句中包围整个事物:

if (this.size()!=0)
{
    ...    //Your code goes here
}
else this.set(0, item);

编辑:

事实证明,问题不止于此。这是我的最终代码;希望您可以通读并了解我所做的更改。 (除其他外,我还添加了针对特殊情况的测试。)

这应该显示如下:

size: 21  bad insertions: 19    //This should always add up to 40, because an add() method is called 40 times in total by testInteger()
[64, 65, 155, 281, 284, 340, 363, 444, 529, 596, 600, 628, 665, 745, 782, 856, 872, 885, 891, 899, 996]
package myUtil;

@SuppressWarnings("serial")
public class SortedArrayList<T extends Comparable<T>>extends java.util.ArrayList<T>
{
    public SortedArrayList() {}

    public SortedArrayList(int capacity) {}

    @Override
    public boolean add(T item)
    {
        int index=this.size();
        //Adds item to every position until it finds one that works
        for (int i=0;i<=index;i++)
        {
            try
            {
                add(i,item);
                break;
        }
            catch (IllegalArgumentException e) {}
        }   
        return true;
    }



    @Override
    public void add(int i, T item)
    {
        //Tests for special cases with if statements.
        //If item is inserted into the wrong place, throws IllegalArgumentException()
        if (i<=size())
        {
            if (size()==0) super.add(item);
            else if (i==size())
            {
                if(item.compareTo(this.get(i-1))>=0)
                    super.add(i, item);
                else throw new IllegalArgumentException();
            }
            else if (i==0)
            {
                if(item.compareTo(this.get(i))<=0)
                    super.add(i, item);
                else throw new IllegalArgumentException();
            }
            else
            {
                if(item.compareTo(this.get(i-1))>=0&&item.compareTo(this.get(i))<=0)
                    super.add(i, item);
                else throw new IllegalArgumentException();
            }
        }
        else
        {
            throw new IllegalArgumentException();
        }
    }
}

【讨论】:

  • 返回真;必须超出 if/else 语句。
  • 我刚刚尝试实施您的解决方案,但得到了一些不同的错误代码。我认为这也是问题所在......无论如何现在错误是:线程“主”java.lang.IndexOutOfBoundsException中的异常:索引:0,大小:0在java.util.ArrayList.rangeCheck(未知来源)在java .util.ArrayList.set(Unknown Source) at myUtil.SortedArrayList.add(SortedArrayList.java:32) at Asg3.Asg3.testInteger(Asg3.java:25) at Asg3.Asg3.main(Asg3.java:57)
  • 非常感谢您的帮助
  • 我尝试使用 super.add(item) 而不是 set,它对我有用。现在的问题是 add(int i, T item) 方法不起作用
  • 我修好了 - 我认为你的教授希望你做的是抛出一个 IllegalArgumentException (因为他在 try/catch (IllegalArgumentException e) 中包围了该方法
猜你喜欢
  • 2020-01-20
  • 2011-04-08
  • 2020-04-21
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多