Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 插入到已排序的列表中_Java_Arraylist_Alphabetical_Sorted - Fatal编程技术网

Java 插入到已排序的列表中

Java 插入到已排序的列表中,java,arraylist,alphabetical,sorted,Java,Arraylist,Alphabetical,Sorted,对于Java,我有一个名为TestClass的类,它有一个名为Name的成员,这是一个字符串。我还有一个这种类型的ArrayList,它已经按名称的字母顺序排序了。我想做的是找到放置TestClass新实例的最佳索引。到目前为止,我能想到的最佳方法是: public static int findBestIndex(char entry, ArrayList<TestClass> list){ int desiredIndex = -1; int oldPivot =

对于Java,我有一个名为TestClass的类,它有一个名为Name的成员,这是一个字符串。我还有一个这种类型的ArrayList,它已经按名称的字母顺序排序了。我想做的是找到放置TestClass新实例的最佳索引。到目前为止,我能想到的最佳方法是:

public static int findBestIndex(char entry, ArrayList<TestClass> list){
    int desiredIndex = -1;
    int oldPivot = list.size();
    int pivot = list.size()/2;
    do
    {
        char test = list.get(pivot).Name.charAt(0);
        if (test == entry)
        {
            desiredIndex = pivot;
        }
        else if (Math.abs(oldPivot - pivot) <= 1)
        {
            if (test < entry)
            {
                desiredIndex = pivot + 1;
            }
            else
            {
                desiredIndex = pivot - 1;
            }
        }
        else if (test < entry)
        {
            int tempPiv = pivot;
            pivot = oldPivot - (oldPivot - pivot)/2;
            oldPivot = tempPiv;
        }
        else
        {
            int tempPiv = pivot;
            pivot = pivot - (oldPivot - pivot)/2;
            oldPivot = tempPiv;
        }

    } while (desiredIndex < 0);

    return desiredIndex;
}
public static int findBestIndex(char条目,ArrayList列表){
int desiredIndex=-1;
int oldpoint=list.size();
int pivot=list.size()/2;
做
{
char test=list.get(pivot.Name.charAt(0);
如果(测试==条目)
{
desiredIndex=枢轴;
}

else if(Math.abs(oldprovot-pivot)您应该使用像PriorityQueue这样已经有秩序感的东西。插入到有秩序感的集合中会自动以最短的时间(通常为log(n)或更少)将元素放置在正确的位置

如果您希望在没有此选项的情况下执行任意插入,那么我建议使用不必重新引用或完全复制的LinkedList来插入单个项目,如您当前拥有的ArrayList。而为LinkedList找到正确的插入位置将需要高达O(n)实际上,它仍然比使用日志(n)搜索ArrayList中的正确位置要快,但随后需要对其进行复制或排序

此外,在链表中查找插入位置的代码要简单得多

if (next != null && next.compareTo(insertElement) > 0){
    // You have the right location
}

可以使用其他数据结构代替列表,如树、优先级队列等。

如前所述,没有理由自己实现,简单的代码示例:



    class FooBar implements Comparable<FooBar> {

        String name;

        @Override
        public int compareTo(FooBar other) {
           return name.compareTo(other.name);
        }
    }

    TreeSet<FooBar> foobarSet = new TreeSet<>();
    FooBar f1;
    foobarSet.add(new FooBar("2"));
    foobarSet.add(f1 = new FooBar("1"));

    int index = foobarSet.headSet(f1).size();


类FooBar实现了可比较的{
字符串名;
@凌驾
公共int比较(FooBar其他){
返回name.compareTo(其他.name);
}
}
TreeSet foobarSet=新树集();
福巴f1;
添加(新的FooBar(“2”));
添加(f1=新的FooBar(“1”));
int index=foobarSet.headSet(f1).size();

(基于)

我认为问题在于这段代码:

else if (test < entry)
{
    int tempPiv = pivot;
    pivot = oldPivot - (oldPivot - pivot)/2;
    oldPivot = tempPiv;
}
else
{
    int tempPiv = pivot;
    pivot = pivot - (oldPivot - pivot)/2;
    oldPivot = tempPiv;
}
else if(测试
无论是testentry,您都在执行相同的操作。当您搜索的项目位于数组的开头时,这将导致线性搜索

我更喜欢使用(低和高)像

high=list.size();
低=0;
做{
枢轴=(高+低)/2;
如果(测试<输入){
低=枢轴;
}否则如果(测试>输入){
高=枢轴
}否则{
....
}
}而。。。;

制作自己的列表实现,在add方法中有以下几行:

wrappedList.add(object);
Collections.sort(wrappedList);

为此,使用SortedSet(例如TreeSet)可能不是一个好主意,因为集合不允许重复的元素。如果有重复的元素(例如同名的TestClass实例),则应使用列表。将元素插入到已排序的列表中非常简单:

void insert(List<TestClass> list, TestClass element) {
    int index = Collections.binarySearch(list, element, Comparator.comparing(TestClass::getName));
    if (index < 0) {
        index = -index - 1;
    }
    list.add(index, element);
}
void插入(列表,TestClass元素){
int index=Collections.binarySearch(列表、元素、比较器.comparing(TestClass::getName));
如果(指数<0){
指数=-指数-1;
}
添加(索引、元素);
}

此代码需要Java 8或更高版本,但也可以重写以在较旧的Java版本中工作。

为什么不插入所有元素,然后使用
Collections.sort()
?也许我没有看到这一点,但如果您确定该值在所选(测试)之后point,你能检查一下数组的后半部分吗?@fge,每次插入后重新尝试可能是最慢的方式,尽管速度不是我最关心的,因为不太可能有很多对象被快速移入移出。@mbrach,这是我试图做的,但我这样做的尝试可能是完全错误的,一个nd是我遇到问题的地方。@user2423158这取决于访问此排序列表的频率。如果不是那么频繁,您可以在需要时重新构建该列表。我还认为我们应该使用可排序列表。在回答中,我们使用Comparable。另一个选项是使用Comparator。我不确定PriorityQueue或LinkedList是否最适合我所说的我必须说,你不想使用LinkedList b/c的原因是把ArrayList翻译成c会更容易些,这是不正确的。两种方法都同样容易翻译(我甚至会说LinkedList更容易些)。但最重要的是,如果不移动ArrayList后面的所有元素,就无法将元素插入ArrayList的中间。这涉及到复制ArrayList的该部分,速度明显慢于LinkedList插入。基本上,如果您是为了提高效率,则使用的数据结构是错误的。我选择ArrayList是因为熟悉,并且易于访问任何给定元素。然而,另一个数据结构可能是个好主意,尽管我必须先做一些研究。为什么这不是公认的答案(如果@user2423158想要接受一个…?它有在O(log(n))中工作的键)关于数组。谢谢!@Matthieu谢谢你的支持投票,我怀疑用户希望他的问题得到回答,之后就没有兴趣了。这与树无关。Set不允许重复元素谢谢你指出这一点。我相应地更改了措辞。
void insert(List<TestClass> list, TestClass element) {
    int index = Collections.binarySearch(list, element, Comparator.comparing(TestClass::getName));
    if (index < 0) {
        index = -index - 1;
    }
    list.add(index, element);
}