【问题标题】:how to insert into arraylist using a scanner?如何使用扫描仪插入数组列表?
【发布时间】:2011-10-20 19:54:38
【问题描述】:

我在试图弄清楚如何使用扫描仪将整数插入 ArrayList 时遇到了一些问题。我在 java 方面不是那么好(实际上什至不是很好),但我只是想弄清楚一些事情,任何帮助都会很棒。

package mySort;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;



public class MergeInsert {
private int limit = 100;
//private int size = 0;
private ArrayList<Integer> ArrayToSort;

public MergeInsert(int x) {
    ArrayToSort = new ArrayList<Integer>(x);
    }

public MergeInsert(Scanner integerScan){
    int j = 0;
    while(integerScan.hasNextInt()){
        this.insert(integerScan.hasNextInt());
        if (j % 10000 == 0){
            long time = System.nanoTime();
            System.out.println(j + "," + time);
        }
    }
}

public void insert(int x){
    for(int i=0; i<ArrayToSort.size(); i++){
        ArrayToSort(size++) = x;
    }
}


//  public MergeInsert(int v){
//      int val = v;
//  }

//    public void insertFile(){
//      try {
//          Scanner integerScan = new Scanner(new FileInputStream(""));
//          while(integerScan.hasNextInt()){
//              new MergeInsert(integerScan.nextInt());
//          }
//      }
//       catch (FileNotFoundException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
//    }


public void sort(){

}

public void mergeSort(ArrayList<Integer> in, int low,int high){
    int n = in.size();
    int mid = (high+low)/2;
    if (n<2){  //already sorted
        return;
    }
    if ((high - low) < limit){
        insertionSort(in);
    }
    ArrayList<Integer> in1 = new ArrayList<Integer>(); //helper
    ArrayList<Integer> in2 = new ArrayList<Integer>(); //helper
    int i=0;

    while (i < n/2){ //moves the first half to the helper
        in1.add(in.remove(0));
        i++;
    }
    while (!in.isEmpty()) //moves the second half to the helper
        in2.add(in.remove(0));
    mergeSort(in1, low, mid); //breaks it down some more like mergesort should
    mergeSort(in2, mid+1, high); //does it again
    merge(in1,in2,in); //trying to build it up again
    }

public void merge(ArrayList<Integer> in, ArrayList<Integer> in1, ArrayList<Integer> in2){
    while (!in1.isEmpty() || !in2.isEmpty()) //as long as both helpers still have elements
        if ((in1.get(0).compareTo(in2.get(0)) <= 0)) //comparison to rebuild
            in.add(in1.remove(0)); //building it back up
        else
            in.add(in2.remove(0)); //still building
    while(!in1.isEmpty()) //as long as the first helper isn't empty keep building
        in.add(in1.remove(0));
    while(!in2.isEmpty()) //as long as the second helper isn't empty keep building
        in.add(in2.remove(0));
}

public ArrayList<Integer> insertionSort(ArrayList<Integer> in){
    int index = 1;
    while (index<in.size()){
        insertSorted((int)(in.get(index)),in,index);
        index = index +1;
    }
    return in;
}

public ArrayList<Integer> insertSorted(Integer s, ArrayList<Integer> in, int index){
    int loc = index-1;
    while((loc>=0) || s.compareTo(in.get(loc)) <= 0){
        in.set(loc + 1, in.get(loc));
        loc = loc -1;
    }
    in.set(loc+1, s);
    return in;
    }


/**
 * @param args
 * @throws FileNotFoundException 
 */
public static void main(String[] args) throws FileNotFoundException {
    Scanner integerScan = new Scanner(new FileInputStream("src/myRandomNumbers.txt"));
    MergeInsert myObject = new MergeInsert(integerScan);
    myObject.sort();

}

}

它还没有完全完成,但所有这一切背后的想法是尝试和改进 MergeSort。基本上,一旦元素被分解到某个点,就切入 InsertionSort,因为它通常在非常小的(相对而言非常小的)数据集上会更好。

【问题讨论】:

  • 附带说明,您使用插入排序而不是合并排序的阈值非常高。在JDK中,它是7。你有它在100。:-O
  • 我暂时只是将它用作占位符。我打算在不同大小的列表上运行它,看看什么最适合不同大小的集合。
  • 分析和调整常量是最好的方法! :-)

标签: java insert arraylist mergesort insertion-sort


【解决方案1】:
public void insert(int x){
    ArrayToSort.add(x); // add it to the end
}

原因是……就算去了

ArrayToSort = new ArrayList<Integer>(100000);

它的大小仍然为 0。它的容量仅为 100000。

【讨论】:

  • 对不起,我忘了我在那里添加了尺寸参考。我只是想在发帖前看看这是否有帮助,显然没有。
  • 如果您不提供尺寸,它只会提供new ArrayList&lt;Integer&gt;(10)。如果需要,您可以覆盖默认值 10。
  • ArrayLists 在运行时不根据需要扩展吗?就像我正在读取 1000 个元素一样,它会扩展以容纳它们,如果我从一个具有 100 万个元素的不同文件中读取,它也应该在不修改代码的情况下处理它。还是我的理解有误?
  • 你的理解是正确的。但是,如果您知道您将至少获得一定数量的记录,为什么不为自己节省一些您不需要做的扩展呢?默认情况下,它是 10,因此它将扩展为 20、40、80、160、320、640、1280、2560、5120、10240、20480、40960、81920、163840、327680 和 655360。所以这就是 16 个扩展如果您知道您将获得 1000000 条记录,则无需这样做。如果您 - 不 - 预分配,它仍然可以正常工作,只是会慢一点。
  • 好的,知道了,谢谢。我不知道它所做的一切都是双倍的。如果我确实覆盖了它,肯定会帮助事情运行得更快一点。因为我一开始就想让它跑得更快,那么这样做才有意义。
【解决方案2】:

使用add 将对象插入到列表中。

此外,您的代码现在的结构方式是,当您尝试调用 add 时,您将得到一个 NullPointerException,因为您调用的构造函数从不初始化列表。

鉴于您的代码质量,我强烈建议您阅读Learning the Java Language

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多