学习总纲:
Java 集合框架提供了一组接口和类,以实现各种数据结构和算法。
Java集合框架提供了可以直接使用的各种数据结构和算法。这有两个主要优点:
我们不需要手动编写代码来实现这些数据结构和算法。
随着集合框架的高度优化,我们的代码将更加高效。
此外,集合框架允许我们对特定类型的数据使用特定的数据结构。例如,
如果我们希望我们的数据是唯一的,那么我们可以使用集合框架提供的Set接口。
要以键/值对的形式存储数据,可以使用Map接口。
ArrayList类提供可调整大小的数组的功能
Collection 接口包括各种可用于对对象执行不同操作的方法。这些方法在其所有子接口中均可用。
List接口是一个有序的集合,它允许我们像数组一样添加和删除元素
由于List是接口,因此无法从中创建对象。
为了使用List接口的功能,我们可以使用以下类:
首先,使用这些集合框架的声明一般为:
//List 的ArrayList 实现
List<String> list1 = new ArrayList<>();
// List 的LinkedList 实现
List<String> list2 = new LinkedList<>();
此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性
为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类呢?,这时你只要改变这一行就行了:List list = new LinkedList();
其它使用了list地方的代码根本不需要改动。假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。
如果没有特别需求的话,最好使用List list = new LinkedList(); ,便于程序代码的重构. 这就是面向接口编程的好处
ArrayList类是List接口的实现,允许我们创建可调整大小的数组
它的常用方法:
study.list.add(28);
study.list.add(3,21);//这种方法add,它的下标不能跳跃。
animals.addAll(mammals);
import java.util.Arrays;//但是我们可以使用atList()来达到相同的目的
ArrayList<String> animals = new ArrayList<>(Arrays.asList("Cat", "Cow", "Dog"));
//从数组列表中获取元素
String str = animals.get(0);
import java.util.Iterator;
//创建一个Iterator对象
Iterator<String> iterate = animals.iterator();
//使用Iterator的方法访问元素
while(iterate.hasNext()){
System.out.print(iterate.next());
System.out.print(", ");
}
//更改数组列表的元素
animals.set(2, "Zebra");
//从索引2中删除元素
String str = animals.remove(2);
// 删除所有元素
animals.removeAll(animals);
//删除所有元素
animals.clear();
for(int i = 0; i < animals.size(); i++) {
System.out.print(animals.get(i));
System.out.print(", ");
}
//使用forEach循环
System.out.println("访问所有元素: ");
for(String animal : animals) {
System.out.print(animal);
System.out.print(", ");
}
//获取arrayList的大小
System.out.println("arrayList的大小: " + animals.size());
import java.util.Collections;
//对数组列表进行排序
Collections.sort(animals);
//将ArrayList转换成数组
animals.toArray(arr);//arr为应该转化成的数组
import java.util.Arrays;
String[] arr = {"Dog", "Cat", "Horse"};
ArrayList<String> animals = new ArrayList<>(Arrays.asList(arr));
String str = animals.toString();
Java堆栈Stack
类已经过时,Java官方推荐使用Deque
替代Stack
使用
Vector类是List接口的一个实现,它允许我们创建类似于ArrayList类的可调整大小的数组
由于向量(vector)不是线程安全的并且效率较低,因此建议使用ArrayList代替Vector
当我们要以先进先出(有输入输出次序)的方式存储和访问元素时,可以使用Queue接口
不知道为啥,队列这种集合好像很少被用到,可能是这种输入输出端受限的数据结构也可以用List实现。
使用方法和队列一样,但是它对入队的元素有排序(大小根堆),是用数组存放的,但是逻辑上是有顺序的。
在常规队列中,元素是从后面添加的,而从前面删除的。但是,在双端队列中,我们可以从前后插入和删除元素
push() - 在双端队列的开头添加元素
pop() - 从双端队列的开头删除元素
LinkedList的API boolean add(E object) void add(int location, E object) boolean addAll(Collection<? extends E> collection) boolean addAll(int location, Collection<? extends E> collection) void addFirst(E object) void addLast(E object) void clear() Object clone() boolean contains(Object object) Iterator<E> descendingIterator() E element() E get(int location) E getFirst() E getLast() int indexOf(Object object) int lastIndexOf(Object object) ListIterator<E> listIterator(int location) boolean offer(E o) boolean offerFirst(E e) boolean offerLast(E e) E peek() E peekFirst() E peekLast() E poll() E pollFirst() E pollLast() E pop() void push(E e) E remove() E remove(int location) boolean remove(Object object) E removeFirst() boolean removeFirstOccurrence(Object o) E removeLast() boolean removeLastOccurrence(Object o) E set(int location, E object) int size() <T> T[] toArray(T[] contents) Object[] toArray()
在Java中,我们可以使用ArrayDeque该类使用数组来实现队列和双端队列数据结构
Set接口允许我们将元素存储在不同的集合中,类似于数学中的集合。它不能有重复的元素
Java Set接口允许我们执行基本的数学集合运算,例如并集,交集和子集。
Union - 为了得到两个集合x和y的并集,我们可以使用x.addAll(y)
Intersection - 要获得两个集合x和y的交集,我们可以使用x.retainAll(y)
Subset - 要检查x是否是y的子集,我们可以使用y.containsAll(x)
Java Collections框架的HashSet类提供了哈希表数据结构的功能。
//具有8个容量和0.75负载因子的HashSet HashSet<Integer> numbers = new HashSet<>(8, 0.75);
也可以不传递参数初始化hashset,默认的容量为16,负载因子为0.75
要访问哈希集合的元素,我们可以使用iterator()方法。为了使用此方法,我们必须导入java.util.Iterator包
// 调用iterator()方法 Iterator<Integer> iterate = numbers.iterator(); System.out.print("使用Iterator的HashSet: "); //访问元素 while(iterate.hasNext()) { System.out.print(iterate.next()); System.out.print(", "); }
执行两个集合之间的并集,我们可以使用addAll()方法
numbers.addAll(evenNumbers); //就是在一个集合中加入另一个集合,由于集合元素的唯一性,实现了并的功能
要执行两个集合之间的交集,我们可以使用retainAll()方法
//集合的交集,即保存与新set共有的元素 evenNumbers.retainAll(primeNumbers);
要计算两组之间的差集,我们可以使用removeAll()方法
//HashSet1和HashSet2之间的差集 primeNumbers.removeAll(oddNumbers);
要检查一个集合是否是另一个集合的子集,我们可以使用containsAll()方法
//检查primeNumbers是否是numbers的子集 boolean result = numbers.containsAll(primeNumbers);
在Java中,如果我们必须随机访问元素,则通常使用HashSet。 这是因为哈希表中的元素是使用哈希码访问的。
元素的hashcode是唯一标识,它有助于标识散列表中的元素。
HashSet不能包含重复的元素。因此,每个散列集元素都有一个惟一的hashcode。
Map接口允许元素以键/值对的形式存储。键是唯一的名称,可用于访问map中的特定元素。而且,每个键都有一个与之关联的值
Map接口维护3个不同的集合:
键集
值集
键/值关联(Map集合)的集合。
因此,我们可以分别访问键,值和关联。
//使用HashMap类创建Map Map<Key, Value> numbers = new HashMap<>();
Map接口包括Collection接口的所有方法。这是因为Collection是Map的超级接口。
除了Collection接口中可用的方法之外,Map接口还包括以下方法:
put(K,V) - 将键K和值V的关联插入到map中。如果键已经存在,则新值将替换旧值。
putAll() - 将指定Map集合中的所有条目插入此Map集合中。
putIfAbsent(K,V) - 如果键K尚未与value关联,则插入关联V。
get(K) - 返回与指定键K关联的值。如果找不到该键,则返回null。
getOrDefault(K,defaultValue) - 返回与指定键K关联的值。如果找不到键,则返回defaultValue。
containsKey(K) - 检查指定的键K是否在map中。
containsValue(V) - 检查指定的值V是否存在于map中。
replace(K,V) - 将键K的值替换为新的指定值V。
replace(K,oldValue,newValue) - 仅当键K与值oldValue相关联时,才用新值newValue替换键K的值。
remove(K) - 从键K表示的Map中删除条目。
remove(K,V) - 从Map集合中删除键K与值V相关联的条目。。
keySet() -返回Map集合中存在的所有键的集合。
values() -返回一组包含在Map集合中的所有值。
entrySet() -返回map中存在的所有键/值映射的集合。
//具有默认容量和负载因子的HashMap HashMap<Key, Value> numbers1 = new HashMap<>();
1.使用entrySet(),keySet()和values()
entrySet() -返回一组所有键/值映射的map
keySet() -返回map所有键的集合
values() -返回map所有值的集合
2.使用get()和getOrDefault()
get() - 返回与指定键关联的值。如果找不到键,则返回null。
getOrDefault() - 返回与指定键关联的值。如果找不到键,则返回指定的默认值。
replace(key, value) - 将key的值替换为value
replace(key, old, new) - 仅当old值已与指定键key关联时,才用new值替换old值
replaceAll(function) - 用指定函数的结果替换映射的每个值
1.使用compute()方法
compute() - 使用指定的函数计算新值。然后将计算值与指定的键相关联。
computeIfAbsent() - 如果指定的键没有映射到任何值,该方法将使用指定的函数计算一个新值。然后将新值与键关联。
computeIfPresent() -如果指定的键已经映射到任何值,此方法将使用指定的函数计算一个新值。然后将新值与键关联。
2.使用merge()方法
如果指定的键尚未关联,则merge()方法将指定的值与指定的键关联。
但是,如果指定的键已经与一个值关联,它将把新的指定值与现有的旧值合并
LinkedHashMap类提供了Map接口的哈希表和链表实现。
LinkedHashMap继承了HashMap类,以将其条目存储在哈希表中。它在内部在所有条目之间维护一个双链列表,以对条目进行排序。
ConcurrentHashMap类提供了线程安全的映射。 也就是说,多个线程可以一次访问该映射,而不会影响映射中条目的一致性。
以下是ConcurrentHashMap和HashMap之间的一些区别,
ConcurrentHashMap是线程安全的集合。也就是说,多个线程可以同时访问和修改它。
ConcurrentHashMap提供用于批量操作的方法,例如forEach(),search()和reduce()。
ConcurrentHashMap类允许多个线程修改操作并发进行。
默认情况下,并发哈希映射分为16段。这就是为什么允许16个线程同时修改映射的原因。但是,一次可以访问任意数量的线程。
如果指定的键已经存在,则putIfAbsent()方法将不会覆盖映射中的条目。
Iterator即迭代器,实现透明的遍历访问,即不论集合的内部组织形式是何种样子的,只要实现了Iterator接口就能方便的实现遍历。
Iterator接口提供了4种方法,可用于对集合元素执行各种操作。常用的就是next和hasNext。
hasNext() - 如果集合中存在元素,则返回true
next() - 返回集合的下一个元素
remove() -删除next()返回的最后一个元素
forEachRemaining() - 对集合的每个剩余元素执行指定的操作
//创建Iterator的实例 Iterator<Integer> iterate = numbers.iterator();
ListIterator提供了访问列表元素的功能。
它是双向的。 这意味着它允许我们在两个方向上迭代列表的元素。
ListIterator接口提供了可用于对列表元素执行各种操作的方法。
hasNext() - 如果列表中存在元素,则返回true
next() - 返回列表的下一个元素
nextIndex() - 返回next()方法将返回的元素的索引
previous() - 返回列表的前一个元素
previousIndex()- 返回previous()方法将返回的元素的索引
remove()- 删除由next()或previous()返回的元素
set() - 将next()或previous()返回的元素替换为指定的元素
// 使用sort()方法 Collections.sort(numbers);
//使用shuffle()方法 Collections.shuffle(numbers);
在Java中,集合框架提供了可用于处理数据的不同方法。
reverse() - 反转元素的顺序
fill() - 用指定的值替换集合中的每个元素
copy() - 创建从指定源到目标的元素副本
swap() - 交换集合中两个元素的位置
addAll() - 将集合的所有元素添加到其他集合
// 使用 binarySearch(),返回在集合中的位置,在执行binarySearch()方法之前,应对集合进行排序。 int pos = Collections.binarySearch(numbers, 3);
frequency() - 返回元素在集合中存在的次数计数
disjoint() - 检查两个集合是否包含一些公共元素
Java集合框架的min()和max()方法分别用于查找最小和最大元素。
原文:https://www.cnblogs.com/lison-qlq/p/15302938.html