以单个单元表示的任何一组单独对象称为对象集合。在Java中,一个名为 “收集框架” 已在JDK 1.2中定义,其中包含所有集合类和接口。
集合界面( JAVAutil。收集 )和地图界面( JAVAutil。地图 )是Java集合类的两个主要“根”接口。
什么是框架?
框架是一组 班级 和 接口 它提供了一个现成的架构。为了实现一个新特性或类,不需要定义框架。然而,一个最佳的面向对象设计总是包含一个包含类集合的框架,这样所有的类都可以执行相同的任务。
需要一个单独的收集框架
在引入集合框架(或JDK 1.2之前)之前,对Java对象(或集合)进行分组的标准方法是 阵列 或 载体 或 哈希表 .所有这些集合都没有通用接口。因此,尽管所有集合的主要目标是相同的,但所有这些集合的实现都是独立定义的,它们之间没有相关性。而且,用户很难记住所有不同的信息 方法 、语法和 建设者 参加每一个收集课。
让我们通过在哈希表和向量中添加元素的示例来理解这一点。
JAVA
// Java program to demonstrate // why collection framework was needed import java.io.*; import java.util.*; class CollectionDemo { public static void main(String[] args) { // Creating instances of the array, // vector and hashtable int arr[] = new int [] { 1 , 2 , 3 , 4 }; Vector<Integer> v = new Vector(); Hashtable<Integer, String> h = new Hashtable(); // Adding the elements into the // vector v.addElement( 1 ); v.addElement( 2 ); // Adding the element into the // hashtable h.put( 1 , "geeks" ); h.put( 2 , "4geeks" ); // Array instance creation requires [], // while Vector and hastable require () // Vector element insertion requires addElement(), // but hashtable element insertion requires put() // Accessing the first element of the // array, vector and hashtable System.out.println(arr[ 0 ]); System.out.println(v.elementAt( 0 )); System.out.println(h.get( 1 )); // Array elements are accessed using [], // vector elements using elementAt() // and hashtable elements using get() } } |
输出:
1 1 geeks
正如我们所观察到的,这些集合(数组、向量或哈希表)都没有实现标准的成员访问接口,程序员很难编写适用于各种集合的算法。另一个缺点是大多数“Vector”方法都是final,这意味着我们无法扩展“Vector”类来实现类似的集合。因此,Java开发人员决定提出一个通用接口来处理上述问题,并在JDK 1.2 post中引入了收集框架,对遗留向量和哈希表进行了修改,以符合收集框架。
收集框架的优点: 由于缺乏收集框架导致了上述一系列缺点,以下是收集框架的优点。
- 一致的API: API有一套基本的 接口 喜欢 收集 , 设置 , 列表 或 地图 ,所有的班级( ArrayList , 链表 实现这些接口的 一些 常用的一套方法。
- 减少编程工作量: 程序员不必担心集合的设计,而是可以专注于它在程序中的最佳使用。因此,面向对象编程(即抽象)的基本概念已经成功实现。
- 提高节目速度和质量: 通过提供有用数据结构和算法的高性能实现来提高性能,因为在这种情况下,程序员不需要考虑特定数据结构的最佳实现。他可以简单地使用最好的实现来大幅提高算法/程序的性能。
收集框架的层次结构
实用程序包(java.util)包含集合框架所需的所有类和接口。集合框架包含一个名为iterable接口的接口,该接口提供迭代器来迭代所有集合。该接口由作为集合框架根的主集合接口扩展。所有集合都扩展了这个集合接口,从而扩展了迭代器的属性和这个接口的方法。下图说明了集合框架的层次结构。
在理解上述框架中的不同组件之前,让我们先了解一个类和一个接口。
- 班 : 类是用户定义的蓝图或原型,从中创建对象。它表示一种类型的所有对象所共有的一组属性或方法。
- 界面 : 与类一样,接口可以有方法和变量,但接口中声明的方法默认是抽象的(只有方法签名,没有正文)。接口指定类必须做什么,而不是如何做。这是班级的蓝图。
收集接口的方法
此接口包含各种方法,可由实现此接口的所有集合直接使用。他们是:
方法 |
描述 |
---|---|
添加(对象) | 此方法用于向集合中添加对象。 |
addAll(集合c) | 此方法将给定集合中的所有元素添加到此集合。 |
清除() | 此方法删除此集合中的所有元素。 |
包含(对象o) | 如果集合包含指定的元素,则此方法返回true。 |
CONTANSALL(c系列) | 如果集合包含给定集合中的所有元素,则此方法返回true。 |
等于(对象o) | 此方法比较指定对象与此集合的相等性。 |
hashCode() | 此方法用于返回此集合的哈希代码值。 |
isEmpty() | 如果此集合不包含元素,则此方法返回true。 |
迭代器() | 此方法返回此集合中元素的迭代器。 |
麦克斯() | 此方法用于返回集合中存在的最大值。 |
parallelStream() | 此方法返回一个以该集合为源的并行流。 |
移除(对象o) | 此方法用于从集合中删除给定对象。如果存在重复值,则此方法将删除对象的第一个匹配项。 |
removeAll(集合c) | 此方法用于从集合中删除给定集合中提到的所有对象。 |
removeIf(谓词过滤器) | 此方法用于删除此集合中满足给定条件的所有元素 谓语 . |
保留(c组) | 此方法仅用于保留此集合中包含在指定集合中的元素。 |
大小() | 此方法用于返回集合中的元素数。 |
拆分器() | 此方法用于创建 分离器 在这个系列的元素之上。 |
流() | 此方法用于返回以此集合为源的序列流。 |
toArray() | 此方法用于返回包含此集合中所有元素的数组。 |
扩展集合接口的接口
收集框架包含多个接口,每个接口用于存储特定类型的数据。以下是框架中存在的接口。
1.可移植接口: 这是整个集合框架的根接口。collection接口扩展了iterable接口。因此,从本质上讲,所有接口和类都实现了这个接口。该接口的主要功能是为集合提供迭代器。因此,这个接口只包含一个抽象方法,即迭代器。它返回
迭代器迭代器();
2.采集接口: 该接口扩展了iterable接口,并由集合框架中的所有类实现。该接口包含每个集合都具有的所有基本方法,如向集合中添加数据、删除数据、清除数据等。所有这些方法都在该接口中实现,因为这些方法由所有类实现,而不管它们的实现方式如何。而且,在这个接口中使用这些方法可以确保这些方法的名称对于所有集合都是通用的。因此,简而言之,我们可以说,这个接口为实现集合类奠定了基础。
3. 列表界面: 这是集合接口的子接口。该接口专用于列表类型的数据,我们可以在其中存储所有有序的对象集合。这也允许在其中存在重复数据。这个列表接口由不同的类实现,比如 ArrayList , 矢量 , 堆栈 因为所有的子类都实现了列表,所以我们可以用这些类中的任何一个实例化一个列表对象。例如
List
al=new ArrayList<>(); List ll=new LinkedList<>(); List v=新向量<>(); 其中T是对象的类型
实现列表接口的类如下所示:
A. ArrayList: ArrayList为我们提供了Java中的动态数组。不过,它可能比标准数组慢,但在需要对数组进行大量操作的程序中可能会有所帮助。如果从集合中删除对象,则集合会增大或缩小,则ArrayList的大小会自动增大。Java ArrayList允许我们随机访问列表。ArrayList不能用于 基本类型 ,比如int,char等等。我们需要一个 包装类 对于这种情况。让我们通过以下示例了解ArrayList:
JAVA
// Java program to demonstrate the // working of ArrayList import java.io.*; import java.util.*; class GFG { // Main Method public static void main(String[] args) { // Declaring the ArrayList with // initial size n ArrayList<Integer> al = new ArrayList<Integer>(); // Appending new elements at // the end of the list for ( int i = 1 ; i <= 5 ; i++) al.add(i); // Printing elements System.out.println(al); // Remove element at index 3 al.remove( 3 ); // Displaying the ArrayList // after deletion System.out.println(al); // Printing elements one by one for ( int i = 0 ; i < al.size(); i++) System.out.print(al.get(i) + " " ); } } |
[1, 2, 3, 4, 5] [1, 2, 3, 5] 1 2 3 5
B LinkedList: LinkedList类是 LinkedList数据结构 这是一种线性数据结构,其中元素不存储在连续位置,每个元素都是一个单独的对象,具有数据部分和地址部分。元素使用指针和地址链接。每个元素称为一个节点。让我们用下面的例子来理解LinkedList:
JAVA
// Java program to demonstrate the // working of LinkedList import java.io.*; import java.util.*; class GFG { // Main Method public static void main(String[] args) { // Declaring the LinkedList LinkedList<Integer> ll = new LinkedList<Integer>(); // Appending new elements at // the end of the list for ( int i = 1 ; i <= 5 ; i++) ll.add(i); // Printing elements System.out.println(ll); // Remove element at index 3 ll.remove( 3 ); // Displaying the List // after deletion System.out.println(ll); // Printing elements one by one for ( int i = 0 ; i < ll.size(); i++) System.out.print(ll.get(i) + " " ); } } |
[1, 2, 3, 4, 5] [1, 2, 3, 5] 1 2 3 5
C 矢量: 向量为我们提供了Java中的动态数组。不过,它可能比标准数组慢,但在需要对数组进行大量操作的程序中可能会有所帮助。这在实现方面与ArrayList相同。然而,向量和ArrayList之间的主要区别在于向量是同步的,而ArrayList是非同步的。让我们用一个例子来理解向量:
JAVA
// Java program to demonstrate the // working of Vector import java.io.*; import java.util.*; class GFG { // Main Method public static void main(String[] args) { // Declaring the Vector Vector<Integer> v = new Vector<Integer>(); // Appending new elements at // the end of the list for ( int i = 1 ; i <= 5 ; i++) v.add(i); // Printing elements System.out.println(v); // Remove element at index 3 v.remove( 3 ); // Displaying the Vector // after deletion System.out.println(v); // Printing elements one by one for ( int i = 0 ; i < v.size(); i++) System.out.print(v.get(i) + " " ); } } |
[1, 2, 3, 4, 5] [1, 2, 3, 5] 1 2 3 5
D 堆栈 : 堆栈类建模并实现 堆栈数据结构 .这门课的基本原则是 后进先出 .除了基本的推送和弹出操作外,该类还提供了另外三个功能:清空、搜索和查看。该类也可以称为Vector的子类。让我们用一个例子来理解堆栈:
JAVA
// Java program to demonstrate the // working of a stack import java.util.*; public class GFG { // Main Method public static void main(String args[]) { Stack<String> stack = new Stack<String>(); stack.push( "Geeks" ); stack.push( "For" ); stack.push( "Geeks" ); stack.push( "Geeks" ); // Iterator for the stack Iterator<String> itr = stack.iterator(); // Printing the stack while (itr.hasNext()) { System.out.print(itr.next() + " " ); } System.out.println(); stack.pop(); // Iterator for the stack itr = stack.iterator(); // Printing the stack while (itr.hasNext()) { System.out.print(itr.next() + " " ); } } } |
Geeks For Geeks Geeks Geeks For Geeks
注: Stack是Vector的一个子类,也是一个遗留类。它是线程安全的,在不需要线程安全的环境中,这可能会增加开销。堆栈的替代方法是使用 列队 它不是线程安全的,具有更快的阵列实现。
4. 队列接口 : 顾名思义,队列接口维护FIFO(先进先出)顺序,类似于真实世界的队列。该接口专用于存储元素顺序重要的所有元素。例如,每当我们试图订票时,票都是先到先得的。因此,请求最先到达队列的人将获得票证。有各种各样的课程,比如 优先队列 , ArrayDeque 因为所有这些子类都实现了队列,所以我们可以用这些类中的任何一个实例化队列对象。例如
Queue
pq=new PriorityQueue<>(); 队列 ad=new ArrayDeque<>(); 其中T是对象的类型。
队列接口最常用的实现是PriorityQueue。 优先级队列: 当根据优先级处理对象时,使用PriorityQueue。众所周知,队列遵循先进先出算法,但有时需要根据优先级处理队列元素,在这些情况下使用此类。优先级队列基于优先级堆。优先级队列的元素按照自然顺序排序,或者按照 比较器 根据使用的构造函数,在队列构造时提供。让我们用一个例子来理解优先级队列:
JAVA
// Java program to demonstrate the working of // priority queue in Java import java.util.*; class GfG { // Main Method public static void main(String args[]) { // Creating empty priority queue PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>(); // Adding items to the pQueue using add() pQueue.add( 10 ); pQueue.add( 20 ); pQueue.add( 15 ); // Printing the top element of PriorityQueue System.out.println(pQueue.peek()); // Printing the top element and removing it // from the PriorityQueue container System.out.println(pQueue.poll()); // Printing the top element again System.out.println(pQueue.peek()); } } |
10 10 15
5. Deque接口 : 这是一个非常微小的变化 队列数据结构 . 德克 ,也称为双端队列,是一种数据结构,我们可以在其中添加和删除队列两端的元素。此接口扩展了队列接口。实现这个接口的类是 ArrayDeque .由于ArrayDeque类实现了Deque接口,我们可以用这个类实例化Deque对象。例如
Deque
ad=new ArrayDeque<>(); 其中T是对象的类型。
实现deque接口的类是ArrayQue。
ArrayDeque: 在集合框架中实现的ArrayQue类为我们提供了一种应用可调整大小的数组的方法。这是一种特殊的数组,它可以增长,并允许用户从队列两侧添加或删除元素。阵列设备没有容量限制,它们会根据需要增长以支持使用。让我们用一个例子来理解ArrayDesk:
JAVA
// Java program to demonstrate the // ArrayDeque class in Java import java.util.*; public class ArrayDequeDemo { public static void main(String[] args) { // Initializing an deque ArrayDeque<Integer> de_que = new ArrayDeque<Integer>( 10 ); // add() method to insert de_que.add( 10 ); de_que.add( 20 ); de_que.add( 30 ); de_que.add( 40 ); de_que.add( 50 ); System.out.println(de_que); // clear() method de_que.clear(); // addFirst() method to insert the // elements at the head de_que.addFirst( 564 ); de_que.addFirst( 291 ); // addLast() method to insert the // elements at the tail de_que.addLast( 24 ); de_que.addLast( 14 ); System.out.println(de_que); } } |
[10, 20, 30, 40, 50] [291, 564, 24, 14]
6. 设置接口 : 集合是对象的无序集合,其中不能存储重复的值。当我们希望避免对象的重复并希望只存储唯一的对象时,使用此集合。这个set接口由不同的类实现,比如 哈希集 , 有序树 , LinkedHashSet 因为所有的子类都实现了集合,所以我们可以用这些类中的任何一个实例化集合对象。例如
Set
hs=新HashSet<>(); Set lhs=新LinkedHashSet<>(); 设置 ts=new TreeSet<>(); 其中T是对象的类型。
以下是实现Set接口的类:
A. 哈希集: HashSet类是哈希表数据结构的固有实现。我们插入到哈希集中的对象不能保证以相同的顺序插入。根据对象的哈希代码插入对象。此类还允许插入空元素。让我们用一个例子来理解HashSet:
JAVA
// Java program to demonstrate the // working of a HashSet import java.util.*; public class HashSetDemo { // Main Method public static void main(String args[]) { // Creating HashSet and // adding elements HashSet<String> hs = new HashSet<String>(); hs.add( "Geeks" ); hs.add( "For" ); hs.add( "Geeks" ); hs.add( "Is" ); hs.add( "Very helpful" ); // Traversing elements Iterator<String> itr = hs.iterator(); while (itr.hasNext()) { System.out.println(itr.next()); } } } |
Very helpful Geeks For Is
B LinkedHashSet : LinkedHashSet与HashSet非常相似。不同之处在于,它使用双链表存储数据,并保留元素的顺序。让我们用一个例子来理解LinkedHashSet:
JAVA
// Java program to demonstrate the // working of a LinkedHashSet import java.util.*; public class LinkedHashSetDemo { // Main Method public static void main(String args[]) { // Creating LinkedHashSet and // adding elements LinkedHashSet<String> lhs = new LinkedHashSet<String>(); lhs.add( "Geeks" ); lhs.add( "For" ); lhs.add( "Geeks" ); lhs.add( "Is" ); lhs.add( "Very helpful" ); // Traversing elements Iterator<String> itr = lhs.iterator(); while (itr.hasNext()) { System.out.println(itr.next()); } } } |
Geeks For Is Very helpful
7. 排序集接口 : 该接口与set接口非常相似。唯一的区别是,这个接口有额外的方法来维护元素的顺序。排序集接口扩展了集合接口,用于处理需要排序的数据。实现这个接口的类是TreeSet。由于这个类实现了SortedSet,我们可以用这个类实例化SortedSet对象。例如
SortedSet
ts=新树集<>(); 其中T是对象的类型。
实现排序集接口的类是TreeSet。 树集: TreeSet类使用树进行存储。无论是否提供显式比较器,元素的顺序都由一组使用其自然顺序来维持。如果要正确实现Set接口,这必须与equals一致。它也可以由设置创建时提供的比较器进行排序,具体取决于使用的构造函数。让我们用一个例子来理解TreeSet:
JAVA
// Java program to demonstrate the // working of a TreeSet import java.util.*; public class TreeSetDemo { // Main Method public static void main(String args[]) { // Creating TreeSet and // adding elements TreeSet<String> ts = new TreeSet<String>(); ts.add( "Geeks" ); ts.add( "For" ); ts.add( "Geeks" ); ts.add( "Is" ); ts.add( "Very helpful" ); // Traversing elements Iterator<String> itr = ts.iterator(); while (itr.hasNext()) { System.out.println(itr.next()); } } } |
For Geeks Is Very helpful
8. 地图界面 : 映射是支持数据的键值对映射的数据结构。此接口不支持重复密钥,因为同一密钥不能有多个映射。如果有数据,并且我们希望根据密钥执行操作,则地图很有用。这个映射接口由不同的类实现,比如 哈希图 , 树图 因为所有的子类都实现了映射,所以我们可以用这些类中的任何一个实例化一个映射对象。例如
Map
hm=新HashMap<>(); Map tm=newtreemap<>(); 其中T是对象的类型。
映射接口的常用实现是HashMap。 哈希图 : HashMap提供了Java映射接口的基本实现。它以(键、值)对的形式存储数据。要访问HashMap中的值,我们必须知道它的键。HashMap使用一种称为哈希的技术。散列是一种将大字符串转换为代表同一字符串的小字符串的技术,以便索引和搜索操作更快。HashSet还在内部使用HashMap。让我们用一个例子来理解HashMap:
JAVA
// Java program to demonstrate the // working of a HashMap import java.util.*; public class HashMapDemo { // Main Method public static void main(String args[]) { // Creating HashMap and // adding elements HashMap<Integer, String> hm = new HashMap<Integer, String>(); hm.put( 1 , "Geeks" ); hm.put( 2 , "For" ); hm.put( 3 , "Geeks" ); // Finding the value for a key System.out.println( "Value for 1 is " + hm.get( 1 )); // Traversing through the HashMap for (Map.Entry<Integer, String> e : hm.entrySet()) System.out.println(e.getKey() + " " + e.getValue()); } } |
Value for 1 is Geeks 1 Geeks 2 For 3 Geeks