0

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. What is best for this purpose?

Itzik984
  • 15,968
  • 28
  • 69
  • 107

5 Answers5

7

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.

An efficient collecton for int primitives is TIntArrayList. Its like @JPelletier's suggestion but wraps a int[]. A million int values should take about 4 MB of memory or disk.

EDIT: This shows that for 1 million numbers ArrayList is a bad choice. Mainly because remove(0) is O(n) rather than 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
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2
    Would give this several upvotes if I could because a) it's a better solution than the currently accepted one and b) it gives the timings to prove it. – DJClayworth Jan 18 '11 at 16:32
1

Any relational DataBase you could access with JDBC: MySQL, PostgreSQL, Oracle, SQLServer, DB2, Informix, Interbase, Firebird, Ingress, you name it.

If you are looking for something lightweight, you can have a look at SQLite's API for Java.

Community
  • 1
  • 1
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
1

I don't think there's really such a thing as a "FIFO database". 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. Any database I've ever used would be capable of that.

Perhaps the simple answer is that given by Pablo: use any relational database. Pick one of the free ones like MySQL or Postgres, play with it, and learn what they do.

Jay
  • 26,876
  • 10
  • 61
  • 112
  • I might be mistaken with how i wrote the question,but i was thinking about how to save say 1000000 integers and get them in the order they were entered. – Itzik984 Jan 18 '11 at 13:59
  • Wait, are you looking for a "database" or a "data structure"? – Jay Jan 18 '11 at 14:07
  • Ah, others have now posted answers to your real question. – Jay Jan 20 '11 at 22:04
1

Do you really mean a Database? Because you can use an ArrayList for that:

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!

JPelletier
  • 2,049
  • 16
  • 23
  • Ok, just saw your comments that you want a list. ArrayList is not synchronized so the performance is good. If you need synchronization, you can use: List list = Collections.synchronizedList(new ArrayList(...)); – JPelletier Jan 18 '11 at 14:00
  • Using a wrapper for int[] will be much more efficient. – Peter Lawrey Jan 18 '11 at 14:10
  • At a million elements, using Integer rather than int is going to chew up memory very quickly. Also "remove" is going to give you terrible performance. Peter Lawrey's solution is much better. – DJClayworth Jan 18 '11 at 16:31
0

Sounds like you're talking about a queue. Look at JMS and see if that's the concept you're looking for. 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.

Todd R
  • 18,236
  • 8
  • 31
  • 39