简体   繁体   中英

Which Data Structure would be more suitable for the following task in Java?

Every 5 minutes, within the 20th minute cycle, I need to retrieve the data. Currently, I'm using the map data structure.

Is there a better data structure? Every time I read and set the data, I have to write to the file to prevent program restart and data loss.

For example, if the initial data in the map is:

{-1:"result1",-2:"result2",-3:"result3",-4:"result4"}

I want to get the last -4 period's value which is "result4" , and set the new value "result5", so that the updated map will be:

{-1:"result5",-2:"result1",-3:"result2",-4:"result3"}

And again, I want to get the last -4 period's value which is "result3" , and set the new value "result6" , so the map will be:

{-1:"result6",-2:"result5",-3:"result1",-4:"result2"}

The code:

private static String getAndSaveValue(int a) { 
    //read the map from file
    HashMap<Long,String> resultMap=getMapFromFile();
    String  value=resultMap.get(-4L);

    for (Long i = 4L; i >= 2; i--){
        resultMap.put(Long.parseLong(String.valueOf(i - 2 * i)),resultMap.get(1 - i));
    }
    resultMap.put(-1L,"result" + a);
    //save the map to file
    saveMapToFile(resultMap);

    return value;
}

Based on your requirement, I think LinkedList data structure will be suitable for your requirement:

public class Test {
    public static void main(String[] args) {        
        LinkedList<String> ls=new LinkedList<String>();
        ls.push("result4");
        ls.push("result3");
        ls.push("result2");
        ls.push("result1");
        System.out.println(ls);
        ls.push("result5"); //pushing new value
        System.out.println("Last value:"+ls.pollLast()); //this will return `result4`
        System.out.println(ls);
        ls.push("result6"); //pushing new value
        System.out.println("Last value:"+ls.pollLast());  // this will give you `result3`
        System.out.println(ls);
    }
}

Output:

[result1, result2, result3, result4]
Last value:result4
[result5, result1, result2, result3]
Last value:result3  
[result6, result5, result1, result2]

Judging by your example, you need a FIFO data structure which has a bounded size.

There's no bounded general purpose implementation of the Queue interface in the JDK. Only concurrent implementation could be bounded in size. But if you're not going to use it in a multithreaded environment, it's not the best choice because thread safety doesn't come for free - concurrent collections are slower, and also can create confusing for the reader of your code.

To achieve your goal, I suggest you to use the composition by wrapping ArrayDeque , which is an array-based implementation of the Queue and performs way better than LinkedList .

Note that is a preferred approach not to extend ArrayDeque ( IS A relationship) and override its methods add() and offer() , but include it in a class as a field ( HAS A relationship), so that all the method calls on the instance of your class will be forwarded to the underlying collection. You can find more information regarding this approach in the item " Favor composition over inheritance " of Effective Java by Joshua Bloch.

public class BoundQueue<T> {
    private Queue<T> queue;
    private int limit;
    
    public BoundQueue(int limit) {
        this.queue = new ArrayDeque<>(limit);
        this.limit = limit;
    }
    
    public void offer(T item) {
        if (queue.size() == limit) {
            queue.poll(); // or throw new IllegalStateException() depending on your needs
        }
        queue.add(item);
    }
    
    public T poll() {
        return queue.poll();
    }
    
    public boolean isEmpty() {
        return queue.isEmpty();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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