gpt4 book ai didi

java - removeEldestEntry 覆盖

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:57:12 24 4
gpt4 key购买 nike

如何覆盖 removeEldestEntry 方法以将最早的条目保存到文件中?还有如何限制文件的大小,就像我在 LinkedHashMap 中所做的那样。这是代码:

import java.util.*;

public class level1 {
private static final int max_cache = 50;
private Map cache = new LinkedHashMap(max_cache, .75F, true) {
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > max_cache;
}
};


public level1() {
for (int i = 1; i < 52; i++) {
String string = String.valueOf(i);
cache.put(string, string);
System.out.println("\rCache size = " + cache.size() +
"\tRecent value = " + i + " \tLast value = " +
cache.get(string) + "\tValues in cache=" +
cache.values());

}

我尝试使用 FileOutPutSTream :

    private Map cache = new LinkedHashMap(max_cache, .75F, true) {
protected boolean removeEldestEntry(Map.Entry eldest) throws IOException {
boolean removed = super.removeEldestEntry(eldest);
if (removed) {
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(eldest.getValue());

oos.close();
}
return removed;
}

但是我得到了一个错误

Error(15,27): removeEldestEntry(java.util.Map.Entry) in cannot override removeEldestEntry(java.util.Map.Entry) in java.util.LinkedHashMap; overridden method does not throw java.io.IOException

没有 IOExecptio 编译器要求处理 IOexception 和 Filenotfoundexception。也许存在另一种方式?请给我看示例代码,我是 java 的新手,只是想了解 2 级缓存的基本原理。谢谢

最佳答案

您首先需要确保您的方法正确覆盖父级。您可以对签名进行一些小的更改,例如只抛出一个更具体的已检查异常,该异常是父类中声明的已检查异常的子类。在这种情况下,父级不会声明任何已检查的异常,因此您无法进一步细化它并且可能不会抛出任何已检查的异常。因此,您必须在本地处理 IOException。有几种方法可以做到这一点,将其转换为某种类型的 RuntimeException 和/或记录它。

如果您担心文件大小,您可能不想只保留最后删除的条目,而是保留其中的许多条目 - 因此您应该打开文件进行追加。

您需要从该方法返回 true 以实际删除最老的元素,并且您需要决定是否应删除该元素。

在处理文件时,您应该使用 try/finally 来确保即使出现异常也能关闭资源。这可能会有点难看 - 有时有一个实用方法来执行关闭是很好的,这样你就不需要额外的 try/catch。

通常您还应该为文件 I/O 使用一些缓冲,这会大大提高性能;在这种情况下,使用将文件流包装在 java.io.BufferedOutputStream 中并将其提供给 ObjectOutputStream

这里有一些东西可以做你想做的事:

private static final int MAX_ENTRIES_ALLOWED = 100;
private static final long MAX_FILE_SIZE = 1L * 1024 * 1024; // 1 MB

protected boolean removeEldestEntry(Map.Entry eldest) {
if (size() <= MAX_ENTRIES_ALLOWED) {
return false;
}

File objFile = new File("t.tmp");
if (objFile.length() > MAX_FILE_SIZE) {
// Do something here to manage the file size, such as renaming the file
// You won't be able to easily remove an object from the file without a more
// advanced file structure since you are writing arbitrary sized serialized
// objects. You would need to do some kind of tagging of each entry or include
// a record length before each one. Then you would have to scan and rebuild
// a new file. You cannot easily just delete bytes earlier in the file without
// even more advanced structures (like having an index, fixed size records and
// free space lists, or even a database).
}

FileOutputStream fos = null;
try {
fos = new FileOutputStream(objFile, true); // Open for append
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos));

oos.writeObject(eldest.getValue());
oos.close(); // Close the object stream to flush remaining generated data (if any).
return true;
} catch (IOException e) {
// Log error here or....
throw new RuntimeException(e.getMessage(), e); // Convert to RuntimeException
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e2) {
// Log failure - no need to throw though
}
}
}
}

关于java - removeEldestEntry 覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4818159/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com