Tag: 集合

Java集合协方差问题

假设我们有一个包含这些类的程序: public interface AbstractItem { } public SharpItem implements AbstractItem { } public BluntItem implements AbstractItem { } public interface AbstractToolbox { //well the problem starts here… public List getItems(); } public ExpensiveToolbox implements AbstractToolbox { private List items = new ArrayList(); public List getItems() { return this.items; } } public CheapTooblox implements AbstractToolbox { […]

关于不可变集和映射的JDK9随机化

阅读这个问题和Eugene给出的答案 ,我发现JDK9不可变集和映射将引入一个会影响其遍历的随机源。 这意味着迭代顺序确实是随机的,至少在JVM的不同运行中。 由于规范不保证集合和映射的任何遍历/迭代顺序,这绝对没问题。 实际上,代码绝不能依赖于特定于实现的细节,而是依赖于规范。 我知道今天,使用JDK 8,如果我有一个HashSet并执行此操作(取自链接的答案): Set wordSet = new HashSet(Arrays.asList(“just”, “a”, “test”)); System.out.println(wordSet); for (int i = 0; i < 100; i++) { wordSet.add("" + i); } for (int i = 0; i < 100; i++) { wordSet.remove("" + i); } System.out.println(wordSet); 然后元素的迭代顺序将改变,两个输出将不同。 这是因为向集合中添加和删除100个元素会更改HashSet的内部容量并重新生成元素。 这是完全有效的行为。 我这里不是在问这个问题。 但是,使用JDK9,如果我这样做: Set set = Set.of(“just”, “a”, “test”); […]

为什么HashMap会重新生成密钥对象提供的哈希码?

我正在阅读Java 1.6 API提供的HashMap类的代码,无法完全理解以下操作的需要(在put和get方法的主体中找到): int hash = hash(key.hashCode()); 方法hash()具有以下主体: private static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } 这有效地通过对提供的哈希码执行位操作来重新计算哈希值。 即使API声明如下,我也无法理解这样做的必要性: 这很关键,因为HashMap使用两个幂的长度哈希表,否则会遇到低位不同的hashCodes的冲突。 我确实理解键值是存储在数据结构数组中的,并且该数组中项的索引位置由其哈希确定。 我无法理解的是这个函数如何为哈希分布添加任何值。

为什么Java Collections Framework提供了两种不同的排序方式?

如果我有一个我想要排序的元素列表,Java提供了两种方法来解决这个问题。 例如,假设我有一个Movie对象列表,我想按标题对它们进行排序。 我可以这样做的一种方法是调用静态java.util.Collections.sort()方法的单参数版本,并将我的电影列表作为单个参数。 所以我会调用Collections.sort(myMovieList)。 为了使其工作,必须声明Movie类以实现java.lang.Comparable接口,并且必须在此类中实现所需的方法compareTo()。 另一种排序方法是使用影片列表和java.util.Comparator对象作为参数调用静态java.util.Collections.sort()方法的双参数版本。 我会调用Collections.sort(myMovieList,titleComparator)。 在这种情况下,Movie类不会实现Comparable接口。 相反,在构建和维护影片列表本身的主类中,我将创建一个实现java.util.Comparator接口的内部类,并实现一个必需的方法compare()。 然后我将创建此类的实例并调用sort()的双参数版本。 第二种方法的好处是您可以创建无限数量的这些内部类比较器,因此您可以以不同的方式对对象列表进行排序。 在上面的示例中,您可以让另一个Comparator按照制作电影的年份进行排序。 我的问题是,为什么麻烦学习两种方式在Java中进行排序,当Collections.sort()的双参数版本执行第一个单参数版本所做的所有事情时,还有一个额外的好处就是能够对列表的元素进行排序根据几个不同的标准? 在编码时必须记住这一点。 你有一个基本的机制来排序Java中的列表来了解。

Hibernate:选择其中包含所有指定valus的实体

我需要一个棘手的hibernate查询问题的帮助。 我有以下实体: public class Book { private String bookId; private String author; private String isbn; private Set tags; // getters, setters etc. } 和 public class Tag { private String tagId; private String tagName; // getters, setters, etc. } 两者之间存在多对多关联,由连接表books_tags_mn以及book_id和tag_id列表示。 我喜欢做的是:我想创建一个hibernate查询/条件查询,它返回所有具有所有特定标记集的书。 选择具有任何一组标签的所有书籍的工作方式是什么。 我一直在搞乱标准API,但并没有真正理解它。 所以我想做什么(在伪HQL中) from Book book where book.tags containsAll(:tags) 对此有任何帮助将非常感谢,所以非常感谢您提前。

Java Collection在满磁盘时会分页到磁盘?

一位同事提到他听说过一个轻量级的集合,当它的内容太满时会自动翻页到磁盘 – 但是他记不住这个名字了。 我想它看起来像这样: PagingCollection pagingCollection = new PagingArrayList(); pagingCollection.setMaxSizeInMemory(500); for (int x = 0; x < 1000; x++) { pagingcollection.add("x="+x); } 然后将x = 0推到x = 500到磁盘。 关键是能够迭代它而不将整个内容加载到内存中。 这适用于内存容量较小的胖客户端。 有谁知道它(或类似的东西)?

如何使用具有非唯一值的Guava进行地图反演?

我们怎样才能用番石榴做到这一点? 注意返回类型中存在List ,因为许多键可以映射到任何法线贴图中的相同值。 public static Map<V, List> inverse(Map map){ Map<V, List> result = new LinkedHashMap<V, List>(); for (Map.Entry entry : map.entrySet()) { if(!result.containsKey(entry.getValue())){ result.put(entry.getValue(), new ArrayList()); } result.get(entry.getValue()).add(entry.getKey()); } return result; } BiMap似乎坚持价值观的BiMap ,但我没有这种奢侈品。

计算java集合中出现次数的优雅方法

给定一组可能重复的对象,我想最终得到每个对象的出现次数。 我通过初始化一个空Map ,然后迭代Collection并将对象映射到它的计数(每次map已经包含对象时递增计数)来实现。 public Map countOccurrences(Collection list){ Map occurrenceMap = new HashMap(); for(Object obj: list){ Integer numOccurrence = occurrenceMap.get(obj); if(numOccurrence == null){ //first count occurrenceMap.put(obj, 1); } else{ occurrenceMap.put(obj, numOccurrence++); } } return occurrenceMap; } 对于计算出现次数的简单逻辑,这看起来过于冗长。 有更优雅/更短的方式吗? 我对一种完全不同的算法或java语言特定function持开放态度,允许更短的代码。

Java – 不同的对象列表

我有一个列表/对象集合,可能有也可能没有相同的属性值。 获得具有相同属性的对象的明确列表的最简单方法是什么? 一种集合类型最适合此目的吗? 例如,在C#中,我可以使用LINQ执行以下操作。 var recipients = (from recipient in recipientList select recipient).Distinct(); 我最初的想法是使用lambdaj( 链接文本 ),但它似乎不支持这一点。

对集合进行线程安全迭代

我们都知道在使用Collections.synchronizedXXX (例如synchronizedSet() )时,我们得到了底层集合的同步“视图”。 但是,这些包装器生成方法的文档指出,在使用迭代器迭代集合时,我们必须在集合上显式同步 。 您选择哪个选项来解决此问题? 我只能看到以下方法: 按照文档说明:对集合进行同步 在调用iterator()之前克隆集合 使用迭代器是线程安全的集合(我只知道CopyOnWriteArrayList / Set) 并且作为一个额外的问题:当使用同步视图时 – 使用foreach / Iterable线程安全吗?