40个Java Collections面试问答

Java Collections Framework is one of the core APIs of java programming language.

Java Collections Framework是Java编程语言的核心API之一。

It’s one of the important topics for java interview questions. Here I am listing some important java collections interview questions and answers to help you in the interview. This is directly coming from my 14+ years of experience in Java programming.

这是Java面试问题的重要主题之一。 在这里,我列出了一些重要的Java集合面试问题和解答,以帮助您进行面试。 这直接来自我14年以上的Java编程经验。

Java Collections面试问题 (Java Collections Interview Questions)

  1. What are Collection related features in Java 8?

    Java 8中与集合相关的功能是什么?
  2. What is Java Collections Framework? List out some benefits of Collections framework?

    什么是Java Collections Framework? 列出Collections框架的一些好处?
  3. What is the benefit of Generics in Collections Framework?

    集合框架中泛型的好处是什么?
  4. What are the basic interfaces of Java Collections Framework?

    Java Collections Framework的基本接口是什么?
  5. Why Collection doesn’t extend Cloneable and Serializable interfaces?

    为什么Collection不扩展Cloneable和Serializable接口?
  6. Why Map interface doesn’t extend Collection interface?

    为什么Map界面不扩展Collection界面?
  7. What is an Iterator?

    什么是迭代器?
  8. What is the difference between Enumeration and Iterator interface?

    Enumeration和Iterator接口有什么区别?
  9. Why there is not a method like Iterator.add() to add elements to the collection?

    为什么没有像Iterator.add()这样的方法将元素添加到集合中?
  10. Why Iterator don’t have a method to get next element directly without moving the cursor?

    为什么Iterator没有不移动光标就直接获取下一个元素的方法?
  11. What is different between Iterator and ListIterator?

    Iterator和ListIterator有什么区别?
  12. What are different ways to iterate over a list?

    有哪些不同的方法可以遍历列表?
  13. What do you understand by iterator fail-fast property?

    您对迭代器快速失败属性有什么了解?
  14. What is difference between fail-fast and fail-safe?

    故障快速和故障安全之间有什么区别?
  15. How to avoid ConcurrentModificationException while iterating a collection?

    如何在迭代集合时避免ConcurrentModificationException?
  16. Why there are no concrete implementations of Iterator interface?

    为什么没有Iterator接口的具体实现?
  17. What is UnsupportedOperationException?

    什么是UnsupportedOperationException?
  18. How HashMap works in Java?

    HashMap如何在Java中工作?
  19. What is the importance of hashCode() and equals() methods?

    hashCode()和equals()方法的重要性是什么?
  20. Can we use any class as Map key?

    我们可以使用任何类作为Map键吗?
  21. What are different Collection views provided by Map interface?

    Map界面提供哪些不同的Collection视图?
  22. What is difference between HashMap and Hashtable?

    HashMap和Hashtable有什么区别?
  23. How to decide between HashMap and TreeMap?

    如何在HashMap和TreeMap之间进行选择?
  24. What are similarities and difference between ArrayList and Vector?

    ArrayList和Vector之间有何异同?
  25. What is difference between Array and ArrayList? When will you use Array over ArrayList?

    Array和ArrayList有什么区别? 什么时候在ArrayList上使用Array?
  26. What is difference between ArrayList and LinkedList?

    ArrayList和LinkedList有什么区别?
  27. Which collection classes provide random access of its elements?

    哪些集合类提供对其元素的随机访问?
  28. What is EnumSet?

    什么是EnumSet?
  29. Which collection classes are thread-safe?

    哪些集合类是线程安全的?
  30. What are concurrent Collection Classes?

    什么是并发集合类?
  31. What is BlockingQueue?

    什么是BlockingQueue?
  32. What is Queue and Stack, list their differences?

    什么是队列和堆栈,列出它们的区别?
  33. What is Collections Class?

    什么是收藏课?
  34. What is Comparable and Comparator interface?

    什么是可比和比较器界面?
  35. What is difference between Comparable and Comparator interface?

    Comparable和Comparator接口之间有什么区别?
  36. How can we sort a list of Objects?

    我们如何排序对象列表?
  37. While passing a Collection as argument to a function, how can we make sure the function will not be able to modify it?

    在将Collection作为参数传递给函数时,我们如何确保该函数将无法对其进行修改?
  38. How can we create a synchronized collection from given collection?

    我们如何从给定的集合中创建一个同步的集合?
  39. What are common algorithms implemented in Collections Framework?

    Collections Framework中实现了哪些常见算法?
  40. What is Big-O notation? Give some examples?

    什么是Big-O表示法? 举一些例子?
  41. What are best practices related to Java Collections Framework?

    与Java Collections Framework相关的最佳实践是什么?
  42. What is Java Priority Queue?

    什么是Java优先级队列?
  43. Why can’t we write code as List<Number> numbers = new ArrayList<Integer>();?

    为什么我们不能将代码写为List<Number> numbers = new ArrayList<Integer>();
  44. Why can’t we create generic array? or write code as List<Integer>[] array = new ArrayList<Integer>[10];

    为什么我们不能创建通用数组? 或将代码写为List<Integer>[] array = new ArrayList<Integer>[10];

Java Collections面试问答 (Java Collections Interview Questions and Answers)

  1. Java 8中与集合相关的功能是什么? (What are Collection related features in Java 8?)

    Java 8 has brought major changes in the Collection API. Some of the changes are:

    1. Java Stream API for collection classes for supporting sequential as well as parallel processing
    2. Iterable interface is extended with forEach() default method that we can use to iterate over a collection. It is very helpful when used with lambda expressions because its argument Consumer is a function interface.
    3. Miscellaneous Collection API improvements such as forEachRemaining(Consumer action) method in Iterator interface, Map replaceAll(), compute(), merge() methods.

    Java 8对Collection API进行了重大更改。 一些更改是:

    1. Java Stream API用于收集类,以支持顺序处理和并行处理
    2. 可迭代接口使用forEach()默认方法扩展,可用于迭代集合。 与lambda表达式一起使用时,它非常有用,因为其参数Consumer是函数接口
    3. 其他Collection API的改进,例如Iterator接口中的forEachRemaining(Consumer action)方法,Map replaceAll()compute()merge()方法。
  2. 什么是Java Collections Framework? 列出Collections框架的一些好处? (What is Java Collections Framework? List out some benefits of Collections framework?)

    Collections are used in every programming language and initial java release contained few classes for collections: Vector, Stack, Hashtable, Array. But looking at the larger scope and usage, Java 1.2 came up with Collections Framework that group all the collections interfaces, implementations and algorithms.
    Java Collections have come through a long way with the usage of Generics and Concurrent Collection classes for thread-safe operations. It also includes blocking interfaces and their implementations in java concurrent package.
    Some of the benefits of collections framework are;

    • Reduced development effort by using core collection classes rather than implementing our own collection classes.
    • Code quality is enhanced with the use of well tested collections framework classes.
    • Reduced effort for code maintenance by using collection classes shipped with JDK.
    • Reusability and Interoperability

    每种编程语言都使用集合,并且最初的Java版本包含几个集合类: VectorStackHashtableArray 。 但是从更大的范围和用途来看,Java 1.2提出了Collections Framework,该框架将所有collection接口,实现和算法分组。
    Java集合通过将泛型和并发集合类用于线程安全操作已经走了很长一段路。 它还包括在Java并发包中的阻塞接口及其实现。
    收款框架的一些好处是;

    • 通过使用核心集合类而不是实现我们自己的集合类来减少开发工作。
    • 通过使用经过良好测试的集合框架类,可以提高代码质量。
    • 通过使用JDK附带的收集类,减少了代码维护工作。
    • 可重用性和互操作性
  3. 集合框架中泛型的好处是什么? (What is the benefit of Generics in Collections Framework?)

    Java 1.5 came with Generics and all collection interfaces and implementations use it heavily. Generics allow us to provide the type of Object that a collection can contain, so if you try to add any element of other type it throws compile time error.
    This avoids ClassCastException at Runtime because you will get the error at compilation. Also Generics make code clean since we don’t need to use casting and instanceof operator. I would highly recommend to go through Java Generic Tutorial to understand generics in a better way.

    Java 1.5带有泛型,所有集合接口和实现都大量使用它。 泛型允许我们提供集合可以包含的Object的类型,因此,如果您尝试添加其他类型的任何元素,则会引发编译时错误。
    这样可以避免在运行时发生ClassCastException,因为您将在编译时得到错误。 由于我们不需要使用强制转换和instanceof运算符,因此泛型也使代码更干净。 我强烈建议您阅读Java泛型教程 ,以更好地理解泛型。

  4. Java Collections Framework的基本接口是什么? (What are the basic interfaces of Java Collections Framework?)

    Collection is the root of the collection hierarchy. A collection represents a group of objects known as its elements. The Java platform doesn’t provide any direct implementations of this interface.

    Set is a collection that cannot contain duplicate elements. This interface models the mathematical set abstraction and is used to represent sets, such as the deck of cards.

    List is an ordered collection and can contain duplicate elements. You can access any element from its index. The list is more like an array with dynamic length.

    A Map is an object that maps keys to values. A map cannot contain duplicate keys: Each key can map to at most one value.

    Some other interfaces are Queue, Dequeue, Iterator, SortedSet, SortedMap and ListIterator.

    集合是集合层次结构的根。 集合表示一组称为其元素的对象。 Java平台不提供此接口的任何直接实现。

    Set是一个不能包含重复元素的集合。 此接口对数学集合的抽象进行建模,并用于表示集合,例如纸牌组。

    List是一个有序的集合,可以包含重复的元素。 您可以从其索引访问任何元素。 该列表更像是具有动态长度的数组。

    映射是将键映射到值的对象。 映射不能包含重复的键:每个键最多可以映射到一个值。

    其他一些接口是QueueDequeueIteratorSortedSetSortedMapListIterator

  5. 为什么Collection不扩展Cloneable和Serializable接口? (Why Collection doesn’t extend Cloneable and Serializable interfaces?)

    Collection interface specifies group of Objects known as elements. How the elements are maintained is left up to the concrete implementations of Collection. For example, some Collection implementations like List allow duplicate elements whereas other implementations like Set don’t.
    A lot of the Collection implementations have a public clone method. However, it doesn’t make sense to include it in all implementations of Collection. This is because Collection is an abstract representation. What matters is the implementation.
    The semantics and the implications of either cloning or serializing come into play when dealing with the actual implementation; so concrete implementation should decide how it should be cloned or serialized, or even if it can be cloned or serialized.
    So mandating cloning and serialization in all implementations is less flexible and more restrictive. The specific implementation should decide as to whether it can be cloned or serialized.

    集合接口指定一组称为元素的对象。 元素的维护方式取决于Collection的具体实现。 例如,某些Collection实现(例如List)允许重复元素,而其他实现(例如Set)则不允许重复元素。
    许多Collection实现都有公共克隆方法。 但是,将其包含在Collection的所有实现中没有意义。 这是因为Collection是抽象表示。 重要的是实施。
    在处理实际实现时,克隆或序列化的语义及其含义都会发挥作用。 因此具体实现应决定如何克隆或序列化它,甚至可以对其进行克隆或序列化。
    因此,在所有实现中强制进行克隆和序列化的灵活性较差,限制也更大。 具体实现应决定是否可以克隆或序列化。

  6. 为什么Map界面不扩展Collection界面? (Why Map interface doesn’t extend Collection interface?)

    Although Map interface and its implementations are part of the Collections Framework, Map is not collections and collections are not Map. Hence it doesn’t make sense for Map to extend Collection or vice versa.
    If Map extends Collection interface, then where are the elements? The map contains key-value pairs and it provides methods to retrieve the list of Keys or values as Collection but it doesn’t fit into the “group of elements” paradigm.

    尽管Map接口及其实现是Collections Framework的一部分,但Map不是集合,集合也不是Map。 因此,Map扩展Collection并没有反之亦然。
    如果Map扩展了Collection接口,那么元素在哪里? 该映射包含键-值对,并且提供了一些方法来检索键或值的列表作为Collection,但它不适合“元素组”范式。

  7. 什么是迭代器? (What is an Iterator?)

    The Iterator interface provides methods to iterate over any Collection. We can get iterator instance from a Collection using iterator() method. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators allow the caller to remove elements from the underlying collection during the iteration. Java Collection iterator provides a generic way for traversal through the elements of a collection and implements Iterator Design Pattern.

    Iterator接口提供了对任何Collection进行迭代的方法。 我们可以使用iterator()方法从Collection中获取迭代器实例。 在Java Collections Framework中,迭代器代替了枚举。 迭代器允许调用者在迭代过程中从基础集合中删除元素。 Java Collection迭代器提供了遍历集合元素的通用方法,并实现了Iterator Design Pattern

  8. Enumeration和Iterator接口之间有什么区别? (What is difference between Enumeration and Iterator interface?)

    Enumeration is twice as fast as Iterator and uses very little memory. Enumeration is very basic and fits basic needs. But the Iterator is much safer as compared to Enumeration because it always denies other threads to modify the collection object which is being iterated by it.
    Iterator takes the place of Enumeration in the Java Collections Framework. Iterators allow the caller to remove elements from the underlying collection that is not possible with Enumeration. Iterator method names have been improved to make its functionality clear.

    枚举速度是Iterator的两倍,并且只占用很少的内存。 枚举是非常基本的,适合基本需求。 但是,与Enumeration相比,Iterator安全得多,因为它始终拒绝其他线程修改被其迭代的集合对象。
    在Java Collections Framework中,迭代器代替了枚举。 迭代器允许调用者从基础集合中移除Enumeration无法实现的元素。 迭代器方法名称已得到改进,以使其功能更清晰。

  9. 为什么没有像Iterator.add()这样的方法将元素添加到集合中? (Why there is not method like Iterator.add() to add elements to the collection?)

    The semantics are unclear, given that the contract for Iterator makes no guarantees about the order of iteration. Note, however, that ListIterator does provide an add operation, as it does guarantee the order of the iteration.

    考虑到Iterator的约定不保证迭代顺序,语义尚不清楚。 但是请注意,ListIterator确实提供了添加操作,因为它确实保证了迭代的顺序。

  10. 为什么Iterator没有不移动光标就直接获取下一个元素的方法? (Why Iterator don’t have a method to get next element directly without moving the cursor?)

    It can be implemented on top of current Iterator interface but since its use will be rare, it doesn’t make sense to include it in the interface that everyone has to implement.

    可以在当前Iterator接口的顶部实现它,但是由于很少使用它,因此将其包含在每个人都必须实现的接口中没有意义。

  11. Iterator和ListIterator有什么区别? (What is different between Iterator and ListIterator?)

    • We can use Iterator to traverse Set and List collections whereas ListIterator can be used with Lists only.
    • Iterator can traverse in forward direction only whereas ListIterator can be used to traverse in both the directions.
    • ListIterator inherits from Iterator interface and comes with extra functionalities like adding an element, replacing an element, getting index position for previous and next elements.

    • 我们可以使用Iterator遍历Set和List集合,而ListIterator只能与Lists一起使用。
    • 迭代器只能向前移动,而ListIterator可以用于两个方向。
    • ListIterator继承自Iterator接口,并具有其他功能,例如添加元素,替换元素,获取上一个和下一个元素的索引位置。
  12. 有哪些不同的方法可以遍历列表? (What are different ways to iterate over a list?)

    We can iterate over a list in two different ways – using iterator and using for-each loop.

    List<String> strList = new ArrayList<>();
    
    //using for-each loop
    for(String obj : strList){
        System.out.println(obj);
    }
    
    //using iterator
    Iterator<String> it = strList.iterator();
    while(it.hasNext()){
        String obj = it.next();
        System.out.println(obj);
    }

    Using iterator is more thread-safe because it makes sure that if underlying list elements are modified, it will throw ConcurrentModificationException.

    我们可以通过两种不同的方式遍历列表–使用迭代器和使用for-each循环。

    使用迭代器更加线程安全,因为它可以确保如果基础列表元素被修改,它将抛出ConcurrentModificationException

  13. 您对迭代器快速失败属性有什么了解? (What do you understand by iterator fail-fast property?)

    Iterator fail-fast property checks for any modification in the structure of the underlying collection everytime we try to get the next element. If there are any modifications found, it throws ConcurrentModificationException. All the implementations of Iterator in Collection classes are fail-fast by design except the concurrent collection classes like ConcurrentHashMap and CopyOnWriteArrayList.

    每当我们尝试获取下一个元素时,迭代器fail-fast属性都会检查基础集合的结构是否有任何修改。 如果找到任何修改,则抛出ConcurrentModificationException 。 除并行并发类(例如ConcurrentHashMap和CopyOnWriteArrayList)外,Collection类中Iterator的所有实现在设计上都是快速失败的。

  14. 故障快速和故障安全之间有什么区别? (What is difference between fail-fast and fail-safe?)

    Iterator fail-safe property work with the clone of underlying collection, hence it’s not affected by any modification in the collection. By design, all the collection classes in java.util package are fail-fast whereas collection classes in java.util.concurrent are fail-safe.
    Fail-fast iterators throw ConcurrentModificationException whereas fail-safe iterator never throws ConcurrentModificationException.
    Check this post for CopyOnWriteArrayList Example.

    Iterator故障安全属性可与基础集合的克隆一起使用,因此不受集合中任何修改的影响。 按照设计, java.util包中的所有收集类都是快速失败的,而java.util.concurrent中的收集类是故障安全的。
    快速失败的迭代器会抛出ConcurrentModificationException,而安全的迭代器绝不会抛出ConcurrentModificationException。
    检查此帖子以获取CopyOnWriteArrayList示例

  15. 如何在迭代集合时避免ConcurrentModificationException? (How to avoid ConcurrentModificationException while iterating a collection?)

    We can use concurrent collection classes to avoid ConcurrentModificationException while iterating over a collection, for example CopyOnWriteArrayList instead of ArrayList.
    Check this post for ConcurrentHashMap Example.

    我们可以使用并发集合类来避免在迭代集合时发生ConcurrentModificationException ,例如,使用CopyOnWriteArrayList而不是ArrayList。
    在这篇文章中查看ConcurrentHashMap示例

  16. 为什么没有Iterator接口的具体实现? (Why there are no concrete implementations of Iterator interface?)

    Iterator interface declare methods for iterating a collection but its implementation is responsibility of the Collection implementation classes. Every collection class that returns an iterator for traversing has its own Iterator implementation nested class.
    This allows collection classes to chose whether iterator is fail-fast or fail-safe. For example ArrayList iterator is fail-fast whereas CopyOnWriteArrayList iterator is fail-safe.

    迭代器接口声明了用于迭代集合的方法,但是其实现是Collection实现类的责任。 每个返回迭代器以进行遍历的集合类都有其自己的Iterator实现嵌套类。
    这使集合类可以选择迭代器是快速失败还是故障安全的。 例如,ArrayList迭代器是快速失败的,而CopyOnWriteArrayList迭代器是故障安全的。

  17. 什么是UnsupportedOperationException? (What is UnsupportedOperationException?)

    UnsupportedOperationException is the exception used to indicate that the operation is not supported. It’s used extensively in JDK classes, in collections framework java.util.Collections.UnmodifiableCollection throws this exception for all add and remove operations.

    UnsupportedOperationException是用于指示不支持该操作的异常。 它在JDK类中被广泛使用,在集合框架java.util.Collections.UnmodifiableCollection ,所有addremove操作都会抛出此异常。

  18. HashMap如何在Java中工作? (How HashMap works in Java?)

    HashMap stores key-value pair in Map.Entry static nested class implementation. HashMap works on hashing algorithm and uses hashCode() and equals() method in put and get methods.

    When we call put method by passing key-value pair, HashMap uses Key hashCode() with hashing to find out the index to store the key-value pair. The Entry is stored in the LinkedList, so if there is an already existing entry, it uses equals() method to check if the passed key already exists, if yes it overwrites the value else it creates a new entry and stores this key-value Entry.

    When we call get method by passing Key, again it uses the hashCode() to find the index in the array and then use equals() method to find the correct Entry and return its value. The below image will explain these detail clearly.

    The other important things to know about HashMap are capacity, load factor, threshold resizing. HashMap initial default capacity is 16 and load factor is 0.75. The threshold is capacity multiplied by load factor and whenever we try to add an entry if map size is greater than the threshold, HashMap rehashes the contents of the map into a new array with a larger capacity. The capacity is always the power of 2, so if you know that you need to store a large number of key-value pairs, for example in caching data from the database, it’s a good idea to initialize the HashMap with correct capacity and load factor.

    HashMap将键值对存储在Map.Entry静态嵌套类实现中。 HashMap使用哈希算法,并在putget方法中使用hashCode()和equals()方法。

    当我们通过传递键值对来调用put方法时,HashMap使用带有哈希值的Key hashCode()来查找存储键值对的索引。 该条目存储在LinkedList中,因此,如果已经存在一个条目,则使用equals()方法检查传递的键是否已经存在,如果是,它将覆盖该值,否则它将创建一个新条目并存储此键值条目。

    当我们通过传递Key调用get方法时,它再次使用hashCode()查找数组中的索引,然后使用equals()方法查找正确的Entry并返回其值。 下图将清楚地解释这些细节。

    有关HashMap的其他重要信息是容量,负载因子,阈值大小调整。 HashMap的初始默认容量为16 ,负载系数为0.75。 阈值是容量乘以负载因子,如果地图大小大于阈值,每当我们尝试添加条目时,HashMap都会将地图的内容重新映射到容量更大的新数组中。 容量始终是2的乘方,因此,如果您知道需要存储大量键/值对,例如在从数据库缓存数据时,最好使用正确的容量和负载因子来初始化HashMap。 。

  19. hashCode()和equals()方法的重要性是什么? (What is the importance of hashCode() and equals() methods?)

    HashMap uses the Key object hashCode() and equals() method to determine the index to put the key-value pair. These methods are also used when we try to get value from HashMap. If these methods are not implemented correctly, two different Key’s might produce the same hashCode() and equals() output and in that case, rather than storing it at a different location, HashMap will consider the same and overwrite them.

    Similarly all the collection classes that doesn’t store duplicate data use hashCode() and equals() to find duplicates, so it’s very important to implement them correctly. The implementation of equals() and hashCode() should follow these rules.

    • If o1.equals(o2), then o1.hashCode() == o2.hashCode()should always be true.
    • If o1.hashCode() == o2.hashCode is true, it doesn’t mean that o1.equals(o2) will be true.

    HashMap使用Key对象的hashCode()和equals()方法来确定放置键值对的索引。 当我们尝试从HashMap获取价值时,也会使用这些方法。 如果这些方法的实现不正确,则两个不同的Key可能会产生相同的hashCode()和equals()输出,在这种情况下,HashMap不会考虑将它们存储在不同的位置,而是将其覆盖并覆盖它们。

    同样,所有不存储重复数据的集合类都使用hashCode()和equals()查找重复项,因此正确实现它们非常重要。 equals()和hashCode()的实现应遵循以下规则。

    • 如果o1.equals(o2) ,则o1.hashCode() == o2.hashCode()应始终为true
    • 如果o1.hashCode() == o2.hashCode为true,则并不意味着o1.equals(o2)true
  20. 我们可以使用任何类作为Map键吗? (Can we use any class as Map key?)

    We can use any class as Map Key, however following points should be considered before using them.

    • If the class overrides equals() method, it should also override hashCode() method.
    • The class should follow the rules associated with equals() and hashCode() for all instances. Please refer earlier question for these rules.
    • If a class field is not used in equals(), you should not use it in hashCode() method.
    • Best practice for user defined key class is to make it immutable, so that hashCode() value can be cached for fast performance. Also immutable classes make sure that hashCode() and equals() will not change in future that will solve any issue with mutability.
      For example, let’s say I have a class MyKey that I am using for the HashMap key.
      //MyKey name argument passed is used for equals() and hashCode()
      MyKey key = new MyKey("Pankaj"); //assume hashCode=1234
      myHashMap.put(key, "Value");
      
      // Below code will change the key hashCode() and equals()
      // but its location is not changed.
      key.setName("Amit"); //assume new hashCode=7890
      
      //below will return null because HashMap will try to look for key
      //in the same index as it was stored but since the key is mutated, 
      //there will be no match and it will return null.
      myHashMap.get(new MyKey("Pankaj"));

      This is the reason why String and Integer are mostly used as HashMap keys.

    我们可以将任何类用作Map Key,但是在使用它们之前应考虑以下几点。

    • 如果该类重写equals()方法,则它也应该重写hashCode()方法。
    • 对于所有实例,该类应遵循与equals()和hashCode()关联的规则。 这些规则请参考前面的问题。
    • 如果equals()中未使用类字段,则不应在hashCode()方法中使用它。
    • 用户定义的键类的最佳实践是使其不可变,以便可以缓存hashCode()值以提高性能。 不可变的类还确保hashCode()和equals()将来不会更改,这将解决任何可变性问题。
      例如,假设我有一个用于MyHashMap键的类MyKey

      这就是为什么String和Integer大多用作HashMap键的原因。

  21. Map界面提供哪些不同的Collection视图? (What are different Collection views provided by Map interface?)

    Map interface provides three collection views:

    1. Set<K> keySet(): Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator’s remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.
    2. Collection<V> values(): Returns a Collection view of the values contained in this map. The collection is backed by the map, so changes to the map are reflected in the collection, and vice-versa. If the map is modified while an iteration over the collection is in progress (except through the iterator’s remove operation), the results of the iteration are undefined. The collection supports element removal, which removes the corresponding mapping from the map, via the Iterator remove, Collection.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.
    3. Set<Map.Entry<K, V>> entrySet(): Returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator’s remove operation, or the setValue operation on a map entry returned by the iterator) the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

    Map界面提供了三个集合视图:

    1. Set <K> keySet() :返回此映射中包含的键的Set视图。 该集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器的remove操作除外),则迭代的结果不确定。 该集合支持元素删除,它通过迭代器remove,Set.remove,removeAll,retainAll和clear操作从映射中删除相应的映射。 它不支持add或addAll操作。
    2. Collection <V> values() :返回此映射中包含的值的Collection视图。 集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。 如果在对集合进行迭代时修改了映射(通过迭代器的remove操作除外),则迭代的结果是不确定的。 集合支持元素删除,该元素通过迭代器remove,Collection.remove,removeAll,retainAll和clear操作从映射中删除相应的映射。 它不支持add或addAll操作。
    3. Set <Map.Entry <K,V >> entrySet() :返回此映射中包含的映射的Set视图。 该集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。 如果在进行集合迭代时修改了映射(通过迭代器的remove操作或迭代器返回的映射条目的setValue操作除外),则迭代的结果不确定。 该集合支持元素删除,它通过迭代器remove,Set.remove,removeAll,retainAll和clear操作从映射中删除相应的映射。 它不支持add或addAll操作。
  22. HashMap和Hashtable有什么区别? (What is difference between HashMap and Hashtable?)

    HashMap and Hashtable both implements Map interface and looks similar, however, there is the following difference between HashMap and Hashtable.

    1. HashMap allows null key and values whereas Hashtable doesn’t allow null key and values.
    2. Hashtable is synchronized but HashMap is not synchronized. So HashMap is better for single threaded environment, Hashtable is suitable for multi-threaded environment.
    3. LinkedHashMap was introduced in Java 1.4 as a subclass of HashMap, so incase you want iteration order, you can easily switch from HashMap to LinkedHashMap but that is not the case with Hashtable whose iteration order is unpredictable.
    4. HashMap provides Set of keys to iterate and hence it’s fail-fast but Hashtable provides Enumeration of keys that doesn’t support this feature.
    5. Hashtable is considered to be legacy class and if you are looking for modifications of Map while iterating, you should use ConcurrentHashMap.

    HashMap和Hashtable都实现了Map接口,外观相似,但是HashMap和Hashtable之间存在以下区别。

    1. HashMap允许空键和值,而Hashtable不允许空键和值。
    2. Hashtable已同步,但HashMap未同步。 因此HashMap更适合单线程环境,而Hashtable适合多线程环境。
    3. LinkedHashMap是Java 1.4中作为HashMap的子类引入的,因此,如果需要迭代顺序,则可以轻松地从HashMap切换到LinkedHashMap,但是对于Hashtable而言,情况并非如此,其迭代顺序是不可预测的。
    4. HashMap提供了要迭代的键集,因此它是快速失败的,但是Hashtable提供了不支持此功能的键枚举。
    5. Hashtable被认为是旧类,如果在迭代时要查找Map的修改,则应使用ConcurrentHashMap。
  23. 如何在HashMap和TreeMap之间进行选择? (How to decide between HashMap and TreeMap?)

    For inserting, deleting, and locating elements in a Map, the HashMap offers the best alternative. If, however, you need to traverse the keys in a sorted order, then TreeMap is your better alternative. Depending upon the size of your collection, it may be faster to add elements to a HashMap, then convert the map to a TreeMap for sorted key traversal.

    为了在Map中插入,删除和定位元素,HashMap提供了最佳选择。 但是,如果需要按排序顺序遍历键,则TreeMap是更好的选择。 根据集合的大小,向HashMap中添加元素,然后将地图转换为TreeMap以进行排序的键遍历可能更快。

  24. ArrayList和Vector之间有何异同? (What are similarities and difference between ArrayList and Vector?)

    ArrayList and Vector are similar classes in many ways.

    1. Both are index based and backed up by an array internally.
    2. Both maintains the order of insertion and we can get the elements in the order of insertion.
    3. The iterator implementations of ArrayList and Vector both are fail-fast by design.
    4. ArrayList and Vector both allows null values and random access to element using index number.

    These are the differences between ArrayList and Vector.

    1. Vector is synchronized whereas ArrayList is not synchronized. However if you are looking for modification of list while iterating, you should use CopyOnWriteArrayList.
    2. ArrayList is faster than Vector because it doesn’t have any overhead because of synchronization.
    3. ArrayList is more versatile because we can get synchronized list or read-only list from it easily using Collections utility class.

    ArrayList和Vector在许多方面都是相似的类。

    1. 两者均基于索引,并由内部数组进行备份。
    2. 两者都保持插入顺序,我们可以按插入顺序获得元素。
    3. ArrayList和Vector的迭代器实现在设计上都是快速失败的。
    4. ArrayList和Vector都允许空值和使用索引号随机访问元素。

    这些是ArrayList和Vector之间的区别。

    1. 向量已同步,而ArrayList未同步。 但是,如果要在迭代时查找列表的修改,则应使用CopyOnWriteArrayList。
    2. ArrayList比Vector更快,因为由于同步它没有任何开销。
    3. ArrayList更具通用性,因为我们可以使用Collections实用程序类从其中轻松获取同步列表或只读列表。
  25. Array和ArrayList有什么区别? 什么时候在ArrayList上使用Array? (What is difference between Array and ArrayList? When will you use Array over ArrayList?)

    Arrays can contain primitive or Objects whereas ArrayList can contain only Objects.
    Arrays are fixed-size whereas ArrayList size is dynamic.
    Arrays don’t provide a lot of features like ArrayList, such as addAll, removeAll, iterator, etc.

    Although ArrayList is the obvious choice when we work on the list, there are a few times when an array is good to use.

    • If the size of list is fixed and mostly used to store and traverse them.
    • For list of primitive data types, although Collections use autoboxing to reduce the coding effort but still it makes them slow when working on fixed size primitive data types.
    • If you are working on fixed multi-dimensional situation, using [][] is far more easier than List<List<>>

    数组可以包含原语或对象,而ArrayList只能包含对象。
    数组是固定大小的,而ArrayList是动态的。
    数组不提供ArrayList之类的许多功能,例如addAll,removeAll,迭代器等。

    尽管在处理列表时ArrayList是显而易见的选择,但在某些情况下数组很好用。

    • 如果列表的大小是固定的,并且主要用于存储和遍历它们。
    • 对于原始数据类型列表,尽管Collections使用自动装箱来减少编码工作量,但是在处理固定大小的原始数据类型时,它仍然使它们变慢。
    • 如果您正在处理固定的多维情况,则使用[] []远比List <List <>>更容易
  26. ArrayList和LinkedList有什么区别? (What is difference between ArrayList and LinkedList?)

    ArrayList and LinkedList both implement List interface but there are some differences between them.

    1. ArrayList is an index based data structure backed by Array, so it provides random access to its elements with performance as O(1) but LinkedList stores data as list of nodes where every node is linked to its previous and next node. So even though there is a method to get the element using index, internally it traverse from start to reach at the index node and then return the element, so performance is O(n) that is slower than ArrayList.
    2. Insertion, addition or removal of an element is faster in LinkedList compared to ArrayList because there is no concept of resizing array or updating index when element is added in middle.
    3. LinkedList consumes more memory than ArrayList because every node in LinkedList stores reference of previous and next elements.

    ArrayList和LinkedList都实现List接口,但是它们之间有一些区别。

    1. ArrayList是由Array支持的基于索引的数据结构,因此它提供对元素的随机访问,性能为O(1),但LinkedList将数据存储为节点列表,其中每个节点都链接到其上一个和下一个节点。 因此,尽管有一种使用索引获取元素的方法,但它在内部从头开始遍历到索引节点,然后返回该元素,因此性能为O(n)比ArrayList慢。
    2. 与ArrayList相比,LinkedList中元素的插入,添加或删除要快于ArrayList,因为在中间添加元素时没有调整数组大小或更新索引的概念。
    3. LinkedList比ArrayList消耗更多的内存,因为LinkedList中的每个节点都存储上一个和下一个元素的引用。
  27. 哪些集合类提供对其元素的随机访问? (Which collection classes provide random access of its elements?)

    ArrayList, HashMap, TreeMap, Hashtable, and Vector classes provide random access to its elements. Download java collections pdf for more information.

    ArrayList,HashMap,TreeMap,Hashtable和Vector类提供对其元素的随机访问。 下载java collections pdf了解更多信息。

  28. 什么是EnumSet? (What is EnumSet?)

    java.util.EnumSet is Set implementation to use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created. EnumSet is not synchronized and null elements are not allowed. It also provides some useful methods like copyOf(Collection c), of(E first, E… rest) and complementOf(EnumSet s).

    Check this post for java enum tutorial.

    java.util.EnumSet是设置实现以用于枚举类型。 枚举集中的所有元素都必须来自创建集时明确或隐式指定的单个枚举类型。 EnumSet不同步,并且不允许使用null元素。 它还提供了一些有用的方法,例如copyOf(Collection c),of(E first,E…rest)和complementOf(EnumSet s)。

    在这篇文章中查看Java枚举教程

  29. 哪些集合类是线程安全的? (Which collection classes are thread-safe?)

    Vector, Hashtable, Properties and Stack are synchronized classes, so they are thread-safe and can be used in multi-threaded environment. Java 1.5 Concurrent API included some collection classes that allows modification of collection while iteration because they work on the clone of the collection, so they are safe to use in multi-threaded environment.

    Vector,Hashtable,Properties和Stack是同步类,因此它们是线程安全的,可以在多线程环境中使用。 Java 1.5 Concurrent API包括一些集合类,这些类允许在迭代时修改集合,因为它们在集合的克隆上工作,因此可以在多线程环境中安全使用。

  30. 什么是并发集合类? (What are concurrent Collection Classes?)

    Java 1.5 Concurrent package (java.util.concurrent) contains thread-safe collection classes that allow collections to be modified while iterating. By design Iterator implementation in java.util packages are fail-fast and throws ConcurrentModificationException. But Iterator implementation in java.util.concurrent packages are fail-safe and we can modify the collection while iterating. Some of these classes are CopyOnWriteArrayList, ConcurrentHashMap, CopyOnWriteArraySet.

    Read these posts to learn about them in more detail.

    Java 1.5并发包( java.util.concurrent )包含线程安全的集合类,这些类允许在迭代时修改集合。 根据设计, java.util包中的Iterator实现是快速失败的,并抛出ConcurrentModificationException。 但是java.util.concurrent包中的Iterator实现是故障安全的,我们可以在迭代时修改集合。 这些类中的一些是CopyOnWriteArrayListConcurrentHashMapCopyOnWriteArraySet

    阅读这些帖子以更详细地了解它们。

  31. 什么是BlockingQueue? (What is BlockingQueue?)

    java.util.concurrent.BlockingQueue is a Queue that supports operations that wait for the queue to become non-empty when retrieving and removing an element, and wait for space to become available in the queue when adding an element.

    BlockingQueue interface is part of the java collections framework and it’s primarily used for implementing the producer-consumer problem. We don’t need to worry about waiting for the space to be available for producer or object to be available for consumers in BlockingQueue as it’s handled by implementation classes of BlockingQueue.

    Java provides several BlockingQueue implementations such as ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue, etc.
    Check this post for use of BlockingQueue for producer-consumer problem.

    java.util.concurrent.BlockingQueue是一个Queue,它支持以下操作:在检索和删除元素时等待队列变为非空,在添加元素时等待队列中的空间变为可用。

    BlockingQueue接口是java集合框架的一部分,它主要用于实现生产者-消费者问题。 我们不必担心在BlockingQueue中等待生产者或对象对消费者可用的空间,因为它是由BlockingQueue的实现类处理的。

    Java提供了几种BlockingQueue实现,例如ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue,SynchronousQueue等。
    查看此帖子,了解使用BlockingQueue解决生产者-消费者问题

  32. 什么是队列和堆栈,列出它们的区别? (What is Queue and Stack, list their differences?)

    Both Queue and Stack are used to store data before processing them. java.util.Queue is an interface whose implementation classes are present in java concurrent package. Queue allows retrieval of element in First-In-First-Out (FIFO) order but it’s not always the case. There is also Deque interface that allows elements to be retrieved from both end of the queue.
    The stack is similar to queue except that it allows elements to be retrieved in Last-In-First-Out (LIFO) order.
    Stack is a class that extends Vector whereas Queue is an interface.

    队列和堆栈都用于存储数据,然后再处理它们。 java.util.Queue是一个接口,其实现类存在于Java并发包中。 队列允许按照先进先出(FIFO)的顺序检索元素,但情况并非总是如此。 还有一个Deque接口,该接口允许从队列的两端检索元素。
    堆栈类似于队列,除了它允许以后进先出(LIFO)顺序检索元素。
    堆栈是扩展Vector的类,而Queue是接口。

  33. 什么是收藏课? (What is Collections Class?)

    java.util.Collections is a utility class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, “wrappers”, which return a new collection backed by a specified collection, and a few other odds and ends.

    This class contains methods for collection framework algorithms, such as binary search, sorting, shuffling, reverse, etc.

    java.util.Collections是一个实用工具类,仅由对集合进行操作或返回集合的静态方法组成。 它包含对集合进行操作的多态算法,“包装器”(包装器),这些包装器返回由指定集合支持的新集合,以及其他一些零碎的东西。

    此类包含用于集合框架算法的方法,例如二进制搜索,排序,改组,反向等。

  34. 什么是可比和比较器界面? (What is Comparable and Comparator interface?)

    Java provides a Comparable interface which should be implemented by any custom class if we want to use Arrays or Collections sorting methods. The comparable interface has a compareTo(T obj) method which is used by sorting methods. We should override this method in such a way that it returns a negative integer, zero, or a positive integer if “this” object is less than, equal to, or greater than the object passed as an argument.

    But, in most real-life scenarios, we want sorting based on different parameters. For example, as a CEO, I would like to sort the employees based on Salary, an HR would like to sort them based on age. This is the situation where we need to use Comparator interface because Comparable.compareTo(Object o) method implementation can sort based on one field only and we can’t choose the field on which we want to sort the Object.

    Comparator interface compare(Object o1, Object o2) method need to be implemented that takes two Object argument, it should be implemented in such a way that it returns negative int if the first argument is less than the second one and returns zero if they are equal and positive int if the first argument is greater than the second one.

    Check this post for use of Comparable and Comparator interface to sort objects.

    Java提供了Comparable接口,如果我们要使用Arrays或Collections排序方法,则可以由任何自定义类实现。 可比较的接口具有compareTo(T obj)方法,该方法由排序方法使用。 如果“此”对象小于,等于或大于作为参数传递的对象,则应以使其返回负整数,零或正整数的方式覆盖此方法。

    但是,在大多数实际场景中,我们希望基于不同的参数进行排序。 例如,作为首席执行官,我想根据工资对员工进行排序,而人力资源则想根据年龄对员工进行排序。 在这种情况下,我们需要使用Comparator接口,因为Comparable.compareTo(Object o)方法实现只能基于一个字段进行排序,而我们不能选择要对Object进行排序的字段。

    需要实现带有两个Object参数的比较器接口compare(Object o1, Object o2)方法,该方法的实现方式是,如果第一个参数小于第二个参数,则返回负整数,如果第一个参数小于第二个,则返回零。如果第一个参数大于第二个参数,则等于和正整数。

    检查此帖子以了解使用Comparable和Comparator接口对对象进行排序

  35. Comparable和Comparator接口之间有什么区别? (What is difference between Comparable and Comparator interface?)

    Comparable and Comparator interfaces are used to sort collection or array of objects.

    Comparable interface is used to provide the natural sorting of objects and we can use it to provide sorting based on single logic.
    Comparator interface is used to provide different algorithms for sorting and we can choose the comparator we want to use to sort the given collection of objects.

    可比较和比较器接口用于对对象的集合或数组进行排序。

    可比接口用于提供对象的自然排序,我们可以使用它来提供基于单个逻辑的排序。
    比较器接口用于提供不同的排序算法,我们可以选择要用于比较给定对象集合的比较器。

  36. 我们如何排序对象列表? (How can we sort a list of Objects?)

    If we need to sort an array of Objects, we can use Arrays.sort(). If we need to sort a list of objects, we can use Collections.sort(). Both these classes have overloaded sort() methods for natural sorting (using Comparable) or sorting based on criteria (using Comparator).
    Collections internally uses Arrays sorting method, so both of them have same performance except that Collections take sometime to convert list to array.

    如果需要对对象数组进行排序,则可以使用Arrays.sort() 。 如果需要对对象列表进行排序,则可以使用Collections.sort() 。 这两个类都具有重载的sort()方法,用于自然排序(使用Comparable)或基于条件的排序(使用Comparator)。
    集合内部使用数组排序方法,因此两者的性能相同,只是集合需要一些时间才能将列表转换为数组。

  37. 在将Collection作为参数传递给函数时,我们如何确保该函数将无法对其进行修改? (While passing a Collection as argument to a function, how can we make sure the function will not be able to modify it?)

    We can create a read-only collection using Collections.unmodifiableCollection(Collection c) method before passing it as argument, this will make sure that any operation to change the collection will throw UnsupportedOperationException.

    我们可以在将其作为参数传递之前使用Collections.unmodifiableCollection(Collection c)方法创建一个只读集合,这将确保任何更改集合的操作都将抛出UnsupportedOperationException

  38. 我们如何从给定的集合中创建一个同步的集合? (How can we create a synchronized collection from given collection?)

    We can use Collections.synchronizedCollection(Collection c) to get a synchronized (thread-safe) collection backed by the specified collection.

    我们可以使用Collections.synchronizedCollection(Collection c)来获取指定集合支持的同步(线程安全)集合。

  39. Collections Framework中实现了哪些常见算法? (What are common algorithms implemented in Collections Framework?)

    Java Collections Framework provides algorithm implementations that are commonly used such as sorting and searching. Collections class contain these method implementations. Most of these algorithms work on List but some of them are applicable for all kinds of collections.
    Some of them are sorting, searching, shuffling, min-max values.

    Java Collections Framework提供了常用的算法实现,例如排序和搜索。 集合类包含这些方法实现。 这些算法大多数都可以在List上使用,但是其中一些算法适用于所有类型的集合。
    其中一些是排序,搜索,混排,最小-最大值。

  40. 什么是Big-O表示法? 举一些例子? (What is Big-O notation? Give some examples?)

    The Big-O notation describes the performance of an algorithm in terms of the number of elements in a data structure. Since Collection classes are data structures, we usually tend to use Big-O notation to chose the collection implementation to use based on time, memory and performance.

    Example 1: ArrayList get(index i) is a constant-time operation and doesn’t depend on the number of elements in the list. So its performance in Big-O notation is O(1).
    Example 2: A linear search on array or list performance is O(n) because we need to search through entire list of elements to find the element.

    Big-O表示法根据数据结构中元素的数量来描述算法的性能。 由于Collection类是数据结构,因此我们通常倾向于使用Big-O表示法根据时间,内存和性能来选择要使用的collection实现。

    示例1:ArrayList get(index i)是一个恒定时间操作,并且不依赖于列表中元素的数量。 因此,它在Big-O表示法中的性能为O(1)。
    示例2:对数组或列表性能的线性搜索为O(n),因为我们需要搜索整个元素列表以找到该元素。

  41. 与Java Collections Framework相关的最佳实践是什么? (What are best practices related to Java Collections Framework?)

    • Chosing the right type of collection based on the need, for example if size is fixed, we might want to use Array over ArrayList. If we have to iterate over the Map in order of insertion, we need to use LinkedHashMap. If we don’t want duplicates, we should use Set.
    • Some collection classes allows to specify the initial capacity, so if we have an estimate of number of elements we will store, we can use it to avoid rehashing or resizing.
    • Write program in terms of interfaces not implementations, it allows us to change the implementation easily at later point of time.
    • Always use Generics for type-safety and avoid ClassCastException at runtime.
    • Use immutable classes provided by JDK as key in Map to avoid implementation of hashCode() and equals() for our custom class.
    • Use Collections utility class as much as possible for algorithms or to get read-only, synchronized or empty collections rather than writing own implementation. It will enhance code-reuse with greater stability and low maintainability.

    • 根据需要选择正确的集合类型,例如,如果大小固定,我们可能要在ArrayList上使用Array。 如果必须按插入顺序遍历Map,则需要使用LinkedHashMap。 如果不想重复,则应使用Set。
    • 一些收集类允许指定初始容量,因此,如果我们估计要存储的元素数量,则可以使用它来避免重新哈希或调整大小。
    • 根据接口而不是实现来编写程序,它使我们可以在以后的时间轻松更改实现。
    • 始终将泛型用于类型安全,并在运行时避免ClassCastException。
    • 使用JDK提供的不可变类作为Map中的键,以避免为我们的自定义类实现hashCode()和equals()。
    • 尽可能将Collections实用程序类用于算法,或者获取只读,同步或空的Collections,而不是编写自己的实现。 它将以更高的稳定性和较低的可维护性来增强代码重用。
  42. 什么是Java优先级队列? (What is Java Priority Queue?)

    PriorityQueue is an unbounded queue based on a priority heap and the elements are ordered in their natural order or we can provide Comparator for ordering at the time of creation. PriorityQueue doesn’t allow null values and we can’t add any object that doesn’t provide natural ordering or we don’t have any comparator for them for ordering. Java PriorityQueue is not thread-safe and provided O(log(n)) time for enqueing and dequeing operations. Check this post for java priority queue example.

    PriorityQueue是基于优先级堆的无限制队列,并且元素以其自然顺序排序,或者我们可以在创建时提供Comparator进行排序。 PriorityQueue不允许使用null值,我们不能添加任何不提供自然排序的对象,或者我们没有用于排序的比较器。 Java PriorityQueue不是线程安全的,并且为入队和出队操作提供O(log(n))时间。 查看此帖子以获取Java优先级队列示例

  43. 为什么我们不能将代码写为List<Number> numbers = new ArrayList<Integer>();(Why can’t we write code as List<Number> numbers = new ArrayList<Integer>();?)

    Generics doesn’t support sub-typing because it will cause issues in achieving type safety. That’s why List<T> is not considered as a subtype of List<S> where S is the super-type of T. To understanding why it’s not allowed, let’s see what could have happened if it has been supported.

    List<Long> listLong = new ArrayList<Long>();
    listLong.add(Long.valueOf(10));
    List<Number> listNumbers = listLong; // compiler error
    listNumbers.add(Double.valueOf(1.23));

    As you can see from above code that IF generics would have been supporting sub-typing, we could have easily add a Double to the list of Long that would have caused ClassCastException at runtime while traversing the list of Long.

    泛型不支持子类型,因为它将导致实现类型安全的问题。 这就是为什么List <T>不被视为List <S>的子类型的原因,其中S是T的超类型。要理解为什么不允许它,让我们看看如果支持它会发生什么。

    从上面的代码中可以看到,IF泛型将一直支持子类型,我们可以轻松地向Long列表中添加Double,这会在遍历Long列表时在运行时导致ClassCastException

  44. 为什么我们不能创建通用数组? 或将代码写为List<Integer>[] array = new ArrayList<Integer>[10]; (Why can’t we create generic array? or write code as List<Integer>[] array = new ArrayList<Integer>[10];)

    We are not allowed to create generic arrays because array carry type information of its elements at runtime. This information is used at runtime to throw ArrayStoreException if elements type doesn’t match to the defined type. Since generics type information gets erased at compile time by Type Erasure, the array store check would have been passed where it should have failed. Let’s understand this with a simple example code.

    List<Integer>[] intList = new List<Integer>[5]; // compile error
    Object[] objArray = intList;
    List<Double> doubleList = new ArrayList<Double>();
    doubleList.add(Double.valueOf(1.23));
    objArray[0] = doubleList; // this should fail but it would pass because at runtime intList and doubleList both are just List

    Arrays are covariant by nature i.e S[] is a subtype of T[] whenever S is a subtype of T but generics doesn’t support covariance or sub-typing as we saw in the last question. So if we would have been allowed to create generic arrays, because of type erasure we would not get an array store exception even though both types are not related.

    To know more about Generics, read Java Generics Tutorial.

    我们不允许创建通用数组,因为数组在运行时会携带其元素的类型信息。 如果元素类型与定义的类型不匹配,则在运行时使用此信息引发ArrayStoreException 。 由于泛型类型信息在编译时会被类型擦除擦除,因此数组存储检查将在应该失败的地方通过。 让我们用一个简单的示例代码来理解这一点。

    数组本质上是协变的,即只要S是T的子类型,S []就是T []的子类型,但是泛型不支持协变或子类型,如我们在上一个问题中看到的那样。 因此,如果允许我们创建通用数组,由于类型擦除,即使两种类型都不相关,我们也不会获得数组存储异常。

    要了解有关泛型的更多信息,请阅读Java Generics Tutorial

I will keep on adding more questions on java collections framework as and when I found them, if you found it useful please share it with others too, it motivates me in writing more like these. 🙂

我将继续在java集合框架上添加更多问题,当我发现它们时,如果您发现它有用,也请与他人分享,这会激励我编写更多此类内容。 🙂

Please let me know if I have missed any important question, I will include that to list.

如果我错过了任何重要问题,请告诉我,我将在列表中列出。

翻译自: https://www.journaldev.com/1330/java-collections-interview-questions-and-answers

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值