集合可以存储任意类型的对象,并且长度可变
集合对象可以是任意的数据类型,并且长度可变
单列集合Collection | 双列集合Map |
---|---|
单列集合根接口,用于存储一系列符合某种规则的元素 | 双列集合根接口,用于存储具有键(Key )、值(Value )映射关系的元素 |
Collection 集合有两个重要的子接口,分别是List和Set |
Map 集合中每个元素都包含一对键值,并且Key唯一,在使用Map 集合时通过指定的Key找到对应的· |
List 集合的特点是元素有序、可重复。该接口的主要实现类有ArrayList 和LinkedList |
Map 接口的主要实现类有HashMap 和TreeMap |
Set 集合的特点是元素无序并且不可重复。该接口的主要实现类有HashSet 和TreeSet |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PkC8S47W-1634995158221)(https://i.loli.net/2021/10/22/TO8apPtlNEo6Lvs.png)]
方法声明 | 功能描述 |
---|---|
boolean add(Object o) | 向集合中添加一个元素 |
boolean addAll(Collection c) | 将指定集合c中的所有元素添加到该集合中 |
void clear() | 删除该集合中的所有元素 |
boolean remove(Object o) | 删除该集合中指定的元素 |
boolean removeAll(Collection c) | 删除该集合中包含指定集合c中的所有元素 |
boolean isEmpty() | 判断该集合是否为空 |
boolean contains(Object o) | 判断该集合中是否包含某个元素 |
boolean containsAll(Collection c) | 判断该集合中是否包含指定集合c中的所有元素 |
Iterator iterator() | 返回在该集合的元素上进行迭代的迭代器(Iterator),用于遍历该集合所有元素 |
int size() | 获取该集合元素个数 |
Stream stream() | 将集合源转换为有序元素的流对象(JDK 8新方法) |
方法声明 | 功能描述 |
---|---|
void add(int index,Object element) | 将元素element插入在List集合的指定索引位置 |
boolean addAll(int index,Collection c) | 将集合c包含的所有元素插入到List集合的指定索引位置 |
Object get(int index) | 返回集合索引index处的元素 |
Object remove(int index) | 删除index索引处的元素 |
Object set(int index, Object element) | 将索引index处元素替换成element元素,并将替换后的元素返回 |
int indexOf(Object o) | 返回对象o在List集合中首次出现的位置索引 |
int lastIndexOf(Object o) | 返回对象o在List集合中最后一次出现的位置索引 |
List subList(int fromIndex, int toIndex) | 返回从索引fromIndex(包括)到 toIndex(不包括)处所有元素集合组成的子集合 |
Object[] toArray() | 将集合元素转换为数组 |
default void sort(Comparator super E> c) | 根据指定的比较器规则对集合元素排序(JDK 8新方法) |
ArrayList list = new ArrayList();
list.add("stu1");
list.add("stu2");
System.out.println("集合的长度:" + list.size());
System.out.println("第2个元素是:" + list.get(1));
左图为新增元素,图中的元素1和元素2在集合中彼此为前后关系,在它们之间新增一个元素时,只需要让元素1记住它后面的元素是新元素,让元素2记住它前面的元素为新元素就可以了
右图为删除元素,要想删除元素1和元素2之间的元素3,只需要让元素1与元素2变成前后关系就可以了
方法声明 | 功能描述 |
---|---|
void add(int index, E element) | 在此列表中指定的位置插入指定的元素。 |
void addFirst(Object o) | 将指定元素插入集合的开头 |
void addLast(Object o) | 将指定元素添加到集合的结尾 |
Object getFirst() | 返回集合的第一个元素 |
Object getLast() | 返回集合的最后一个元素 |
Object removeFirst() | 移除并返回集合的第一个元素 |
Object removeLast() | 移除并返回集合的最后一个元素 |
boolean offer(Object o) | 将指定元素添加到集合的结尾 |
boolean offerFirst(Object o) | 将指定元素添加到集合的开头 |
boolean offerLast(Object o) | 将指定元素添加到集合的结尾 |
Object peek() | 获取集合的第一个元素 |
Object peekFirst() | 获取集合的第一个元素 |
Object peekLast() | 获取集合的最后一个元素 |
Object poll() | 移除并返回集合的第一个元素 |
Object pollFirst() | 移除并返回集合的第一个元素 |
Object pollLast() | 移除并返回集合的最后一个元素 |
void push(Object o) | 将指定元素添加到集合的开头 |
Object pop() | 移除并返回集合的第一个元素 |
LinkedList link = new LinkedList();
link.add("stu1");
link.add("stu2");
link.offer("offer"); // 向集合尾部追加元素
link.push("push"); // 向集合头部添加元素
Object object = link.peek(); //获取集合第一个元素
link.removeFirst(); // 删除集合第一个元素
link.pollLast(); // 删除集合最后一个元素
Iterator遍历集合时,内部采用指针的方式来跟踪集合中的元素。在调用next()方法之前,索引位于第一个元素之前,不指向任何元素
第一次调用next()方法后,索引会向后移动一位,指向第一个元素并将该元素返回
再次调用next()方法时,索引会指向第二个元素并将该元素返回
以此类推,直到hasNext()方法返回false,表示到达了集合的末尾终止对元素的遍历
int[] arr = new int[10];
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(100) + 1;
list.add(arr[i]);
}
System.out.println(Arrays.toString(arr));
System.out.println(list);
/**
* 使用Iterator迭代器遍历list集合
*/
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println(obj);
}
Iterator
迭代器对集合中的元素进行迭代时,如果调用了集合对象的remove()方法删除元素,会出现ConcurrentModificationException
异常。/**
* 使用增强版for遍历list集合
*/
for (Object obj : list) {
System.out.println(obj);
}
foreach
循环遍历集合和数组时,只能访问集合中的元素,不能对其中的元素进行修改list.forEach(obj -> System.out.println(obj));
Iterator it = list.iterator();
it.forEachRemaining(obj -> System.out.println("迭代集合元素:"+obj));
分类 | 简介 |
---|---|
HashSet | 根据对象的哈希值来确定元素在集合中的存储的位置,因此具有良好的存取和查找性能 |
TreeSet | 以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f9uP80fy-1634995158227)(https://i.loli.net/2021/10/22/Wl1HpNIjkamMBsO.png)]
hashCode()
和equals()
方法HashSet
集合中添加自定义的数据类型,如Student
类时,必须增加重写的hashCode()
和equals()
方法,才能保证数据的唯一性。TreeSet
是Set
接口的另一个实现类,它内部采用平衡二叉树来存储元素,来保证TreeSet
集合中没有重复的元素,并且可以对元素进行排序[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kK8pDDQg-1634995158228)(https://i.loli.net/2021/10/22/VB7G4P2wLFvcZ3x.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C5wSaJsG-1634995158229)(https://i.loli.net/2021/10/22/WHcuqkK2j9hvVUE.png)]
方法声明 | 功能描述 |
---|---|
Object first() | 返回TreeSet集合的首个元素 |
Object last() | 返回TreeSet集合的最后一个元素 |
Object lower(Object o) | 返回TreeSet集合中小于给定元素的最大元素,如果没有返回null |
Object floor(Object o) | 返回TreeSet集合中小于或等于给定元素的最大元素,如果没有返回null |
Object higher(Object o) | 返回TreeSet集合中大于给定元素的最小元素,如果没有返回null |
Object ceiling(Object o) | 返回TreeSet集合中大于或等于给定元素的最小元素,如果没有返回null |
Object pollFirst() | 移除并返回集合的第一个元素 |
Object pollLast() | 移除并返回集合的最后一个元素 |
Comparable
接口Comparable
接口,并默认实现了接口中的CompareTo()
方法,如Integer
、Double
和String等
Comparable
接口,并重写compareTo()
方法Comparator
接口,并重写compare()
方法,然后将该比较器作为参数传入集合的有参构造自然排序 | 定制排序 |
---|---|
适合元素类本身未实现Comparable 接口,无法进行比较 |
元素类本身实现Comparable 接口 |
适合元素类实现的Comparable接口排序规则无法满足用户需求 | 依赖compareTo() 方法的实现 |
会额外定义一个实现Comparator 接口的比较器 |
实现Comparable 接口排序规则比较单一,不利于后续改进 |
public class Person implements Comparable<Object>{
public String name;
public int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return this.name + ": " + age;
}
public int compareTo(Object obj) {
Person person = (Person) obj;
if(this.age - person.age > 0) {
return 1;
}
if(this.age - person.age == 0) {
return this.name.compareTo(person.name);
}
return -1;
}
}
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
TreeSet<Object> ts = new TreeSet<Object>();
ts.add(new Person("Alice", 13));
ts.add(new Person("Bob", 23));
ts.add(new Person("Charli", 13));
ts.add(new Person("Alice", 13));
System.out.println(ts);
}
}
import java.util.Comparator;
public class Person implements Comparator<Object>{
public String name;
public int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return this.name + ": " + age;
}
public int compare(Object obj1, Object obj2) {
Person person1 = (Person) obj1;
Person person2 = (Person) obj2;
if(person1.age - person2.age > 0) {
return 1;
}
if(person1.age - person2.age == 0) {
return person1.name.compareTo(person2.name);
}
return -1;
}
}
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
TreeSet<Object> ts = new TreeSet<Object>(new Person());
ts.add(new Person("Alice", 13));
ts.add(new Person("Bob", 23));
ts.add(new Person("Charli", 13));
ts.add(new Person("Alice", 13));
System.out.println(ts);
}
}
Key
和值对象Value
,键和值对象之间存在一种对应关系,称为映射Map
中的映射关系是一对一的,一个键对象Key
对应唯一一个值对象Value
,其中键对象Key和值对象Value可以是任意数据类型,并且键对象Key不允许重复,这样在访问Map集合中的元素时,只要指定了Key,就能找到对应的Value方法声明 | 功能描述 |
---|---|
void put(Object key, Object value) | 向Map集合中添加指定键值映射的元素 |
int size() | 返回Map集合键值对映射的个数 |
Object get(Object key) | 返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null |
boolean containsKey(Object key) | 查看Map集合中是否存在指定的键对象key |
boolean containsValue(Object value) | 查看Map集合中是否存在指定的值对象value |
Object remove(Object key) | 删除并返回Map集合中指定键对象Key的键值映射元素 |
void clear() | 清空整个Map集合中的键值映射元素 |
Set keySet() | 以Set集合的形式返回Map集合中所有的键对象Key |
Collection values() | 以Collection集合的形式返回Map集合中所有的值对象Value |
Set |
将Map集合转换为存储元素类型为Map的Set集合 |
Object getOrDefault(Object key, Object defaultValue) | 返回Map集合指定键所映射的值,如果不存在则返回默认值defaultValue(JDK 8新方法) |
void forEach(BiConsumer action) | 通过传入一个函数式接口对Map集合元素进行遍历(JDK 8新方法) |
Object putIfAbsent(Object key, Object value) | 向Map集合中添加指定键值映射的元素,如果集合中已存在该键值映射元素,则不再添加而是返回已存在的值对象Value(JDK 8新方法) |
boolean remove(Object key, Object value) | 删除Map集合中键值映射同时匹配的元素(JDK 8新方法) |
boolean replace(Object key, Object value) | 将Map集合中指定键对象Key所映射的值修改为value(JDK 8新方法) |
HashMap
的主体结构,链表则主要是为了解决哈希值冲突而存在的分支结构。正因为这样特殊的存储结构,HashMap
集合对于元素的增、删、改、查操作表现出的效率都比较高[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4krjYKEC-1634995158229)(https://i.loli.net/2021/10/22/DB63Y1yivjLanUt.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQQxqPEe-1634995158230)(https://i.loli.net/2021/10/22/msn9H6LrI2GWQRV.png)]
使用HashMap集合时,如果通过键对象k定位到的桶位置不含链表结构,那么对于查找、添加等操作很快;如果定位到的桶位置包含链表结构,对于添加操作,其时间复杂度依然不大,因为最新的元素会插入链表头部,只需要简单改变引用链即可;而对于查找操作来讲,此时就需要遍历链表,然后通过键对象k的equals(k)方法逐一查找比对。
所以,从性能方面考虑,HashMap中的链表出现越少,性能才会越好,这就要求HashMap集合中的桶越多越好。
HashMap根据实际情况,内部实现了动态地分配桶数量的策略。
通过new HashMap()方法创建HashMap时,会默认集合容量capacity大小为16,加载因子loadFactor为0.75(HashMap桶多少权衡策略的经验值),此时该集合桶的阀值就为12(容量capacity与加载因子loadFactor的乘积),如果向HashMap集合中不断添加完全不同的键值对
HashMap
集合并不保证集合元素存入和取出的顺序LinkedHashMap
类,它是HashMap的子类。和LinkedList
一样也使用双向链表来维护内部元素的关系,使LinkedHashMap
元素迭代的顺序与存入的顺序一致HashMap
,在Map
中插入、删除和定位元素,HashMap
是最好的选择。但如果需要输出的顺序和输入的相同,那么用LinkedHashMap
可以实现,它还可以按读取顺序来排列Map
集合转换为Iterator
接口对象,然后进行遍历。由于Map集合中元素是由键值对组成的,所以使用Iterator
接口遍历Map
集合时,会有两种将Map
集合转换为Iterator
接口对象再进行遍历的方法keySet()
方法和entrySet()
方法Set keySet = map.keySet(); // 获取键的集合
Iterator it = keySet.iterator(); // 迭代键的集合
while (it.hasNext()) {
Object key = it.next();
Object value = map.get(key); // 获取每个键所对应的值
System.out.println(key + ":" + value);
}
Set entrySet = map.entrySet();
Iterator it = entrySet.iterator(); // 获取Iterator对象
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) (it.next());
Object key = entry.getKey(); // 获取Entry中的键
Object value = entry.getValue(); // 获取Entry中的值
System.out.println(key + ":" + value);
}
Lambda
表达式特性新增了一个forEach(BiConsumer action)
方法来遍历Map
集合,该方法所需要的参数也是一个函数式接口,因此可以使用Lambda
表达式的书写形式来进行集合遍历map.forEach((key,value) -> System.out.println(key + ":" + value));
Map
集合中,除了以上介绍的两种主要的遍历方式外,还提供了一个values()
方法,通过这个方法可以直接获取Map中存储所有值的Collection
集合Collection values = map.values(); // 获取Map集合中value值集合对象
values.forEach(v -> System.out.println(v));
TreeMap
集合是Map
接口的另一个实现类,在TreeMap
内部是通过二叉树的原理来保证键的唯一性,这与TreeSet
集合存储的原理一样,因此TreeMap
中所有的键是按照某种顺序排列的TreeMap
元素排序,可以参考TreeSet
集合排序方式,使用自然排序和定制排序import java.util.Map;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
Map map = new TreeMap();
map.put("2", "Rose");
map.put("1", "Jack");
map.put("3", "Luck");
System.out.println(map);
}
}
comparator
方式
import java.util.*;
class CustomComparator implements Comparator {
public int compara (Object obj1, Object obj2) {
String key1 = (String) obj1;
String key2 = (String) obj2;
return key2.comparaTo(key1); //调用了String对象的comparaTo()方法
}
}
public class Main {
public static void main(String[] args) {
Map map = new TreeMap(new CustomComparator());
map.put("2", "Rose");
map.put("1", Jack);
map.put("3", "Luck");
System.out.println(map);
}
}
/**
* 打印结果
* {1=Jack, 2=Rose, 3=Luck}
*/
Map
接口还有一个实现类Hashtable
,它和HashMap
十分相似,其中一个主要区别在于Hashtable
是线程安全的Hashtable
类有一个子类Properties
,Properties
主要用来存储字符串类型的键和值,在实际开发中,经常使用**Properties
集合类来存取应用的配置项**import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
puclic class Main {
public static void main(String[] args) throws Exception {
// 1.通过Properties进行属性文件读取操作
Properties pps = new Properties();
// 加载读取的文件 test.properties
pps.load(new FileInputStream("test.properties"));
// 遍历test.properties键值对元素信息
pps.forEach((key, value) -> System.out.println(key + " = " + value));
// 2.通过Properties进行属性文件写入操作
// 指定写入操作的文件名称和位置
FileOutputStream out = new FileOutputStream("test.properties");
// 向Properties类文件进行写入键值对信息
pps.setProperties("charset", "utf-8");
// 将此 Properties 集合中新增键值对信息写入配置文件
pps.store(out, "新增charset编码");
}
}
/**
* 打印结果
*
* language=chinese
* Font-size=14px
* Backgroup-color=red
*/
ArrayList<参数化类型> list = new ArrayList<参数化类型>();
ArrayList<String> list = new ArrayList<String>();
方法声明 | 功能描述 |
---|---|
static boolean addAll(Collection super T> c, T… elements) | 将所有指定元素添加到指定集合c中 |
static void reverse(List list) | 反转指定List集合中元素的顺序 |
static void shuffle(List list) | 对List集合中的元素进行随机排序 |
static void sort(List list) | 根据元素的自然顺序对List集合中的元素进行排序 |
static void swap(List list,int i,int j) | 将指定List集合中角标i处元素和j处元素进行交换 |
improt java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "c", "z", "b", "k");
System.out.println("排序前:" + list);
Collections.reverse(list);
System.out.println("反转后:" + list);
Collections.sort(list);
System.out.println("按自然顺序排序后:" + list);
Collections.shuffle(list);
System.out.print("随机排序后:" + list);
Collections.swap(list, 0, list.size() - 1);
System.out.print("集合收尾交换后:" + list);
}
}
/**
* 打印结果
*
* 排序前:[c, z, b, k]
* 反转后:[k, b, z, c]
* 按自然顺序排序后:[b, c, k, z]
* 按随机顺序排序后:[b, z, k, c]
* 集合收尾元素交换后:[c, z, k, b]
*/
方法声明 | 功能描述 |
---|---|
static int binarySearch(List list,Object key) | 使用二分法搜索指定对象在List集合中的索引,查找的List集合中的元素必须是有序的 |
static Object max(Collection col) | 根据元素的自然顺序,返回给定集合中最大的元素 |
static Object min(Collection col) | 根据元素的自然顺序,返回给定集合中最小的元素 |
static boolean replaceAll(List list,Object oldVal,Object newVal) | 用一个新值newVal替换List集合中所有的旧值oldVal |
improt java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<Integer>list = new ArrayList<Integer>();
Collections.addAll(list, -3, 2, 9, 5, 8);
System.out.println("集合中的元素:" + lsit);
System.out.println("集合中最大元素:" + Collections.max(list));
Systme.out.println("集合中最小元素:" + Collections.min(list));
Collections.replaceAll(list, 8, 0); //将集合中的8用0替换掉
System.out.println("替换后的集合:" + list);
collections.sort(list); //使用二分法查找前,必须保证元素有序
System.out.println("集合排序后为:" + list);
int index = Collections.binarySearch(list, 9);
System.out.println("集合通过二分查找方法查找元素9所在角标为:" + index);
}
}
/**
* 打印结果
*
* 集合中的元素:[-3, 2, 9, 5, 8]
* 集合中的最大元素:9
* 集合中的最小元素:-3
* 替换后的集合:[-3, 2, 9, 5, 0]
* 集合排序后为:[-3, 0, 2, 5, 9]
* 集合通过二分查找方法查找元素9所在角标为:4
*/
sort()
排序int[] arr = {9, 8, 3, 5, 2};
Arrays.sort(arr);
System.out.println(arr);
// {2, 3, 5, 8, 9}
binarySearch(Object[] obj, Object key)
用二分法查找obj
中的key
int[] arr = {9, 8, 3, 5, 2};
Arrays.sort(arr);
System.out.println(arr);
int index = Arrays.binarySearch(arr, 8);
System.out.println("8的索引位为:" + index);
// {2, 3, 5, 8, 9}
// 8的索引位为:3
copyOfRange(int[] original, int from, int to)
复制数组的指定范围int[] arr = {9, 8, 3, 5, 2}
int[] copy = Arrays.copyOfRange(arr, 1, 7);
System.out.println(copy);
// {8, 3, 5, 2}
fill(Object[] a, Object value)
用value
把数组填充int[] arr = {9, 8, 3, 5, 2};
Arrays.fill(arr, 6);
// {6, 6, 6, 6, 6}
asList()
把Array转换为ListInteger[] array = {9, 8, 3, 5, 2};
List<Integer> list = Arrays.toList(array);
System.out.println(list);
// [9, 8, 3, 5, 2]
stream()
创建stream
流对象Integer[] array = {9, 8, 3, 5, 2};
Stream<Integer> stream = Arrays.stream(array);
stream.forEach(item -> System.out.println(item + " "));
// 9 8 3 5 2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vJ6Xj8KI-1634995158231)(https://i.loli.net/2021/10/23/GLnxOQerBAWDk3f.png)]
Collections
集合都可以使用stream()
静态方法获取Stream
流对象Stream
接口的of()
静态方法可以获取基本类型包装类数组、引用类型数组和单个元素的Stream
流对象Arrays
工具类的stream()
静态方法也可以获取数组元素的Stream
流对象import java.util.*;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Integer array = {9, 8, 3, 5, 2};
List<Integer> list = Arrays.asList(array);
// 1.使用stream()静态方法获取Stream流对象
Stream<Integer> stream1 = list.stream();
stream1.forEach(item -> System.out.println(item + " "));
System.out.println();
// 2.使用Stream接口的of()静态方法创建Stream流对象
Stream<Integer> stream2 = Stream.of(array);
stream2.forEach(item -> System.out.println(item + " "));
System.out.println();
// 3.使用Arrays数组工具类的stream()静态方法创建stream流对象
Stream<Integer> stream3 = Arrays.stream(array);
stream3.forEach(item -> System.out.println(item + " "));
}
}
Stream
流对象中的数据,并不会改变原始集合或数组中的源数据方法声明 | 功能描述 |
---|---|
Stream filter(Predicate super T> predicate) | 将指定流对象中的元素进行过滤,并返回一个子流对象 |
Stream map(Function super T, ? extends R> mapper) | 将流中的元素按规则映射到另一个流中 |
Stream distinct() | 删除流中重复的元素 |
Stream sorted() | 将流中的元素按自然顺序排序 |
Stream limit(long maxSize) | 截取流中元素的长度 |
Stream skip(long n) | 丢弃流中前n个元素 |
static Stream concat(Stream extends T> a, Stream extends T> b) | 将两个流对象合并为一个流 |
long count() | 统计流中元素的个数 |
R collect(Collector super T, A, R> collector) | 将流中的元素收集到一个容器中(如集合) |
Object[] toArray() | 将流中的元素收集到一个数组中 |
void forEach(Consumer super T> action) | 将流中的元素进行遍历 |
forEach()
遍历// 不保证元素的遍历过程在流中是被有序执行的
void forEach(Consumer<? super T> action);
stream.forEach(i -> System.out.println(i)); // 遍历并打印流元素
filter()
过滤// 将一个Stream流中的元素进行筛选转换成另一个子集流
Stream<T>filter(Predicate<? super T> predicate);
stream.filter(i -> i.startsWith("张")); // 筛选出以“张”开头的流元素
map()
映射// 将流对象中的元素通过特定的规则进行修改然后映射为另一个流对象
Stream<R> map(Function<? super T, ? extends R> mapper);
stream.map(str -> str.toUpperCase());
stream.map(String::toUpperCase); // 将所有流元素字母转换为大写
limit()
截取// 用于对流对象中的元素进行截取操作
// 在多数情况下,limit()方法会与skip()方法(跳过方法)组合使用,用于截取流对象中指定位置的多个元素
Stream<T> limit(long maxSize);
stream.skip(1) // 跳过流中的前1个元素
.limit(2); // 截取剩余流中的前2个元素
collect()
收集//
/**
* collect()是十分有用的终结操作,它可以把Stream中的元素保存为另外一种形式,比如集合、字符串等
*
* Collector参数包含4种操作
*
* 1) supplier(初始构造器)
* 2) accumulator(累加器)
* 3) combiner(组合器)
* 4)finisher(终结者)
* 在JDK 8中的java.util.stream包下的Collectors类内置了各种复杂的收集操作
*/
<R, A> R collect(Collector<? super T, A, R> collector);
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("张三", "李四", "张小明", "张阳");
// 通过filter()方法筛选出字符串中以“张”开头的元素
// 通过collect()方法进行终结操作,将流元素收集到一个List集合中
List<String> list = stream1.filter(item -> item.startWith("张"))
.collect(Collectors.toList());
System.out.println(list);
Stream<String> stream2 = Stream.of("张三", "李四", "张小明", "张阳");
// 通过filter()方法筛选出字符串中以“张”开头的元素
// 通过collect()方法进行终结操作,将流元素使用“and”连接收集到一个字符串中
String string = stream2.filter(item -> item.startWith("张"))
.collect(Collectors.joining("and"));
System.out.println(string);
}
}
/**
* 打印结果
*
* [张三, 张小明, 张阳]
* 张三 and 张小明 and 张阳
*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PJV0v5nD-1634995158231)(https://i.loli.net/2021/10/23/MR5B7quGU4O2bDJ.png)]
Collection
集合接口的parallelStream()
方法直接将集合类型的源数据转变为Stream
并行流BaseStream
接口的parallel()
方法将Stream
串行流转变为Stream
并行流import java.util.*;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("张三", "李四", "张小明", "张阳");
// 1.直接使用Collection接口的parallelStream()创建并行流
Stream<String> paralleStream = list.parallelStream();
System.out.println(parallelStream.isParallel());
// 创建一个Stream串行流
Stream<String> stream = Stream.of("张三", "李四", "张小明", "张阳");
// 2.使用BaseStream接口的parallel()方法将串行流变为并行流
Stream<String> parallel = stream.parallel();
System.out.println(parallel.isParallel());
}
}
/**
* 打印结果
* true
* true
*/
创建Stream
流对象时,除非有特别声明,否则默认创建的都是串行流
使用Stream
并行流在一定程度上可以提升程序的执行效率,但是在多线程执行就会出现线程安全这个大问题,所以为了能够在聚合操作中使用Stream
并行流,前提是要执行操作的源数据在并行执行过程中不会被修改
seStream接口的
parallel()方法将
Stream串行流转变为
Stream`并行流
import java.util.*;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("张三", "李四", "张小明", "张阳");
// 1.直接使用Collection接口的parallelStream()创建并行流
Stream<String> paralleStream = list.parallelStream();
System.out.println(parallelStream.isParallel());
// 创建一个Stream串行流
Stream<String> stream = Stream.of("张三", "李四", "张小明", "张阳");
// 2.使用BaseStream接口的parallel()方法将串行流变为并行流
Stream<String> parallel = stream.parallel();
System.out.println(parallel.isParallel());
}
}
/**
* 打印结果
* true
* true
*/
创建Stream
流对象时,除非有特别声明,否则默认创建的都是串行流
使用Stream
并行流在一定程度上可以提升程序的执行效率,但是在多线程执行就会出现线程安全这个大问题,所以为了能够在聚合操作中使用Stream
并行流,前提是要执行操作的源数据在并行执行过程中不会被修改