简体   繁体   English

在Java中使用的正确数据结构是什么?

[英]What is the correct data structure to use in java?

I want to save integers in a data structure, but without knowing the number of integers i might get. 我想将整数保存在数据结构中,但是不知道我可能会得到的整数数量。 I want the database to be of FIFO kind. 我希望数据库为FIFO类型。 What is best for this purpose? 为此目的最好是什么?

Apart from using a database, if you just have a number of intergers you could write them to a plain file. 除了使用数据库之外,如果您只有大量的整数,则可以将它们写入纯文件。 Plain files retain order, however removing entries can be expensive. 普通文件保留顺序,但是删除条目可能会很昂贵。

You can write/rewrite 1 million integers in about 0.1 seconds using a plain file. 您可以使用纯文件在约0.1秒内写入/重写100万个整数。

An efficient collecton for int primitives is TIntArrayList. TIntArrayList是int原语的有效收集器。 Its like @JPelletier's suggestion but wraps a int[]. 就像@JPelletier的建议一样,但包装了一个int []。 A million int values should take about 4 MB of memory or disk. 一百万个int值应占用大约4 MB的内存或磁盘。

EDIT: This shows that for 1 million numbers ArrayList is a bad choice. 编辑:这表明对于一百万个数字,ArrayList是一个错误的选择。 Mainly because remove(0) is O(n) rather than O(1) 主要是因为remove(0)是O(n)而不是O(1)

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

// based on http://www.cs.princeton.edu/introcs/43stack/RingBuffer.java.html
public class IntRingBuffer {
    private final int[] a;       // queue elements
    private int N = 0;           // number of elements on queue
    private int first = 0;       // index of first element of queue
    private int last  = 0;       // index of next available slot

    // cast needed since no generic array creation in Java
    public IntRingBuffer(int capacity) {
        a = new int[capacity];
    }

    public boolean isEmpty() { return N == 0; }
    public int size()        { return N;      }

    public void enqueue(int item) {
        if (N == a.length) { throw new RuntimeException("Ring buffer overflow"); }
        a[last] = item;
        last = (last + 1) % a.length;     // wrap-around
        N++;
    }

    // remove the least recently added item - doesn't check for underflow
    public int dequeue() {
        if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
        int item = a[first];
        N--;
        first = (first + 1) % a.length;   // wrap-around
        return item;
    }

    public static void main(String... args) {
        int size = 1000000;
        {
        long start = System.nanoTime();
        IntRingBuffer list = new IntRingBuffer(size);
        for(int i=0;i< size;i++)
            list.enqueue(i);
        for(int i=0;i< size;i++)
            list.dequeue();
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }
        {
        long start = System.nanoTime();
        List<Integer> list = new LinkedList<Integer>();
        for(int i=0;i< size;i++)
            list.add(i);
        for(int i=0;i< size;i++)
            list.remove(0);
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }
        {
        long start = System.nanoTime();
        List<Integer> list = new ArrayList<Integer>();
        for(int i=0;i< size;i++)
            list.add(i);
        for(int i=0;i< size;i++)
            list.remove(0);
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }

    }
}

Prints 版画

IntRingBuffer: Took 31 ms to add/remove 1000000 elements
LinkedList: Took 252 ms to add/remove 1000000 elements
ArrayList: Took 325832 ms to add/remove 1000000 elements

Any relational DataBase you could access with JDBC: MySQL, PostgreSQL, Oracle, SQLServer, DB2, Informix, Interbase, Firebird, Ingress, you name it. 您可以使用JDBC访问的任何关系数据库:MySQL,PostgreSQL,Oracle,SQLServer,DB2,Informix,Interbase,Firebird,Ingress,您都可以命名。

If you are looking for something lightweight, you can have a look at SQLite's API for Java . 如果您正在寻找轻量级的东西,可以看看SQLite的Java API

I don't think there's really such a thing as a "FIFO database". 我认为没有真正的“ FIFO数据库”之类的东西。 A database normally allows you to access data in any desired order using some sort of indexing scheme. 数据库通常允许您使用某种索引方案以任何所需顺序访问数据。 You could implement a FIFO queue in a database by attaching sequence numbers to each record and reading them in order. 您可以通过将序列号附加到每个记录并按顺序读取它们来在数据库中实现FIFO队列。 Any database I've ever used would be capable of that. 我曾经使用过的任何数据库都可以做到这一点。

Perhaps the simple answer is that given by Pablo: use any relational database. 也许简单的答案就是Pablo给出的答案:使用任何关系数据库。 Pick one of the free ones like MySQL or Postgres, play with it, and learn what they do. 选择一种免费的工具,例如MySQL或Postgres,进行试用,并了解它们的作用。

Do you really mean a Database? 您真的是数据库吗? Because you can use an ArrayList for that: 因为您可以为此使用ArrayList

ArrayList<Integer> array = new ArrayList<Integer>();
array.add(3);
array.add(4);
array.add(5); // Appends to the end of this list

int myInt = array.remove(0); // Return first element

If you really need a database, can you give us more details on what you want to do? 如果您确实需要数据库,能否为我们提供有关您想做什么的更多详细信息?

[EDIT] I recommend you to read: Java Best Practices – Vector vs ArrayList vs HashSet Thanks! [编辑]我建议您阅读: Java最佳实践– Vector vs ArrayList vs HashSet谢谢!

Sounds like you're talking about a queue. 听起来您在谈论队列。 Look at JMS and see if that's the concept you're looking for. 查看JMS,看看这是否是您想要的概念。 While it may seem like a big tool for such a simple task, it will give you FIFO in a persisted (to any database you wish) functionality. 尽管它看起来像是用于完成此简单任务的重要工具,但它将为您提供FIFO(持久化(对于您希望的任何数据库))功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM