17. 区分Java中的Array和ArrayList。
以下是 Java 中 Arrays 和 ArrayLists 之间的区别:
- Java 提供数组作为基本功能。ArrayList 是Java 集合系统的一个组件。因此,它用于访问数组成员,而 ArrayList 提供了一组访问和修改组件的方法。
- ArrayList 不是固定大小的数据结构,但 Array 是。创建 ArrayList 对象时,无需提供其大小。即使我们设置了最大容量,我们也可以在之后添加更多部件。
- 数组可以包含原始数据类型和类对象,具体取决于数组的定义。另一方面,ArrayList 只接受对象条目而不接受原始数据类型。请注意,当我们使用 arraylist.add(1); 时,原始 int 数据类型将转换为 Integer 对象。
- ArrayList 的成员总是引用不同内存位置的对象,因为不能为原始数据类型构造 ArrayList 结果,ArrayList 中的实际对象永远不会保存在同一个位置。对真实物品的引用保持在附近。数组是原始数组还是对象取决于数组的类型。原始类型的实际值是连续区域,而对象的分配等效于 ArrayList。
- Java ArrayList 支持许多其他操作,例如 indexOf() 和 delete()。数组不支持这些功能。
18. 如何在 Java 中将 ArrayList 设为只读?
借助 Collections.unmodifiableList() 方法,我们可以轻松地将 ArrayList 设为只读。此函数将可变的 ArrayList 作为输入,并返回 ArrayList 的只读、未修改的视图。
例子:
public class InterviewBit { public static void main(String[] args) throws Exception { try { // creating object of ArrayList<String> List<String> sample_list = new ArrayList<String>(); sample_list.add(“practice”); sample_list.add(“solve”); sample_list.add(“interview”); // displaying the initial list System.out.println("The initial list is : " + sample_list); // using unmodifiableList() method List<String> read_only_list = Collections .unmodifiableList(sample_list); // displaying the read-only list System.out.println("The ReadOnly ArrayList is : " + read_only_list); // Trying to add an element to the read-only list System.out.println("Trying to modify the ReadOnly ArrayList."); read_only_list.add(“job”); } catch (UnsupportedOperationException e) { System.out.println("The exception thrown is : " + e); } } }
输出:
The initial list is : [practice, solve, interview]
The ReadOnly ArrayList is: [practice, solve, interview]
Trying to modify th eReadOnly ArrayList.
Exception thrown: java.lang.UnsupportedOperationException
我们可以看到,当我们尝试将元素添加到只读 ArrayList 时,我们会抛出异常。
19.区分Java上下文中的Comparable和Comparator。
Comparable | Comparator |
Comparable 提供了一个单一的排序顺序。换句话说,我们可以按单个属性(例如 id、name 或 price)对集合进行排序。 | 比较器中提供了多个排序顺序。换句话说,我们可以根据 id、name 和 price 等不同的标准对集合进行排序。 |
为了对元素进行排序,Comparable 提供了 compareTo() 方法。 | 为了对元素进行排序,Comparator 提供了 compare() 方法。 |
它存在于 java.lang 包中。 | 它存在于 java.util 包中。 |
原类受Comparable影响,即改变了真实类。 | 原始类不受比较器的影响,即真实类不受影响。 |
Collections.sort(List) 方法可用于对 Comparable 类型列表成员进行排序。 | Collections.sort(List, Comparator) 方法可用于对 Comparator 类型的列表组件进行排序。 |
20. 你对 Java 中的 BlockingQueue 了解多少?
BlockingQueue 是一个与许多其他并发实用程序类(例如 ConcurrentHashMap、Counting Semaphore、CopyOnWriteArrayList 等)一起包含的接口。除了排队,BlockingQueue 接口通过在 BlockingQueue 已满或为空时添加阻塞来启用流控制。
试图将一个元素加入一个完整队列的线程将被阻塞,直到另一个线程通过使一个或多个元素出队或完全清除队列来清除队列。它还可以防止线程从空队列中删除,直到另一个线程插入一个项目。BlockingQueue 不接受空值。Java BlockingQueue 接口的实现是线程安全的。BlockingQueue 的方法都是原子的,并使用内部锁或其他形式的并发管理。
Java中有两种类型的BlockingQueue。它们如下:
无界队列:阻塞队列的容量将设置为整数。最大值。无界阻塞队列永远不会阻塞,因为它有可能增长到非常大的规模。随着您添加更多片段,队列的大小会增加。
例子 :
BlockingQueue unbounded_queue = new LinkedBlockingDeque();
有界队列:有界队列是第二种队列。在有界队列的情况下,队列的容量可以在创建阻塞队列时传递给构造函数。
例子:// Creates a Blocking Queue with capacity 10
BlockingQueue bounded_queue = new LinkedBlockingDeque(10);
21. 解释故障快速和故障安全迭代器。区分它们。
如果集合的结构发生变化,Fail-Fast迭代器会立即抛出 ConcurrentModificationException。当线程遍历集合时,结构更改包括添加或删除任何元素。故障安全迭代器类包括 ArrayList Iterator 和 HashMap Iterator。快速失败迭代器使用称为 modCount 的内部指示符,每次修改集合时都会更新该指示符,以确定集合是否已在结构上进行了修改。当快速失败迭代器(通过 next() 方法)获取下一项时,它会检查 modCount 标志,如果在生成迭代器后发现 modCount 已更改,则抛出 ConcurrentModificationException。
如果在对集合进行迭代时对其进行了结构更新,则故障安全迭代器不会抛出任何异常。因为它们对集合的克隆而不是原始集合进行操作,所以它们被称为故障安全迭代器。故障安全迭代器包括 CopyOnWriteArrayList 和 ConcurrentHashMap 类。
Fail-Fast | Fail-safe |
这些类型的迭代器不允许在迭代集合时修改集合。 | 这些类型的迭代器允许在迭代集合时修改集合。 |
如果在迭代集合时修改了集合,它会抛出 ConcurrentModificationException。 | 如果在迭代集合时修改了集合,则不会引发异常。 |
它在遍历元素时使用原始集合。 | 它在遍历它时使用原始集合的副本。 |
在这种情况下不需要额外的内存。 | 在这种情况下需要额外的内存。 |
22. RandomAccess 接口的用途是什么?命名实现此接口的集合类型。
RandomAccess 与 Serializable 和 Cloneable 接口一样,是一个标记接口。这些标记接口中没有定义任何方法。相反,他们将一个类指定为具有特定能力。
RandomAccess 接口指示给定的 java.util.List 实现是否支持随机访问。这个界面试图定义一个模糊的概念:快速是什么意思?文档中提供了一个简单的指南:如果使用 List.get() 方法重复访问比使用 Iterator.next() 方法重复访问更快,则 List 具有快速随机访问。
使用 List.get() 重复访问:
Object obj; for (int i=0, n=list.size( ); i < n; i++) obj = list.get(i);
使用 Iterator.next( ) 重复访问:
Object obj; for (Iterator itr=list.iterator( ); itr.hasNext( ); ) obj = itr.next( );
23. 区分迭代器和枚举。
Iterator:因为它可以应用于任何 Collection 对象,所以它是一个通用的迭代器。我们可以使用迭代器执行读取和删除操作。它是 Enumeration 的增强版本,增加了从列表中删除元素的功能。
枚举:枚举(或枚举)是由用户定义的数据类型。它主要用于给出整数常量名称,这使程序更易于理解和维护。枚举在 Java 中(从 1.5 开始)通过枚举数据类型表示。
迭代器 Iterator | 枚举 Enumeration |
Iterator 是一个通用游标,因为它适用于所有集合类。 | 因为它只适用于遗留类,所以枚举不是通用游标。 |
迭代器可以进行更改(例如,delete() 方法在遍历期间从 Collection 中删除元素)。 | Enumeration 接口是一个只读接口,这意味着您在遍历 Collection 元素时不能对 Collection 进行任何更改。 |
remove() 方法在 Iterator 类中可用。 | remove() 方法在枚举中不可用。 |
迭代器不是遗留接口。Iterator 可以遍历 HashMaps、LinkedLists、ArrayLists、HashSets、TreeMaps 和 TreeSets。 | 枚举是用于遍历 Hashtables 和 Vectors 的遗留接口。 |
24、Java中Properties类有什么用?属性文件有什么好处?
键值对都是属性对象中的字符串。java.util.Properties 类是 Hashtable 子类。
它可用于根据其键计算属性的值。Properties 类具有从属性文件读取和写入数据的方法。它也可以用来获取系统的属性。
属性文件的优点:
如果修改了属性文件中的信息,则不需要重新编译:如果属性文件中的任何信息发生更改,则无需重新编译 java 类。它用于跟踪需要经常更新的信息。
例子:
让我们首先创建一个名为“info.properties”的属性文件,其内容如下:
用户=成功
密码=决心
现在让我们创import java.util.*;
importjava.io.*;
public class Sample { public static void main(String[] args)throws Exception{ FileReader reader = new FileReader("info.properties"); Properties obj_p = new Properties(); obj_p.load(reader); System.out.println(obj_p.getProperty("user")); System.out.println(obj_p.getProperty("password")); } }
输出:
success determination
25. HashMap和HashTable的区别。
以下是HashMap和HashTable的区别:
- HashMap 是一种非同步数据结构。它不是线程安全的,并且在不使用同步代码的情况下不能在多个线程之间共享,而 Hashtable 是同步的。它是线程安全的,可以被多个线程使用。
- HashMap 支持一个空键和多个空值,而 Hashtable 不支持。
- 如果不需要线程同步,HashMap 通常比 HashTable 更可取。
26. 为什么HashMap允许null,而HashTable不允许null?
用作键的对象必须实现 hashCode 和 equals 方法才能成功地从 HashTable 中保存和检索对象。这些方法不能由 null 实现,因为它不是对象。HashMap是Hashtable的一个更高级和改进的变体。HashMap是在HashTable之后发明的,以克服HashTable的缺点。
27. 如何在 Java 中同步一个 ArrayList?
可以使用以下两种方式同步 ArrayList:
使用 Collections.synchronizedList() 方法:
对备份列表的所有访问都必须通过返回列表完成,才能执行串行访问。在遍历返回的列表时,用户手动同步至关重要。
例子:
class InterviewBit { public static void main (String[] args) { List<String> synchronized_list = Collections.synchronizedList(new ArrayList<String>()); synchronized_list.add("learn"); synchronized_list.add("practice"); synchronized_list.add("solve"); synchronized_list.add("interview"); synchronized(synchronized_list)// must be declared { Iterator it = synchronized_list.iterator(); while (it.hasNext()) System.out.println(it.next()); } } }
输出:
learn
practice
solve
interview
- 使用 CopyOnWriteArrayList:
CopyOnWriteArrayList<T> list_name = new CopyOnWriteArrayList<T>();
在这里,创建了 ArrayList 的线程安全变体。T 代表通用。
所有可变操作(例如添加、设置、删除等)都是通过在 ArrayList 的这个线程安全变体中生成底层数组的单独副本来实现的。它通过生成 List 的第二个副本来实现线程安全,这与向量和其他集合实现线程安全的方式不同。
即使在形成迭代器后修改了 copyOnWriteArrayList,迭代器也不会引发 ConcurrentModificationException,因为迭代器正在对 ArrayList 的单独副本进行迭代,而对 ArrayList 的另一个副本进行写操作。
例子:
import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; class InterviewBit { public static void main (String[] args) { CopyOnWriteArrayList<String> synchronized_list = new CopyOnWriteArrayList<String>();// creating a thread-safe Arraylist. // Adding strings to the synchronized ArrayList synchronized_list.add("learn"); synchronized_list.add("practice"); synchronized_list.add("solve"); synchronized_list.add("interview"); System.out.println("The synchronized ArrayList has the following elements :"); // Iterating on the synchronized ArrayList using an iterator. Iterator<String> it = synchronized_list.iterator(); while (it.hasNext()) System.out.println(it.next()); } }
输出:
The synchronized ArrayList has the following elements : learn practice solve interview
28. 当我们在Java中有Vectors(它们是同步的)时,为什么我们需要同步的ArrayList?
以下是我们需要同步 ArrayLists 的原因,即使我们有 Vectors :
- Vector 比 ArrayList 稍慢,因为它是同步的和线程安全的。
- Vector 的功能是同步每个单独的动作。程序员的偏好是同步整个动作序列。单独的操作不太安全,并且需要更长的时间来同步。
- 向量在 Java 中被认为是过时的并且已被非正式地弃用。Vector 还基于每个操作进行同步,这几乎从未完成。大多数 Java 程序员更喜欢使用 ArrayList,因为他们几乎肯定会在需要时显式同步 arrayList。
29、为什么Map接口不扩展Collection接口,反之亦然?
如果 Map 扩展了 Collection 接口,“键值对”可以是此类 Collection 的唯一元素类型,尽管这提供了非常有限(并且不是真正有用)的 Map 抽象。您无法查询特定键对应的值,也无法在不知道它对应的值的情况下删除条目。
Maps 上的三个“Collection 查看过程”表示 Maps 可以被视为集合(键、值或对)(keySet、entrySet 和值)的事实。虽然理论上可以将 List 视为映射到项的 Map 索引,但这具有不幸的副作用,即在删除成员之前更改与 List 中的每个元素关联的 Key。这也是不能做Collection来扩展Map Interface的原因。
30. 区分Java上下文中的HashMap和TreeMap。
HashMap | TreeMap |
Map 接口的 Java HashMap 实现基于哈希表。 | Java TreeMap 是基于Tree 结构的Map 接口实现。 |
Map、Cloneable 和 Serializable 接口由 HashMap 实现。 | NavigableMap、Cloneable 和 Serializable 接口由 TreeMap 实现。 |
因为 HashMap 不对键进行排序,所以它允许异构元素。 | 由于排序,TreeMap 允许将同质值用作键。 |
HashMap 比 TreeMap 更快,因为它为 get() 和 put() 等基本操作提供了 O(1) 的恒定时间性能。 | TreeMap 比 HashMap 慢,因为它以 O(log(n)) 的性能执行大多数操作,例如 add()、remove() 和 contains()。 |
HashMap 中允许单个空键和多个空值。 | TreeMap 不允许空键,但允许多个空值。 |
为了比较键,它使用 Object 类的 equals() 方法。它被 Map 类的 equals() 函数覆盖。 | 它使用 compareTo() 方法比较键。 |
HashMap 不跟踪任何顺序。 | 元素按时间顺序(升序)排列。 |
当我们不需要排序的键值对时,我们应该使用 HashMap。 | 当我们需要按排序(升序)顺序的键值对时,我们应该使用 TreeMap。 |
31. 在 Java 中给定一个数组,将其转换为一个集合。
我们可以使用 Java 中 Arrays 类的 asList() 方法将数组转换为集合。
import java.util.*; public class Convert_Array_To_Collection { public static void main(String args[]) { //creating a sample array String sample_array[] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; int length_array = sample_array.length; System.out.println("The input elements are as follows : "); for(int i = 0; i < length_array; i ++) { System.out.print(sample_array[i] + " "); } System.out.println();// setting the print cursor to the next line List converted_list = Arrays.asList(sample_array);// converting the array to a list // print converted elements System.out.println("The converted list is as follows : " + converted_list); } }
输出:
The input elements are as follows : Monday Tuesday Wednesday Thursday Friday Saturday Sunday The converted list is as follows : [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]
32. 用 Java 编写一个程序,使用枚举显示 HashTable 的内容。
我们使用 Enumeration 类的 hasMoreElements 和 nextElement 方法来遍历 HashMap
import java.util.Enumeration; import java.util.Hashtable; public class Iterate_HashTable { public static void main(String[] args) { Hashtable hash_table = new Hashtable();//creating a hash table hash_table.put("1", "Monday"); hash_table.put("2", "Tuesday"); hash_table.put("3", "Wednesday"); hash_table.put("4", "Thursday"); hash_table.put("5", "Friday"); hash_table.put("6", "Saturday"); hash_table.put("7", "Sunday"); Enumeration enumeration_hash_table = hash_table.elements();//creating an enumeration object //while loop runs until the hashtable has more entries in it while(enumeration_hash_table.hasMoreElements()) { System.out.println(enumeration_hash_table.nextElement()); } } }
输出:
Saturday Friday Thursday Wednesday Tuesday Monday Sunday
我们注意到值的顺序与我们在哈希表中插入键值对的顺序不同。这是因为 Hashtable 的元素不能保证在任何特定的序列中。哈希表的实现根据它们的 Hashcode 和内部实现将值分成多个桶,这意味着相同的值可能在不同的机器、运行或框架的版本上以不同的顺序出现。这是因为 Hashtables 旨在通过键而不是按顺序检索数据。
33. 编写一个程序,用 Java 打乱集合的所有元素。
我们使用 Collections 类的 shuffle() 方法。
import java.util.ArrayList; import java.util.Collections; import java.util.List; publicclassShuffle_collection{ publicstaticvoidmain(String[] argv) throws Exception { ArrayList<String> array_list =newArrayList<String>();//creating an arraylist of strings array_list.add("Monday"); array_list.add("Tuesday"); array_list.add("Wednesday"); array_list.add("Thursday"); array_list.add("Friday"); array_list.add("Saturday"); array_list.add("Sunday"); Collections.shuffle(array_list);//shuffling the arraylist System.out.println("The shuffled array list is as follows : "+ array_list);//printing the shuffled array list } }
输出:
The shuffled array list is as follows : [Thursday, Friday, Saturday, Wednesday, Tuesday, Sunday, Monday]
34. 用 Java 编写一个程序,将一个 Treeset 克隆到另一个 Treeset。
我们使用 TreeSet 类的 clone() 方法将一个 TreeSet 克隆到另一个 TreeSet 中。
import java.util.TreeSet; import java.util.Iterator; public class Clone_Tree_Set { public static void main(String[] args) { TreeSet<String> tree_set = new TreeSet<String>();//creating an empty tree set //adding values in the tree set tree_set.add("Monday"); tree_set.add("Tuesday"); tree_set.add("Wednesday"); tree_set.add("Thursday"); tree_set.add("Friday"); tree_set.add("Saturday"); tree_set.add("Sunday"); //printing the original tree set System.out.println("The original tree set is as follows : " + tree_set); //cloning the tree set TreeSet<String> cloned_tree_set = (TreeSet<String>)tree_set.clone(); //printing the cloned tree set System.out.println("The cloned tree set is as follows : " + cloned_tree_set); } }
输出:
The original tree set is as follows : [Friday, Monday, Saturday, Sunday, Thursday, Tuesday, Wednesday] The cloned tree set is as follows : [Friday, Monday, Saturday, Sunday, Thursday, Tuesday, Wednesday]
35. 用 java 编写一个程序来获取 HashMap 中存在的值的集合视图。
我们使用 HashMap 的 values() 函数来获取集合视图。
import java.util.*; public class Collection_View { public static void main(String args[]){ HashMap<String,String> hash_map = new HashMap<String,String>();//creating an empty hash map //adding key values to the hash map hash_map.put("1","Monday"); hash_map.put("2","Tuesday"); hash_map.put("3","Wednesday"); hash_map.put("4","Thursday"); hash_map.put("5","Friday"); hash_map.put("6","Saturday"); hash_map.put("7","Sunday"); //printing the original hash map System.out.println("The original hash map is as follows : " + hash_map); //printing the collection view of the hash map System.out.println("The collection view is as follows : " + hash_map.values()); } }
输出:
The original hash map is as follows: {1=Monday, 2=Tuesday, 3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday, 7=Sunday} The collection view is as follows : [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]
36.用java编写程序,将两个arraylist连接成一个arraylist。
我们使用 ArrayList 类的 addAll() 方法将两个给定数组列表的内容添加到一个新的数组列表中
import java.util.ArrayList; import java.util.Collections; public class Join_Lists { public static void main(String[] args) { //creating the first array list ArrayList<String> list_1 = new ArrayList<String>(); list_1.add("Monday"); list_1.add("Tuesday"); list_1.add("Wednesday"); list_1.add("Thursday"); //printing the first array list System.out.println("The elements of the first array list is as follows : " + list_1); //creating the second array list ArrayList<String> list_2 = new ArrayList<String>(); list_2.add("Friday"); list_2.add("Saturday"); list_2.add("Sunday"); //printing the second array list System.out.println("The elements of the second array list is as follows : " + list_2); //creating the third array list ArrayList<String> joined_list = new ArrayList<String>(); joined_list.addAll(list_1);//adding the elements of the first array list joined_list.addAll(list_2);//adding the elements of the second array list System.out.println("The elements of the joined array list is as follows : " + joined_list); } } 输出 The elements of the first array list is as follows : [Monday, Tuesday, Wednesday, Thursday] The elements of the second array list is as follows : [Friday, Saturday, Sunday] The elements of the joined array list is as follows : [Monday, Tu esday, Wednesday, Thursday, Fri