我有一个文件列表。我想扫描并计算相同大小的文件数量。问题在于文件大小很长,正如我们所知,hashmap 将只接收一个对象而不是一个原语。所以使用new Long(filesize)
,我将其放入哈希图中。由于每个 Long obj 都是唯一的,我没有得到一对 (filesize, count),而是得到了 (filesize, 1) 的列表。
我该如何构建这个蓄能器?
1.4.2的任何解决方案?
我有一个文件列表。我想扫描并计算相同大小的文件数量。问题在于文件大小很长,正如我们所知,hashmap 将只接收一个对象而不是一个原语。所以使用new Long(filesize)
,我将其放入哈希图中。由于每个 Long obj 都是唯一的,我没有得到一对 (filesize, count),而是得到了 (filesize, 1) 的列表。
我该如何构建这个蓄能器?
1.4.2的任何解决方案?
您只需这样做:
Map<Long, Integer> count = new HashMap<Long, Integer>();
for (File file : files) {
long size = file.getTotalSpace();
Integer n = count.get(size);
if (n == null) {
count.put(size, 1);
} else {
count.put(size, n + 1);
}
}
这里有一些自动装箱和拆箱。
而不是使用new Long(size)
,你应该使用Long.valueOf(size)
。这将返回内部缓存的相同 Long 引用,并且还应该提高性能(除非您执行数百万次这样的操作,否则它将不可见new Long()
)。
附言。仅适用于 java 1.5 或更高版本
您可以使用Trove存储对 (long,int) - TLongIntHashMap
或者您可以使用 AtomicInteger 作为可变整数。
Map<Long, AtomicInteger> count = new HashMap<Long, AtomicInteger>();
for (File file : files) {
long size = file.length(); // getTotalSpace() get the space consumed (e.g. a multiple of 8K) rather the actual file size.
AtomicInteger n = count.get(size);
if (n == null) {
count.put(size, new AtomicInteger(1));
} else {
n.getAndIncrement();
}
}
扩展 cletus 写的内容。
他的解决方案很好,除了它只存储您遇到的每个文件大小以及具有此大小的文件的数量。如果您想知道哪些文件是这种数据结构,那么这些文件对您来说毫无用处,所以我认为 cletus 解决方案不是很完整。相反,我会做
Map<Long, Collection<File>> count = new HashMap<Long, Collection<File>>();
for (File file : files) {
long size = file.getTotalSpace();
Collection<File> c = count.get(size);
if (c == null) {
c = new ArrayList<File>(); //or whatever collection you feel comfortable with
count.put(size, c);
}
c.add(file);
}
然后您可以使用 c.size() 获取文件的数量,并且您可以轻松地遍历具有该数量的所有文件,而无需再次运行此过程。
我认为还有更多内容,我们需要您提供更多详细信息。我假设您知道给定大小的文件肯定不止一个,否则我会先检查一下是否是这种情况。就您所知,您只是拥有许多具有独特文件大小的文件。
你提到:
...因为每个 Long 对象都是独一无二的。
我不认为这是问题所在。虽然这可能取决于您如何实例化 Long,但它不应该阻止 HashMaps 以您想要的方式运行。只要两个键对象返回相同的 hashCode() 值,并且 equals() 方法说它们相等,你的 HashMap 就不会为它创建另一个条目。实际上,您应该不可能看到具有相同文件大小值的“(filesize, 1) 列表”(除非您编写了自己的 Long 并且未能正确实现 hashCode()/equals())。
也就是说,如果您使用的是 Java 5 或更高版本,Cletus 的代码应该可以工作,如果您使用的是 Java 1.4 或更低版本,您需要手动进行自己的装箱/拆箱,或者查看Apache Commons Collections。这是 Cletus 示例的 Java 5 之前的版本:
Map count = new HashMap();
for (Iterator filesIter = files.iterator(); filesIter.hasNext();) {
File file = (File)filesIter.next();
long size = file.getTotalSpace();
Integer n = count.get(size);
if (n == null) {
count.put(size, Integer.valueOf(1));
} else {
count.put(size, Integer.valueOf(n.intValue() + 1));
}
}