Java中ArrayList/Collections方法的代码速度慢

Java中ArrayList/Collections方法的代码速度慢,java,collections,arraylist,sublist,Java,Collections,Arraylist,Sublist,我正在尝试组合一个2D KD树实现。在这一点上,它可以工作,但运行时间会爆炸,超过10万个点。100k需要15秒,1e6需要30分钟。起初,我认为瓶颈是排序以找到中值,但似乎是使用subList和addAll方法。任何改进的建议都会很好 谢谢 import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.R

我正在尝试组合一个2D KD树实现。在这一点上,它可以工作,但运行时间会爆炸,超过10万个点。100k需要15秒,1e6需要30分钟。起初,我认为瓶颈是排序以找到中值,但似乎是使用subList和addAll方法。任何改进的建议都会很好

谢谢

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class KDtree {

    //****************************************************
    //setting up a data set for input
    //****************************************************
    public kdLite() {


        long startTime = System.currentTimeMillis() / 1000;

        //select random values to generate data set
        double[][] dataSet = new double[2][100000];
        for (int i = 0; i < 100000; i++) {
            dataSet[0][i] = (Math.random() * (99));
            dataSet[1][i] = (Math.random() * (99));
            //System.out.print(dataSet[0][i] + "\t" + dataSet[1][i] + "\n");
        }
        //System.out.print("\n");
        //setup a point class for simple data manipulation and add data to it
        ArrayList<Point> preSorted = new ArrayList<Point>();
        for (int i = 0; i < dataSet[0].length; i++) {
            Point point = new Point(i, dataSet[0][i], dataSet[1][i], 0);
            preSorted.add(point);
        }

        //split and sort the list
        ArrayList<Point> outList = splitList(preSorted);

        // add the list to the binary tree structure
        BinaryST buildKD = new BinaryST();
        for (int i = 0; i < outList.size(); i++) {
            buildKD.insertNode(outList.get(i));
        }
        long endTime = System.currentTimeMillis() / 1000;
        System.out.println((int) (endTime - startTime) / 60 + " Minutes and " + (endTime - startTime) + " Seconds");
        // buildKD.printTree();
        //****************************************************
    }

    //****************************************************
    //the brunt of the code.  this method takes a list of Point objects
    //solves for the axis to split on and cuts the list into 2^i segments
    //****************************************************

    public ArrayList<Point> splitList(ArrayList<Point> arrToSplit) {


        ArrayList<ArrayList<Point>> splitList = new ArrayList<ArrayList<Point>>();
        ArrayList<Point> Meds = new ArrayList<Point>();
        int axis = 0;
        int toSplit = 0;
        double maxXdif = 0;
        double maxYdif = 0;

        //populate first bucket
        splitList.add(new ArrayList<Point>());
        for (int i = 0; i < arrToSplit.size(); i++) {
            splitList.get(0).add(arrToSplit.get(i));
        }


        for (int slice = 0; slice < arrToSplit.size(); slice++) {


            //get first bucket that has more than one value then use it first
            for (int i = 0; i < splitList.size(); i++) {
                if (splitList.get(i).size() >= 1) {
                    toSplit = i;
                    if (splitList.get(i).size() > 1) {
                        break;
                    }
                }
            }

            if (splitList.get(toSplit).size() > 1) {
                sortByX(splitList.get(toSplit));
                maxXdif = Math.abs(splitList.get(toSplit).get(0).x - splitList.get(toSplit).get(splitList.get(toSplit).size() - 1).x);
                sortByY(splitList.get(toSplit));
                maxYdif = Math.abs(splitList.get(toSplit).get(0).y - splitList.get(toSplit).get(splitList.get(toSplit).size() - 1).y);

                //arrange by splitting axis according to largest distance to find splitting axis
                if (maxXdif > maxYdif) {
                    axis = 0;
                    sortByX(splitList.get(toSplit));
                } else {
                    axis = 1;
                    sortByY(splitList.get(toSplit));
                }

                //solve for median point .. arbitrate if no point lies on axis (uneven split)
                int Med = (int) Math.floor(splitList.get(toSplit).size() / 2);

                //take median point, assign splitting axis
                splitList.get(toSplit).get(Med).axis = axis;
                Meds.add(splitList.get(toSplit).get(Med));
                splitList.get(toSplit).remove(Med);

                ---- >>>>>> PROBLEM CODE                            
                // relocate all points except median to new list, delete the median value
                List<Point> head = splitList.get(toSplit).subList(Med, splitList.get(toSplit).size());
                splitList.add(new ArrayList<Point>());
                splitList.get(splitList.size() - 1).addAll(head);
                head.clear();
                splitList.get(toSplit).subList(Med - 1, splitList.get(toSplit).size() - 1).clear();
            } else {
                //these are the leftover points so ordering is arbitrary
                //randomize axis to ensure balance
                Random random = new Random();
                int randomAxis = random.nextInt(2 - 0);
                Meds.add(splitList.get(toSplit).get(0));
                splitList.get(toSplit).get(0).axis = randomAxis;
                splitList.remove(toSplit);
            }


        }
        return Meds;
    }

    //****************************************************


    //****************************************************
    //sorting methods for sorting a list by x or y
    //must use comparator to sort by custom object attributes
    //****************************************************
    private ArrayList<Point> sortByX(ArrayList<Point> xList) {
        Collections.sort(xList, new Comparator<Point>() {
            public int compare(Point p1, Point p2) {
                return Double.compare(p1.getX(), p2.getX());
            }
        });
        return xList;
    }

    private ArrayList<Point> sortByY(ArrayList<Point> yList) {
        Collections.sort(yList, new Comparator<Point>() {
            public int compare(Point p1, Point p2) {
                return Double.compare(p1.getY(), p2.getY());
            }
        });
        return yList;
    }
    //****************************************************

}
import java.util.ArrayList;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.List;
导入java.util.Random;
公共类KDtree{
//****************************************************
//为输入设置数据集
//****************************************************
公共kdLite(){
long startTime=System.currentTimeMillis()/1000;
//选择随机值以生成数据集
double[]数据集=新的double[2][100000];
对于(int i=0;i<100000;i++){
数据集[0][i]=(Math.random()*(99));
数据集[1][i]=(Math.random()*(99));
//System.out.print(数据集[0][i]+“\t”+数据集[1][i]+“\n”);
}
//系统输出打印(“\n”);
//为简单的数据操作设置点类并向其添加数据
ArrayList预排序=新建ArrayList();
对于(int i=0;i=1){
toSplit=i;
if(splitList.get(i).size()>1){
打破
}
}
}
if(splitList.get(toSplit.size()>1){
sortByX(splitList.get(toSplit));
maxXdif=Math.abs(splitList.get(toSplit).get(0).x-splitList.get(toSplit).get(splitList.get(toSplit).size()-1.x);
sortByY(splitList.get(toSplit));
maxYdif=Math.abs(splitList.get(toSplit).get(0).y-splitList.get(toSplit).get(splitList.get(toSplit).size()-1.y);
//按最大距离分轴排列,找到分轴
if(maxXdif>maxYdif){
轴=0;
sortByX(splitList.get(toSplit));
}否则{
轴=1;
sortByY(splitList.get(toSplit));
}
//求解中间点。如果轴上没有点(不均匀分割),则进行仲裁
int Med=(int)Math.floor(splitList.get(toSplit.size()/2);
//取中点,指定分割轴
splitList.get(toSplit).get(Med).axis=axis;
Meds.add(splitList.get(toSplit.get(Med));
splitList.get(toSplit).remove(Med);
---->>>>>>>>问题代码
//将除中间值以外的所有点重新定位到新列表,删除中间值
List head=splitList.get(toSplit).subList(Med,splitList.get(toSplit.size());
添加(新的ArrayList());
splitList.get(splitList.size()-1).addAll(head);
头。清除();
splitList.get(toSplit).subList(Med-1,splitList.get(toSplit).size()-1).clear();
}否则{
//这些是剩余点,因此排序是任意的
//随机化轴以确保平衡
随机=新随机();
int randomAxis=random.nextInt(2-0);
药物添加(splitList.get(toSplit.get(0));
splitList.get(toSplit).get(0).axis=randomAxis;
splitList.remove(toSplit);
}
}
退药;
}
//****************************************************
//****************************************************
//按x或y对列表进行排序的排序方法
//必须使用comparator按自定义对象属性排序
//****************************************************
专用ArrayList sortByX(ArrayList XLList){
Collections.sort(xList,newcomparator(){
公共整数比较(点p1,点p2){
返回Double.compare(p1.getX(),p2.getX());
}
});
返回xList;
}
私有ArrayList sortByY(ArrayList-yList){
Collections.sort(yList,newcomparator(){
ArrayList<Point>(int capacity);