哪种数据结构更适合 Java 中的以下任务?
Which Data Structure would be more suitable for the following task in Java?
每隔 5
分钟,在第 20 分钟周期内,我需要检索数据。目前,我正在使用 map 数据结构。
有没有更好的数据结构?每次读取和设置数据都要写入文件,防止程序重启,数据丢失。
例如,如果map中的初始数据是:
{-1:"result1",-2:"result2",-3:"result3",-4:"result4"}
我想获取最后一个 -4
周期的值,即 "result4"
,并设置新值“result5”,以便更新后的 map将是:
{-1:"result5",-2:"result1",-3:"result2",-4:"result3"}
同样,我想获取最后一个 -4
周期的值,即 "result3"
,并设置新值 "result6"
,因此 map 将是:
{-1:"result6",-2:"result5",-3:"result1",-4:"result2"}
代码:
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;
}
根据您的要求,我认为 LinkedList 数据结构将适合您的要求:
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);
}
}
输出:
[result1, result2, result3, result4]
Last value:result4
[result5, result1, result2, result3]
Last value:result3
[result6, result5, result1, result2]
根据您的示例判断,您需要一个 FIFO 大小有界的数据结构。
JDK 中的 Queue
接口没有有限的通用实现。只有并发实现可以限制大小。但是如果你不打算在多线程环境中使用它,它不是最好的选择,因为线程安全不是免费的 - 并发收集速度较慢,并且还会使代码的 reader 混乱.
为了实现您的目标,我建议您通过包装 ArrayDeque
来使用合成,它是 Queue
的 array-based 实现并且比 [=14= 执行得更好].
请注意,首选方法是不扩展 ArrayDeque
(IS A 关系)并覆盖其方法 add()
和 offer()
,但将其作为字段包含在 class 中(具有 关系),以便对 class 实例的所有方法调用都将转发到底层集合。您可以在 Effective Java[ 的“Favor composition over inheritance”项中找到有关此方法的更多信息=33=] 作者:约书亚·布洛赫。
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();
}
}
每隔 5
分钟,在第 20 分钟周期内,我需要检索数据。目前,我正在使用 map 数据结构。
有没有更好的数据结构?每次读取和设置数据都要写入文件,防止程序重启,数据丢失。
例如,如果map中的初始数据是:
{-1:"result1",-2:"result2",-3:"result3",-4:"result4"}
我想获取最后一个 -4
周期的值,即 "result4"
,并设置新值“result5”,以便更新后的 map将是:
{-1:"result5",-2:"result1",-3:"result2",-4:"result3"}
同样,我想获取最后一个 -4
周期的值,即 "result3"
,并设置新值 "result6"
,因此 map 将是:
{-1:"result6",-2:"result5",-3:"result1",-4:"result2"}
代码:
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;
}
根据您的要求,我认为 LinkedList 数据结构将适合您的要求:
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);
}
}
输出:
[result1, result2, result3, result4]
Last value:result4
[result5, result1, result2, result3]
Last value:result3
[result6, result5, result1, result2]
根据您的示例判断,您需要一个 FIFO 大小有界的数据结构。
JDK 中的 Queue
接口没有有限的通用实现。只有并发实现可以限制大小。但是如果你不打算在多线程环境中使用它,它不是最好的选择,因为线程安全不是免费的 - 并发收集速度较慢,并且还会使代码的 reader 混乱.
为了实现您的目标,我建议您通过包装 ArrayDeque
来使用合成,它是 Queue
的 array-based 实现并且比 [=14= 执行得更好].
请注意,首选方法是不扩展 ArrayDeque
(IS A 关系)并覆盖其方法 add()
和 offer()
,但将其作为字段包含在 class 中(具有 关系),以便对 class 实例的所有方法调用都将转发到底层集合。您可以在 Effective Java[ 的“Favor composition over inheritance”项中找到有关此方法的更多信息=33=] 作者:约书亚·布洛赫。
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();
}
}