JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)
目录
一、Java 集合框架体系
1.Collection接口:用于存储一个一个的数据,也称单列数据集合(single)。
2.Map接口:用于存储具有映射关系“key-value对”的集合(couple)
3.Iterator接口:不提供存储对象的能力,主要用于遍历Collection中的元素
二、Iterator(迭代器)接口
1.常用方法
2.foreach循环
三、Collection接口及方法
1.添加方法
2.判断方法
3.删除方法
4.其他方法
四、 Collection子接口1:List
1.List接口特点
2.List接口方法
3.List接口主要实现类之一:ArrayList
4.List的实现类之二:LinkedList
5.List的实现类之三:Vector
五、Collection子接口2:Set
详解(如果你有疑问,可跳转到另一篇文章查看)
1.Set接口概述
2.Set主要实现类:HashSet
HashSet概述:
方法:
示例:
3.Set主要实现类二:LinkedHashSet
与HashSet相比,LinkedHashSet有以下特点:
4.Set实现类之三:TreeSet
1.TreeSet概述
常用方法:
六、总结
List接口的实现类特点:
Set接口的实现类特点:
下一篇:Map接口及子实现类,Collections工具类
一、Java 集合框架体系
1.Collection接口:用于存储一个一个的数据,也称单列数据集合(single)
。
-
List子接口:用来存储有序的、可以重复的数据(主要用来替换数组,"动态"数组)
-
实现类:ArrayList(主要实现类)、LinkedList、Vector
-
-
Set子接口:用来存储无序的、不可重复的数据(类似于高中讲的"集合")
-
实现类:HashSet(主要实现类)、LinkedHashSet、TreeSet
-
2.Map接口:用于存储具有映射关系“key-value对”的集合(couple)
-
HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtable、Properties
3.Iterator
接口:不提供存储对象的能力,主要用于遍历
Collection中的元素
二、Iterator(迭代器)接口
1.常用方法
方法 | 描述 |
---|---|
public Iterator iterator() | 获取集合对应的迭代器,用来遍历集合中的元素 |
public E next() | 返回迭代的下一个元素 |
public boolean hasNext() | 如果仍有元素可以迭代,则返回 true |
void remove() | 从集合中删除迭代器返回的最后一个元素(可选操作) |
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");Iterator<String> iterator = list.iterator(); // 获取迭代器while(iterator.hasNext()) {String element = iterator.next(); // 获取下一个元素System.out.println(element);
}
输出:
apple
banana
orange
2.foreach循环
-
foreach循环的语法格式:
for(元素的数据类型 局部变量 : Collection集合或数组){ //操作局部变量的输出操作
}
//这里局部变量就是一个临时变量,自己命名就可以
-
对于集合的遍历,增强for的内部原理其实是个Iterator迭代器。如下图。
当编译器遇到增强for循环时,会自动生成一个与该集合对应的迭代器,并使用迭代器来迭代集合中的元素。在每次循环中,编译器会自动调用迭代器的next()
方法获取下一个元素,并将其赋值给element
变量。当集合中没有更多元素时,迭代器的hasNext()
方法会返回false
,循环结束。
- 它用于遍历Collection和数组。通常只进行遍历元素,不能在遍历的过程中对集合元素进行增删操作。
public class Test {public static void main(String[] args) {String[] str ={"aa","bb", "cc", "dd", "ee"};for (String myStr : str) {myStr = "wrong";System.out.println(myStr);}for (int i = 0; i < str.length; i++) {System.out.println(str[i]);}}
}
wrong
wrong
wrong
wrong
wrong
aa
bb
cc
dd
ee
三、Collection接口及方法
1.添加方法
add(E obj) | 添加元素对象到当前集合中 |
addAll(Collection other) | 添加other集合中的所有元素对象到当前集合中,即this = this ∪ other |
public class Test {public static void main(String[] args) {testAdd();testAddAll();}public static void testAdd(){//ArrayList是Collection的子接口List的实现类之一。//因为Collection是一个接口,而不是一个具体的类,不能直接被实例化。在Java中,接口是一种抽象类型,只定义了接口的方法声明,而没有具体的实现。//因此,我们不能通过"new Collection()"来创建一个Collection对象。//相反,ArrayList是Collection接口的一个具体实现类,它提供了对一个动态大小的数组的操作方法。//所以,我们可以使用"new ArrayList()"来创建一个ArrayList对象,并将其赋值给Collection类型的变量coll。//可以根据需要选择不同的类作为接口的实现类,因为接口可以有多个实现类Collection coll = new ArrayList();coll.add("486");coll.add("艾米莉亚");coll.add("蕾姆");System.out.println(coll);}public static void testAddAll(){Collection c1 = new ArrayList();c1.add(1);c1.add(2);System.out.println("c1集合元素的个数:" + c1.size());//2System.out.println("c1 = " + c1);Collection c2 = new ArrayList();c2.add(1);c2.add(2);System.out.println("c2集合元素的个数:" + c2.size());//2System.out.println("c2 = " + c2);Collection other = new ArrayList();other.add(1);other.add(2);other.add(3);System.out.println("other集合元素的个数:" + other.size());//3System.out.println("other = " + other);System.out.println();c1.addAll(other);System.out.println("c1集合元素的个数:" + c1.size());//5System.out.println("c1.addAll(other) = " + c1);c2.add(other);System.out.println("c2集合元素的个数:" + c2.size());//3System.out.println("c2.add(other) = " + c2);}
}
输出:
[486, 艾米莉亚, 蕾姆]
c1集合元素的个数:2
c1 = [1, 2]
c2集合元素的个数:2
c2 = [1, 2]
other集合元素的个数:3
other = [1, 2, 3]c1集合元素的个数:5
c1.addAll(other) = [1, 2, 1, 2, 3]
c2集合元素的个数:3
c2.add(other) = [1, 2, [1, 2, 3]]
2.判断方法
方法名 | 方法描述 |
---|---|
int size() | 获取当前集合中实际存储的元素个数 |
boolean isEmpty() | 判断当前集合是否为空集合 |
boolean contains(Object obj) | 判断当前集合中是否存在一个与obj对象equals返回true的元素 |
boolean containsAll(Collection coll) | 判断coll集合中的元素是否在当前集合中都存在。即coll集合是否是当前集合的“子集” |
boolean equals(Object obj) | 判断当前集合与obj是否相等 |
区分: contains与 containsAll
public class Test {public static void main(String[] args) {Collection c1 = new ArrayList();c1.add(1);c1.add(2);System.out.println("c1集合元素的个数:" + c1.size());//2System.out.println("c1 = " + c1);Collection c2 = new ArrayList();c2.add(1);c2.add(2);System.out.println("c2集合元素的个数:" + c2.size());//2System.out.println("c2 = " + c2);Collection other = new ArrayList();other.add(1);other.add(2);other.add(3);System.out.println("other集合元素的个数:" + other.size());//3System.out.println("other = " + other);System.out.println();c1.addAll(other);System.out.println("c1集合元素的个数:" + c1.size());//5System.out.println("c1.addAll(other) = " + c1);System.out.println("c1.contains(other) = " + c1.contains(other));System.out.println("c1.containsAll(other) = " + c1.containsAll(other));System.out.println();c2.add(other);System.out.println("c2集合元素的个数:" + c2.size());System.out.println("c2.add(other) = " + c2);System.out.println("c2.contains(other) = " + c2.contains(other));System.out.println("c2.containsAll(other) = " + c2.containsAll(other));}
}
输出:
c1集合元素的个数:2
c1 = [1, 2]
c2集合元素的个数:2
c2 = [1, 2]
other集合元素的个数:3
other = [1, 2, 3]c1集合元素的个数:5
c1.addAll(other) = [1, 2, 1, 2, 3]
c1.contains(other) = false
c1.containsAll(other) = truec2集合元素的个数:3
c2.add(other) = [1, 2, [1, 2, 3]]
c2.contains(other) = true
c2.containsAll(other) = false
3.删除方法
方法 | 描述 |
---|---|
void clear() | 清空集合元素 |
boolean remove(Object obj) | 从当前集合中删除第一个找到的与obj对象equals返回true的元素。 |
boolean removeAll(Collection coll) | 从当前集合中删除所有与coll集合中相同的元素。即this = this - this ∩ coll |
boolean retainAll(Collection coll) | 从当前集合中删除两个集合中不同的元素,使得当前集合仅保留与coll集合中的元素相同的元素,即当前集合中仅保留两个集合的交集,即this = this ∩ coll; |
区别 :removeAll和retainAll
public class Test {public static void main(String[] args) {Collection coll = new ArrayList();coll.add("486");coll.add("艾米莉亚");coll.add("蕾姆");coll.add("拉姆");System.out.println("coll = " + coll);Collection other = new ArrayList();other.add("艾米莉亚");other.add("蕾姆");other.add("拉姆");System.out.println("other = " + other);coll.retainAll(other);System.out.println("coll.retainAll(other)之后,coll = " + coll);System.out.println("coll.retainAll(other)之后,other = " + other);System.out.println();Collection coll1 = new ArrayList();coll1.add("486");coll1.add("艾米莉亚");coll1.add("蕾姆");coll1.add("拉姆");System.out.println("coll1 = " + coll1);Collection other1 = new ArrayList();other1.add("艾米莉亚");other1.add("蕾姆");other1.add("拉姆");System.out.println("other1 = " + other1);coll1.removeAll(other1);System.out.println("coll1.removeAll(other1)之后,coll1 = " + coll1);System.out.println("coll1.removeAll(other1)之后,other1 = " + other1);}
}
输出:
coll = [486, 艾米莉亚, 蕾姆, 拉姆]
other = [艾米莉亚, 蕾姆, 拉姆]
coll.retainAll(other)之后,coll = [艾米莉亚, 蕾姆, 拉姆]
coll.retainAll(other)之后,other = [艾米莉亚, 蕾姆, 拉姆]coll1 = [486, 艾米莉亚, 蕾姆, 拉姆]
other1 = [艾米莉亚, 蕾姆, 拉姆]
coll1.removeAll(other1)之后,coll1 = [486]
coll1.removeAll(other1)之后,other1 = [艾米莉亚, 蕾姆, 拉姆]
4.其他方法
方法名 | 功能描述 |
---|---|
toArray() | 返回包含当前集合中的一个Object[] 类型的数组(集合转数组) |
toArray(T[] a) | 将集合转换为指定类型的数组,并将集合元素存储到指定的数组中。 |
asList() | 数组转集合 |
hashCode() | 获取集合对象的哈希值 |
iterator() | 返回迭代器对象,用于集合遍历 |
public class Test {public static void main(String[] args) {System.out.println("集合转数组遍历1:");Collection<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");Object[] str = list.toArray();for (Object s: str) {System.out.println(s);}System.out.println("集合转数组遍历2:");String[] str2 = new String[list.size()];String[] array = list.toArray(str2);for (String s: array) {System.out.println(s);}System.out.println("数组转集合迭代器遍历:");String[] str1 = {"dd","ee","ff"};Collection<String> list1 = Arrays.asList(str1);Iterator<String> iterator = list1.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}
集合转数组遍历1:
aaa
bbb
ccc
集合转数组遍历2:
aaa
bbb
ccc
数组转集合迭代器遍历:
dd
ee
ff
四、 Collection子接口1:List
1.List接口特点
-
鉴于Java中数组用来存储数据的局限性,我们通常使用
java.util.List
替代数组 -
List集合类中
元素有序
、且可重复
,集合中的每个元素都有其对应的顺序索引(从0开始)。
2.List接口方法
功能 | 方法 | 描述 |
---|---|---|
插入元素 | void add(int index, Object ele) | 在index位置插入ele元素 |
boolean addAll(int index, Collection eles) | 从index位置开始将eles中的所有元素添加进来 | |
获取元素 | Object get(int index) | 获取指定index位置的元素 |
List subList(int fromIndex, int toIndex) | 返回从fromIndex到toIndex位置的子集合 | |
获取元素索引 | int indexOf(Object obj) | 返回obj在集合中首次出现的位置 |
int lastIndexOf(Object obj) | 返回obj在当前集合中末次出现的位置 | |
删除和替换元素 | Object remove(int index) | 移除指定index位置的元素,并返回此元素 |
Object set(int index, Object ele) | 设置指定index位置的元素为ele |
3.List接口主要实现类之一:ArrayList
-
ArrayList 是 List 接口的
主要实现类
-
本质上,ArrayList是对象引用的一个”变长”数组,允许重复和空元素
-
当添加或删除元素时,
ArrayList
会自动调整数组的大小以容纳新的元素或释放对应的空间。 -
Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合
ArrayList方法:ArrayList (Java SE 11 & JDK 11 ) (runoob.com)
4.List的实现类之二:LinkedList
-
实现了
List
接口和Deque
接口,对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高。这是由底层采用链表(双向链表)结构存储数据决定的。 - LinkedList方法:LinkedList (Java SE 11 & JDK 11 ) (runoob.com)
特有方法:
方法名 | 功能描述 | 返回值类型 |
---|---|---|
addFirst(Object obj) | 将指定的元素作为列表的第一个元素插入。如果列表为空,则该元素也将成为最后一个元素。 | void |
addLast(Object obj) | 将指定的元素作为列表的最后一个元素插入。如果列表为空,则该元素也将成为第一个元素。 | void |
getFirst() | 返回列表中的第一个元素,但不会移除它。 | Object |
getLast() | 返回列表中的最后一个元素,但不会移除它。 | Object |
removeFirst() | 移除并返回列表中的第一个元素。 | Object |
removeLast() | 移除并返回列表中的最后一个元素。 | Object |
5.List的实现类之三:Vector
-
Vector 是一个
古老
的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全
的。 -
在各种List中,最好把
ArrayList作为默认选择
。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。 -
特有方法:
方法名称 | 方法描述 |
---|---|
addElement(Object obj) | 将指定的元素添加到此向量的末尾。 |
insertElementAt(Object obj, int index) | 在指定的索引处插入指定的元素。原来在该位置和所有后续元素上的元素都向右移动。 |
setElementAt(Object obj, int index) | 将指定索引处的元素设置为指定的对象。 |
removeElement(Object obj) | 从向量中移除指定的元素。如果存在多个匹配的元素,则只移除第一个匹配的元素。 |
removeAllElements() | 从向量中移除所有元素。 |
五、Collection子接口2:Set
1.Set接口概述
-
Set接口是Collection的子接口,Set接口相较于Collection接口没有提供额外的方法
-
Set 集合不允许包含相同的Value,如果试把两个相同的Value加入同一个 Set 集合中,则添加操作失败。因为Set集合是基于哈希表的一种数据结构,在插入元素时会根据元素的哈希值进行判断和处理,确保集合中没有重复的元素。
-
Set集合支持的遍历方式和Collection集合一样:foreach和Iterator。
-
Set的常用实现类有:HashSet、TreeSet、LinkedHashSet。
2.Set主要实现类:HashSet
详解(如果你想了解更多,可跳转到另一篇文章查看)
HashSet概述:
-
无序性:HashSet中的元素是无序的,不会按照插入的顺序进行存储和访问。
-
不可重复性:HashSet中的元素是唯一的,不会存在重复的元素。这是通过哈希表的机制来实现的。
-
允许存储null值:HashSet允许存储一个null元素。
-
内部实现机制:HashSet基于哈希表实现,使用了哈希函数来计算元素的存储位置,所以HashSet集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的hash值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。
-
HashSet 集合
判断两个元素相等的标准
:两个对象通过hashCode()
方法得到的哈希值相等,并且两个对象的equals()
方法返回值为true。 -
对于存放在Set容器中的对象,对应的类一定要重写hashCode()和equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
-
HashSet集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的hash值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。
HashSet方法:HashSet (Java SE 11 & JDK 11 ) (runoob.com)
方法:
方法 | 描述 |
---|---|
boolean add(E e) | 如果指定的元素尚不存在,则将其添加到此集合中。 |
void clear() | 从该集中删除所有元素。 |
boolean contains(Object o) | 如果此 set 包含指定的元素,则返回 true。 |
boolean isEmpty() | 如果此集合不包含任何元素,则返回 true。 |
Iterator<E> iterator() | 返回此 set 中元素的迭代器。 |
boolean remove(Object o) | 如果存在,则从该集合中移除指定的元素。 |
int size() | 返回此集合中的元素数(基数)。 |
示例:
去除重复数字值:
public static List duplicateList(List a) {HashSet set = new HashSet();set.addAll(a);return new ArrayList(set);}public static void main(String[] args) {Integer[] array = {1, 1, 3, 4, 4};// 将数组转换为集合List<Integer> list = Arrays.asList(array);//list转为set达到去重的效果List list2 = duplicateList(list);for (Object integer : list2) {System.out.println(integer);}}
3.Set主要实现类二:LinkedHashSet
LinkedHashSet是Java集合框架中的一种集合实现,它继承自HashSet类,它根据元素的 hashCode 值来决定元素的存储位置,同时使用一个双向链表维护元素的插入顺序。
与HashSet相比,LinkedHashSet有以下特点:
-
保持插入顺序:LinkedHashSet保持了元素的插入顺序。当我们向LinkedHashSet中添加元素时,它们会按照添加的顺序被保存,并且在遍历时按照相同的顺序返回。这使得LinkedHashSet非常适合于需要按照元素的插入顺序进行遍历或组织的场景。
-
高效的查找操作:与HashSet一样,LinkedHashSet使用哈希表实现元素的存储,因此查找元素的效率很高。在大多数查找操作中,LinkedHashSet的性能与HashSet相当。
-
相对较高的存储开销:由于LinkedHashSet需要维护元素插入顺序,它需要额外的存储空间来维护链表。因此,相对于HashSet,LinkedHashSet在存储方面稍微占用更多的内存。
public class Test {public static void main(String[] args) {LinkedHashSet set = new LinkedHashSet<>();// 添加元素set.add("apple");set.add(1);set.add(2);set.add('e');set.add(0.14159);// 遍历集合for (Object element : set) {System.out.println(element);}// 判断元素是否存在boolean contains = set.contains(2 );System.out.println("Contains '2': " + contains);// 移除元素boolean removed = set.remove(1);System.out.println("Removed '1': " + removed);//按添加时的顺序输出System.out.println(set);}
}
输出:
apple
1
2
e
0.14159
Contains '2': true
Removed '1': true
[apple, 2, e, 0.14159]
4.Set实现类之三:TreeSet
1.TreeSet概述
-
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以按照添加的元素的指定的属性的大小顺序进行遍历。
-
TreeSet底层使用
红黑树
结构存储数据 -
TreeSet特点:不允许重复、实现排序(自然排序或定制排序)
-
TreeSet 两种排序方法:
自然排序
和定制排序
。默认情况下,TreeSet 采用自然排序。-
自然排序
:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。-
如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。
-
实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
-
-
定制排序
:如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。-
利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
-
要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。
-
-
-
因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是
同一个类的对象
。
常用方法:
方法 | 描述 |
---|---|
add(E e) | 向TreeSet中添加指定的元素。 |
addAll(Collection<? extends E> c) | 将指定集合中的所有元素添加到TreeSet中。 |
clear() | 从TreeSet中移除所有元素。 |
contains(Object o) | 检查TreeSet中是否包含指定的元素。 |
first() | 返回TreeSet中的第一个(最小)元素。 |
last() | 返回TreeSet中的最后一个(最大)元素。 |
isEmpty() | 检查TreeSet是否为空。 |
remove(Object o) | 从TreeSet中移除指定的元素。 |
size() | 返回TreeSet中的元素数量。 |
iterator() | 返回在TreeSet中元素上进行迭代的迭代器。 |
subSet(E fromElement, E toElement) | 返回一个子集,包括从fromElement(包括)到toElement(不包括)的所有元素。 |
headSet(E toElement) | 返回一个子集,包括小于toElement的所有元素。 |
tailSet(E fromElement) | 返回一个子集,包括大于等于fromElement的所有元素。 |
ceiling(E e) | 返回TreeSet中大于或等于给定元素e的最小元素。 |
floor(E e) | 返回TreeSet中小于或等于给定元素e的最大元素。 |
示例:创建了一个自定义的比较器AgeComparator
,它比较Student对象的年龄属性。然后将该比较器传递给TreeSet的构造函数,使得集合按照学生的年龄进行排序。
import java.util.Comparator;
import java.util.TreeSet;public class TreeSetObjectPropertyOrderingExample {public static void main(String[] args) {TreeSet<Student> set = new TreeSet<>(new AgeComparator());// 添加学生对象set.add(new Student("Alice", 20));set.add(new Student("Bob", 18));set.add(new Student("Charlie", 22));// 遍历集合(按照年龄排序)for (Student student : set) {System.out.println(student.getName() + " : " + student.getAge());}}
}class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}
}class AgeComparator implements Comparator<Student> {@Overridepublic int compare(Student s1, Student s2) {return Integer.compare(s1.getAge(), s2.getAge());}
}
其中:
(new LengthComparator())
是创建一个比较器的实例,并将其作为参数传递给构造函数的简写方式,允许在创建TreeSet时即刻创建并传递一个比较器。
如果你更容易理解完整的步骤,可以按照下面的方式进行:
- 首先,你需要创建一个实现了
Comparator
接口的类,该接口指定了比较器的行为。
class LengthComparator implements Comparator<String> {@Overridepublic int compare(String s1, String s2) {return Integer.compare(s1.length(), s2.length());//如果s1.length()小于s2.length(),则返回负整数值。//如果s1.length()等于s2.length(),则返回0。//如果s1.length()大于s2.length(),则返回正整数值。}
}
- 接下来,你可以实例化比较器的对象:
Comparator<String> lengthComparator = new LengthComparator();
- 然后,你可以使用该比较器对象创建TreeSet对象,并传递比较器对象作为参数:
TreeSet<String> set = new TreeSet<>(lengthComparator);
综合以上三步,你可以用下面的代码来替代 (new LengthComparator())
这样的写法:
Comparator<String> lengthComparator = new LengthComparator();
TreeSet<String> set = new TreeSet<>(lengthComparator);
这样更详细的写法可能更容易理解,但是对于简单的比较器,可以直接在构造函数中使用new 比较器类名()
的方式来创建并传递比较器对象。
输出:
Bob : 18
Alice : 20
Charlie : 22
六、总结
List接口的实现类特点:
- ArrayList:基于数组实现,支持随机访问和快速的插入/删除操作。适用于频繁访问元素和对元素进行插入和删除的场景,但不适用于频繁的插入和删除操作。
- LinkedList:基于链表实现,支持高效的插入/删除操作和快速的查找操作。适用于频繁插入和删除元素的场景,但访问元素性能相对较低。
LinkedList
还实现了Deque
接口,它提供了一系列特殊的链表操作,例如添加/删除首尾元素、获取首尾元素等。 - Vector:与ArrayList类似,但是是线程安全的(采用同步机制)。
ArrayList
和LinkedList
是不安全的,这意味着它们在多线程环境下不能保证线程安全。如果多个线程同时修改一个ArrayList
或LinkedList
实例,可能会导致数据不一致或出现并发访问异常。因此,在多线程环境下使用时,需要使用额外的同步机制来保证线程安全,例如使用Collections.synchronizedList
等方法或使用并发集合类CopyOnWriteArrayList
等。
Vector
是线程安全的,它对其方法进行了同步化,以保证多线程环境下的安全访问。这意味着多个线程可以安全地同时修改一个Vector
实例,而不会导致数据不一致或出现并发访问异常。然而,这种同步化会带来额外的开销,可能导致在性能上略有劣势。
在Java 1.2版本之后,引入了更高效的并发集合类,如ConcurrentHashMap
、ConcurrentLinkedDeque
和CopyOnWriteArrayList
,它们提供了更好的线程安全性和性能。因此,在现代的Java应用程序中,通常建议使用这些并发集合类来替代Vector
、ArrayList
和LinkedList
。
Set接口的实现类特点:
- 它们在多线程环境下都不能保证线程安全
- HashSet:基于哈希表实现,不保证元素的顺序,并且不可重复。查找元素速度快,但无法保持元素的顺序。
- LinkedHashSet:基于链表和哈希表实现,使用一个双向链表维护元素的插入顺序。相比HashSet,插入和删除操作稍慢一些,但仍然较快。
- TreeSet:基于红黑树实现,能够保持元素的有序性。插入和删除操作的性能较慢,但查找元素和按序访问元素的性能非常高。
List接口提供了有序的、可重复的集合,适用于需要保持元素插入顺序或允许重复元素的场景。Set接口提供了无序的、不可重复的集合,适用于需要确保元素唯一性和不关心元素顺序的场景。
需要根据实际需求选择合适的List和Set实现类。如果需要频繁插入和删除元素,可以选择LinkedList和HashSet。如果需要高效的随机访问和根据元素顺序迭代,可以选择ArrayList和LinkedHashSet。如果需要有序集合,可以选择TreeSet或LinkedHashSet。
方法总结:
List接口方法
功能 | 方法 | 描述 |
---|---|---|
插入元素 | void add(int index, Object ele) | 在index位置插入ele元素 |
boolean addAll(int index, Collection eles) | 从index位置开始将eles中的所有元素添加进来 | |
获取元素 | Object get(int index) | 获取指定index位置的元素 |
List subList(int fromIndex, int toIndex) | 返回从fromIndex到toIndex位置的子集合 | |
获取元素索引 | int indexOf(Object obj) | 返回obj在集合中首次出现的位置 |
int lastIndexOf(Object obj) | 返回obj在当前集合中末次出现的位置 | |
删除和替换元素 | Object remove(int index) | 移除指定index位置的元素,并返回此元素 |
Object set(int index, Object ele) | 设置指定index位置的元素为ele |
LinkedList实现类方法:
Vector实现类方法:
HashSet实现类方法:
方法 | 描述 |
---|---|
boolean add(E e) | 如果指定的元素尚不存在,则将其添加到此集合中。 |
void clear() | 从该集中删除所有元素。 |
boolean contains(Object o) | 如果此 set 包含指定的元素,则返回 true。 |
boolean isEmpty() | 如果此集合不包含任何元素,则返回 true。 |
Iterator<E> iterator() | 返回此 set 中元素的迭代器。 |
boolean remove(Object o) | 如果存在,则从该集合中移除指定的元素。 |
int size() | 返回此集合中的元素数(基数)。 |
Tree实现类方法
方法 | 描述 |
---|---|
add(E e) | 向TreeSet中添加指定的元素。 |
addAll(Collection<? extends E> c) | 将指定集合中的所有元素添加到TreeSet中。 |
clear() | 从TreeSet中移除所有元素。 |
contains(Object o) | 检查TreeSet中是否包含指定的元素。 |
first() | 返回TreeSet中的第一个(最小)元素。 |
last() | 返回TreeSet中的最后一个(最大)元素。 |
isEmpty() | 检查TreeSet是否为空。 |
remove(Object o) | 从TreeSet中移除指定的元素。 |
size() | 返回TreeSet中的元素数量。 |
iterator() | 返回在TreeSet中元素上进行迭代的迭代器。 |
subSet(E fromElement, E toElement) | 返回一个子集,包括从fromElement(包括)到toElement(不包括)的所有元素。 |
headSet(E toElement) | 返回一个子集,包括小于toElement的所有元素。 |
tailSet(E fromElement) | 返回一个子集,包括大于等于fromElement的所有元素。 |
ceiling(E e) | 返回TreeSet中大于或等于给定元素e的最小元素。 |
floor(E e) | 返回TreeSet中小于或等于给定元素e的最大元素。 |
相关文章:
![](https://img-blog.csdnimg.cn/30e51a0a47184da593b2c3db11009286.png)
JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)
目录 一、Java 集合框架体系 1.Collection接口:用于存储一个一个的数据,也称单列数据集合(single)。 2.Map接口:用于存储具有映射关系“key-value对”的集合(couple) 3.Iterator接口&#…...
![](https://img-blog.csdnimg.cn/251fed9f416647918661abaced8765b8.png)
python ffmpeg合并ts文件
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:点击跳转 当你从网站下载了一集动漫,然后发现是一堆ts文件,虽然可以打开,但是某个都是10秒左右,…...
![](https://img-blog.csdnimg.cn/681f66d3e62041589109ea70c5f43c89.png#pic_center)
c++map和set剖析
文章参考文献:cplusplus 博主:拖拉机厂第一代码手 gitee:拖拉机厂第一代码手 c专栏:C 目录 🧙🏼♂set剖析🧚🏼set简介🧚🏼set模板参数列表🧚🏼s…...
![](https://www.ngui.cc/images/no-images.jpg)
kubernetes configmap 的data中的文件内容格式错乱
截取一段错乱的配置: kubectl -n monitoring get cm blackbox-exporter-configuration -o yaml apiVersion: v1 data:config.yml: "\"modules\":\n \"http_2xx\":\n \"http\":\n \"preferred_ip_protocol\"…...
![](https://www.ngui.cc/images/no-images.jpg)
A TupleBackedMap cannot be modified Mybatis分页,使用List<Map>接参,无法修改map的解决方案
问题描述 当使用Mybatis 进行Page分页,再使用Page< map >作为接受参数。此时尝试修改map则会报错。 报错为 java.lang.UnsupportedOperationException: A TupleBackedMap cannot be modified解决方案 使用新的数组,使用反射,构建工具…...
![](https://img-blog.csdnimg.cn/9b41a4c68ad842b682a0bc603a4dc42b.png)
Leetcode-每日一题【剑指 Offer 13. 机器人的运动范围】
题目 地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例…...
![](https://img-blog.csdnimg.cn/c57ddc3bf8a04534ac21f121b5bf2d5f.png)
WEB集群——负载均衡集群
目录 一、 LVS-DR 群集。 1、LVS-DR工作原理 2、LVS-DR模式的特点 3、部署LVS-DR集群 3.1 配置负载调度器(192.168.186.100) 3.2 第一台web节点服务器(192.168.186.103) 3.3 第二台web节点服务器(192.168.186.…...
![](https://img-blog.csdnimg.cn/a1946f8723a04745aabdacc014354690.png)
ubuntu 20.0.4 搭建nvidia 显卡环境
一、安装docker 1、安装dokcer sudo apt install docker.io2、docker 添加到用户组 创建docker用户组 sudo groupadd docker添加当前用户加入docker用户组 sudo usermod -aG docker ${USER}重启docker服务 sudo systemctl restart docker切换或者退出当前账户再从新登入 …...
![](https://img-blog.csdnimg.cn/dba48936da934d9d8f9fe1478fbc35b5.png)
Windows环境下通过 系统定时 执行脚本方式 压缩并备份文件夹 到其他数据盘
环境配置 压缩时需要使用7-zip进行调用,因此根据自己电脑进行安装 官网:https://www.7-zip.org/ 脚本文件 新建记事本文件,重命名为git_back_up.bat echo off rem 设置utf-8可以正常显示中文 chcp 65001 > nulrem 获取当前日期和时间&…...
![](https://www.ngui.cc/images/no-images.jpg)
C++系列二:STL教程-常用算法
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 常用算法 前言算法列举:算法例子 前言 还有一些我在尝试中迷惑不解的,有点玄幻。 算法列举: 排序算法: sort(first, last);…...
![](https://img-blog.csdnimg.cn/183c1a182be442e2a46406b921758642.png)
【css】渐变
渐变是设置一种颜色或者多种颜色之间的过度变化。 两种渐变类型: 线性渐变(向下/向上/向左/向右/对角线) 径向渐变(由其中心定义) 1、线性渐变 语法:background-image: linear-gradient(direction, co…...
![](https://img-blog.csdnimg.cn/4d4f04c5cf8c4b58b81a2bc0b5d5c3b7.png)
idea打开多个项目需要开多个窗口(恢复询问弹窗)
【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】【创作不易,点个赞就是对我最大的支持】 前言 仅作为学习笔记,供大家参考 总结的不错的话,记得点赞收藏关注哦! 使用…...
![](https://www.ngui.cc/images/no-images.jpg)
篇十三:策略模式:选择不同算法
篇十三:“策略模式:选择不同算法” 设计模式是软件开发中的重要知识,策略模式(Strategy Pattern)是一种行为型设计模式,用于在运行时根据不同的需求选择不同的算法或行为。本文将探讨策略模式的作用和实现…...
![](https://img-blog.csdnimg.cn/22fe512ffcb340fc8a8cd7be1a0f0c89.png)
Centos7.6 安装mysql过程全记录
在centos 7.6上 离线安装mysql 的步骤,可参考下文: 一、查看当前MySQL的安装情况并卸载 1. 查看当前MySQL的安装情况 查找之前是否安装了MySQL rpm -qa|grep -i mysql 2.卸载mysql 如果已经安装mysql,则需要先停止MySQL,再删除…...
![](https://www.ngui.cc/images/no-images.jpg)
Java中的Guava是什么?
Java中的Guava是一个非常强大的Java库,它提供了很多实用的工具类和方法,可以帮助我们更高效地开发Java应用程序。从新手的角度来看,Guava可以让我们在Java编程中变得更加简单、快速和高效。 Guava的命名来源于“Google’s favorite Java lib…...
![](https://www.ngui.cc/images/no-images.jpg)
vue.js兄弟组件方法调用b组件调用a组件方法
vue.js 中兄弟组件方法调用 场景:父组件中同时引入两个子组件(A和B),此时B组件点击按钮需要调用A组件里面的方法 方案1:vue的事件总线 方案2:自定义事件($emit) 最终方案:…...
![](https://www.ngui.cc/images/no-images.jpg)
【Kubernetes】二进制搭建
目录 二进制搭建 Kubernetes v1.20 操作系统初始化配置 关闭防火墙 关闭selinux 关闭swap 根据规划设置主机名 在master添加hosts 调整内核参数 时间同步 部署 etcd 集群 准备签发证书环境 准备cfssl证书生成工具 生成Etcd证书 上传 etcd-cert.sh 和 etcd.sh 到 …...
![](https://img-blog.csdnimg.cn/d07d1578c5394d4b8298faf2c87fe922.png)
【MFC】08.MFC消息,自定义消息,常用控件(MFC菜单创建大总结),工具栏,状态栏-笔记
本专栏上几篇文章讲解了MFC几大机制,今天带领大家学习MFC自定义消息以及常用控件,最常用的控件请查看本专栏第一二篇文章,今天这篇文章介绍工具栏,菜单和状态栏,以及菜单创建大总结。 文章目录 MFC消息分类࿱…...
![](https://img-blog.csdnimg.cn/7c75bc3c1c5b438e9c39e310bf3bfe63.png)
Clickhouse 数据存储
一、数据分区 数据是以分区目录的形式组织的,每个分区独立分开存储.这种形式,查询数据时,可以有效的跳过无用的数据文件。 1.1 数据分区的规则 分区键的取值,生成分区ID,分区根据ID决定。根据分区键的数据类型不同&am…...
![](https://img-blog.csdnimg.cn/35ccfe352f6f4bd8aca33bef12f9e40d.png)
c语言每日一练(3)
前言:每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情…...
![](https://www.ngui.cc/images/no-images.jpg)
java基础-Stream(流)、File(文件)和IO
Java中的流(Stream)提供了一个统一的接口来处理输入和输出数据,文件(File)提供了一种简单的方式来操作磁盘上的文件,而I/O则允许我们在Java程序中读写数据。 一、流Stream java中得stream是一种抽象概念,流可以从多种来源读取数据ÿ…...
![](https://img-blog.csdnimg.cn/73152f7b02cb4b8cb3a06c109adbb502.png)
el-table实现指定列合并
table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素…...
![](https://img-blog.csdnimg.cn/4442a5c932904f238fb9de2467462764.png)
38.利用matlab解 有约束无约束的参数估计对比(matlab程序)
1.简述 1.离散型随机变量的极大似然估计法: (1) 似然函数 若X为离散型, 似然函数为 (2) 求似然函数L(θ)的最大值点 θ, 则θ就是未知参数的极大似然估计值. 2.连续型随机变量的极大似然估计法: (1) 似然函数 若 X 为连续型, 似然函数为 (2) 求似然函数L(θ)的最大值点θ, 则…...
![](https://img-blog.csdnimg.cn/img_convert/02804f5495e489f5bdcfaf7444ab2d2f.png)
什么是React?React与VU的优缺点有哪些?
什么是React?什么是VUE? 维基百科上的概念解释,Vue.js是一个用于创建用户界面的开源MVVM前端JavaScript框架,也是一个创建单页应用的Web应用框架。Vue.js由尤雨溪(Evan You)创建,由他和其他活跃…...
![](https://img-blog.csdnimg.cn/af4fb42df61f484b87ebaa91482edcf6.png)
区块链技术助力慈善,为您的善举赋予全新力量!
我们怀揣着一颗温暖的心,秉承着公开透明的理念,带着信任与责任,倾力打造了一套区块链技术驱动的去中心化捐赠与物资分发系统,通过智能生态网络(IEN)解决捐赠不透明问题的系统,让您的善举直接温暖…...
![](https://img-blog.csdnimg.cn/2a3c5e7cf5b046b683f1adf03894b108.png)
模拟实现消息队列项目(系列4) -- 服务器模块(内存管理)
目录 前言 1. 创建MemoryDataCenter 2. 封装Exchange 和 Queue方法 3. 封装Binding操作 4. 封装Message操作 4.1 封装消息中心集合messageMap 4.2 封装消息与队列的关系集合queueMessageMap的操作 5. 封装未确认消息集合waitMessage的操作 6. 从硬盘中恢复数据到内存中 7. Memo…...
![](https://img-blog.csdnimg.cn/1069e5d70fdd4c6f8780d363d8a7a3a1.png)
STM32 LoRa源码解读
目录结构: SX1278 |-- include | |-- fifo.h | |-- lora.h | |-- platform.h | |-- radio.h | |-- spi.h | |-- sx1276.h | |-- sx1276Fsk.h | |-- sx1276FskMisc.h | |-- sx1276Hal.h | |-- sx1276LoRa.h | -- sx1276LoRaMisc.h – src |-- fifo.c |-- lora.c |-- …...
![](https://www.ngui.cc/images/no-images.jpg)
【BASH】回顾与知识点梳理(十)
【BASH】回顾与知识点梳理 十 十. 文件的格式化与相关处理10.1 格式化打印: printf10.2 awk:好用的数据处理工具awk 的逻辑运算字符 10.3 文件比对工具diffcmppatch 10.4 文件打印准备: pr 该系列目录 --> 【BASH】回顾与知识点梳理&#…...
![](https://img-blog.csdnimg.cn/dc37326249bc488aabd74b9b45f7b57e.png)
【网络】应用层——HTTPS协议
🐱作者:一只大喵咪1201 🐱专栏:《网络》 🔥格言:你只管努力,剩下的交给时间! HTTPS协议 🍉HTTP的不安全性🍉认识HTTPS协议🍓加密解密ἵ…...
![](https://img-blog.csdnimg.cn/1f47e03579a64ccf9065d12d4e56c932.png)
Windows新版文件资源管理器经常在后台弹出的临时解决方案
禁用组策略自动刷新 运行gpedit.msc找到计算机配置->管理模板->系统->组策略找到 “关闭组策略的后台刷新”启用 参考 https://answers.microsoft.com/en-us/windows/forum/all/windows-11-most-recently-opened-explorer-window/26e097bd-1eba-4462-99bd-61597b5…...
![](/images/no-images.jpg)
创建网站公司 徐州/怎么样推广自己的公司
问题:向正在编辑的Word文档中插入图片时,会发现图片只显示了部分,其余部分被其上面的问题遮挡住 原因:可能是由于设置固定的行间距,导致图片被遮挡 解决方法: 选定插入的图片,在菜单栏中找到 “…...
![](/images/no-images.jpg)
可以自己做网站的软件下载/搜索引擎优化排名seo
概述 因为买不起高速卡,所以只能使用普通的内存卡,但是又怕内存卡坏掉,而且内存卡只有8g容量太小,正好我有一个usb3.0接口的128g u盘,虽然树莓派不支持usb3.0,但是这样子做总比一张内存卡快 镜像的选择 我不…...
![](https://img-blog.csdnimg.cn/img_convert/3237964784bb0f6d6f59bf47020678a0.png)
功能网站开发/win7优化
很多新手电脑屏幕亮度不知道如何调整,这是一个非常重要的问题。电脑屏幕的亮度不仅关系到电脑的节能和使用寿命,而且对我们的眼睛也有很大的影响。很多游戏迷,上班族或学生,整天在哭眼睛疼,眼睛累,但又必须…...
![](https://www.oschina.net/img/hot3.png)
怎么给喜欢的人做网站/网络推广外包想手机蛙软件
2019独角兽企业重金招聘Python工程师标准>>> 8.10 shell特殊符号cut命令 8.11 sort_wc_uniq命令 8.12 tee_tr_split命令 8.13 shell特殊符号下 相关测验题目:http://ask.apelearn.com/question/5437 扩展 1. source exec 区别 http://alsww.blog.51cto.c…...
![](/images/no-images.jpg)
网站模板免费下载中文版/百度电话客服24小时
“计算机科学只存在两个难题:缓存失效和命名。” ——Phil KarIton 前言 命名一直是我编程过程中很头痛的事,有时为了一个恰当的名称是想了又想,还忍不住Google一下。命名真是一门艺术,好的命名那叫一个高大上。今天总结一些前端命…...
![](/images/no-images.jpg)
室内设计网站排行榜前十名知乎/全达seo
JPA进阶 一、主键生成策略 (一)主键实现的两种类型 1.自然主键 有业务含义的主键JPA不定义GeneratedValue就可以了 2.代理主键 没有意义,用来区别每行的数据是不同的 (二) 四种主键生成策略 1.IDENTITY 自增策…...