JavaSE之集合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_1018944104/article/details/82839561

目录

一、集合

1.集合是什么?

2.为什么使用集合?

3.集合与数组的对比

4.Java中集合继承层次(UML画图)

二、Collection 接口

1.介绍

2.常用方法

3.示例

三、List接口

1.介绍

2.常用方法

3.示例

四、Collection 集合遍历

1.遍历方式

2.Iterator 接口

3.ListIterator 接口

4.示例

五、集合比较

1.ArrayList和Vector

2.ArrayList和LinkedList

六、Set接口

1.介绍

2.HashSet的存储原理

3.常用方法

4.示例

七、SortedSet 接口

1.常用方法

2.数据结构:二叉树

八、NavigableSe 接口

1.介绍

2.常用方法

3.示例

九、HashSet、LinkedHashSet以及TreeSet之间的区别

十、Collections 工具类

1.常用方法

2.示例

十一、Queue 队列接口

1.介绍

2.常用方法

3.示例

十二、PriorityQueue类

1.介绍

2.示例

十三、Deque 接口

1.介绍

2.常用方法

3.示例

十四、Map 接口

1.介绍

2.常用方法

3.HashMap类

4.遍历Map

5.比较HashMap、HashTable、LinkedHashMap、TreeMap

十五、Stream 流操作

1.介绍

2.常用方法

十六、Predicate 过滤器接口


一、集合

1.集合是什么?

  • 和数组一样,集合是一种存储和操作数据的容器,存储引用类型的数据,对数据有增、删、改、查等操作。

2.为什么使用集合?

  • 和数组相比,集合可适用于存储规模不确定的数据以及存储具有一定关系的数据。

3.集合与数组的对比

  • 数组可以存储基本类型和引用类型,集合只能存储引用类型。
  • 数组长度是固定的,集合长度是不固定的。
  • 能用数组解决问题,则优先使用数组,因为集合底层是更加复杂的数据结构,会消耗更多的资源。

4.Java中集合继承层次(UML画图)

二、Collection 接口

1.介绍

  • 是一个接口,特点是数据可重复且无序。
  • 直接子接口包括List,Set以及Queue。
  • 常用实现类包括ArrayList,LinkedList,HashSet,LinkedHashSet、TreeSet、PriorityQueue、ArrayDeque

2.常用方法

  • isEmpty():判断集合是否为空
  • size():集合中的元素个数
  • addAll(集合):把参数集合中的所有元素添加到当前集合,当前集合只要发生了改变就返回true
  • remove():删除参数指定的元素,只要当前集合发生改变,返回true
  • remove(集合):删除指定参数集合中的所有元素,若当前集合发生改变,则返回true
  • removeIf():按照条件删除
  • contains():参数指定的元素在集合中是否包含,包含返回true
  • containsAll():参数集合中的所有元素在当前集合中是否包含,包含true
  • toArray():集合转数组(代码中描述了将数组转集合的方法)
  • clear():清空集合

3.示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
public class TestCollection {
	public static void main(String[] args) {
		//创建一个集合
		Collection<String> c = new ArrayList<>();
		//判断集合是否为空,集合元素的个数
		System.out.println(c.isEmpty());
		//添加
		c.add("aa");
		c.add("bb");
		c.add("cc");
		c.add("dd");
		//展示集合中的元素
		System.out.println(c);
		//集合中的元素个数
		System.out.println(c.size());
		
		Collection<String> c1 = new ArrayList<>();
		c1.add("ee");
		c1.add("ff");
		c1.add("gg");
		//把参数集合中的所有元素添加到当前集合,当前集合只要发生了改变就返回true
		c.addAll(c1);
		System.out.println(c);
		//删除参数指定的元素,只要当前集合发生改变,返回true
		c.remove("bb");
		System.out.println(c);
		//删除指定参数集合中的所有元素,若当前集合发生改变,则返回true
		c.removeAll(c1);
		System.out.println(c);
		//按照条件删除
		c.removeIf(new Predicate<String>(){
			@Override
			public boolean test(String t) {
				return t.length() == 3;
			}
		});//可以使用Lambda表达式
		System.out.println(c);
		//参数指定的元素在集合中是否包含,包含返回true
		System.out.println(c.contains("cc"));
		//参数集合中的所有元素在当前集合中是否包含,包含true
		System.out.println(c.containsAll(c1));
		//把一个字符串数组转换成集合
		//转换的集合是Arrays的静态内部类ArrayList,是一个固定长度的集合,不能向集合中添加和删除元素。
		List<String> c2 = Arrays.asList(new String[]{"ee","ff"});
		c.addAll(c2);
		System.out.println(c);
		System.out.println(c.contains(c1));
		//集合转数组
		Object[] obj = c.toArray();
		System.out.println(Arrays.toString(obj));
		//清空集合
		c.clear();
	}
}

三、List接口

1.介绍

  • 是一个继承Collection接口的接口,特点是数据可重复,有序,线性排列。
  • 常用实现类:
    • ArrayList:底层数据结构是数组,线程非安全。遍历,随机访问效率高,插入或删除元素效率低。
    • Verctor:底层数据结构是数组,线程安全,已经不用了。
    • LinkedList:底层数据结构是链表。遍历,随机访问效率低,插入或删除元素效率高。

2.常用方法

  • add(index, element):向索引位置添加元素
  • get(index):获得索引处的元素
  • set(index, element):用第二个参数元素替换索引处的元素
  • indexOf(element):返回参数元素在当前集合中第一次出现的位置索引
  • lastIndexOf(element):返回参数元素在当前集合中最后 一次出现的位置索引
  • subList(start, end):取子集从起始位置到终止位置(左闭右开)
  • sort(Comparator):指定比较器,若参数是null,则会按照Comparable方式自然升序排序(下方代码中详解)

3.示例

import java.util.ArrayList;
import java.util.List;
public class TestList {
	public static void main(String[] args) {
		List<String> list =  new ArrayList<>();
		list.add("aa");//索引0
		list.add("bb");//索引1
		list.add("cc");//索引2
		System.out.println(list);
		//可以向索引位置添加元素
		list.add(1,"xx");
		System.out.println(list);
		//获得索引处的元素
		System.out.println(list.get(1));
		//用第二个参数元素替换索引处的元素
		list.set(1,"yy");
		System.out.println(list);
		list.add("aa");
		System.out.println(list);
		//返回参数元素在当前集合中第一次出现的位置索引
		System.out.println(list.indexOf("aa"));
		//返回参数元素在当前集合中最后 一次出现的位置索引
		System.out.println(list.lastIndexOf("aa"));
		//取子集从起始位置到终止位置(左闭右开)
		System.out.println(list.subList(1, 4));
		//排序
		System.out.println(list);
		//参数是:Comparator类型的比较器
		//若参数是null,则会按照Comparable方式自然升序排序
		list.sort(null);
		System.out.println(list);
		//指定比较器
		list.sort((s1,s2)->s2.compareTo(s1));
		System.out.println(list);
	}
}

四、Collection 集合遍历

1.遍历方式

  • 普通for循环:有索引且索引有顺序;
  • 增强for;
  • 集合自身增强for;
  • Iterator 迭代器
  • ListIterator 迭代器

2.Iterator 接口

//Iterator迭代器获取及使用方式
Iterator<String> i = list.iterator();
while(i.hasNext()) {
	System.out.println(i.next());
}

3.ListIterator 接口

//ListIterator的获取及使用方式
//ListIterator只能遍历List集合,其他集合不行
ListIterator<String> li = list.listIterator();
while(li.hasNext()){
	System.out.println(li.next());
    //一边遍历一边插入元素,在最近一次next()访问的元素后插入
	li.add("hello");
}
//向前遍历
while (li.hasPrevious()) {
	System.out.println(li.previous());
}

4.示例

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;

public class TestIterator {
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("aa");
		list.add("bb");
		list.add("cc");
		list.add("ee");
		System.out.println(list);
		//遍历
		//1.普通for循环:有索引且索引有顺序
		for (int i = 0; i < list.size(); i++) {
			System.out.print(list.get(i) + " ");
		}
		System.out.println();
		//2.增强for
		for (String s : list) {
			System.out.print(s + " ");
		}
		//3.
		list.forEach(new Consumer<String>() {
			@Override
			public void accept(String t) {
				System.out.println(t);	
			}
		});
		list.forEach(t -> System.out.print(t));
		list.forEach(System.out::print);
		//4.Iterator迭代器
		//获得一个迭代器
		Iterator<String> i = list.iterator();
//		System.out.println(i.next());
//		//删除的是最近一次next()访问的元素
//		i.remove();
		while(i.hasNext()) {
			System.out.println(i.next());
			//报错:ConcurrentModificationException,并行异常
//			list.add("ff");
		}
		//作用:遍历List集合,其他集合不行
		ListIterator<String> li = list.listIterator();
		while(li.hasNext()){
			System.out.println(li.next());
			li.add("hello");
		}
		//向前遍历
		while (li.hasPrevious()) {
			System.out.println(li.previous());
		}
		//6.Iterator迭代器的方法
		Iterator<String> i1 = list.iterator();
		i1.forEachRemaining(System.out::println);
		//7.Stream流的方法
		list.stream().forEach(System.out::println);
	}
}

五、集合比较

1.ArrayList和Vector

  • Vector出现的最早,性能低,线程安全,慢(一般不用这个了)。
  • ArrayList性能高,线程非安全(选择底层数组结构的都用这个)现在也可以通过其他方式做到线程安全。

2.ArrayList和LinkedList

  • ArrayList底层是数组存储数据,默认初始容量是10且以1.5倍扩容,适用于遍历和随机访问频繁的情形。
  • LinkedList底层是链表存储数据,链表有节点组成,节点由数据域(存值)和链域(存下一个节点地址)组成。遍历慢(地址空间不连续)、插入和删除快。

六、Set接口

1.介绍

  • 是一个继承Collection 接口的接口。特点是存储数据不重复但无序,底层数据结构是哈希表(将一组关键字映射到地址集上)保证数据的唯一性,本质上是数组+链表(或二叉树)存储。
  • 子接口包括SortedSet接口、NavigableSet接口
  • 实现类包括HashSet、LinkedHashSet、TreeSet

2.HashSet的存储原理

存储原理:

  • 首先调用hashCode()方法算出位置,存储元素。
  • 若哈希冲突(算出的位置值与之前存储过的元素的哈希值一样了),则调用equals()方法判断是否为同一个对象。
  • 若是同一个则采取旧值,若不是同一个可以采取链式存储,链表节点数超过8,则改为二叉树的存储方式。

自定义Hash:

  • 重写hashCode() 和 equals() 用自己的规则去重。

示例:

import java.util.HashSet;
import java.util.Set;
class Employee{
	private int no;
	private String name;
	public Employee() {
		super();
	}
	public Employee(int no, String name) {
		super();
		this.no = no;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Employee [no=" + no + ", name=" + name + "]";
	}
	//重写hashCode和equals方法,自定义去重规则
	@Override
	public int hashCode() {
		return name.hashCode() + no;
	}
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Employee)) {
			return false;
		}
		Employee e = (Employee)obj;
                //工号和名字相同,那二者就是相同的
		return this.name.equals(e.name) && this.no == e.no;
	}
}
public class TestHash {
	public static void main(String[] args) {
		Set<Employee> set = new HashSet<>();
		set.add(new Employee(1,"郭靖"));
		set.add(new Employee(2,"黄蓉"));
		set.add(new Employee(3,"杨康"));
		boolean res = set.add(new Employee(3,"杨康"));
		System.out.println(res);//false,插入失败
		System.out.println(set);
	}
}

3.常用方法

就是Collection 集合中的常用方法,一模一样,真的。

4.示例

import java.util.HashSet;
import java.util.Set;

public class TestSet {
	public static void main(String[] args) {
		Set<String> set = new HashSet<>();
		//返回boolean,添加成功返回true,添加失败返回false
		set.add("aa");
		set.add("bb");
		set.add("cc");
		System.out.println(set);
		//重复数据,未添加成功
		System.out.println(set.add("aa"));
	}
}

七、SortedSet 接口

1.常用方法

  • first()
  • last()
  • subSet(startElement, endElement)

2.数据结构:二叉树

  • 树:是由节点集及连接每对节点的有向边集组成。
  • 二叉树:树形结构,任意节点不能超过2个孩子,如下图:

八、NavigableSe 接口

1.介绍

  • 是一个继承SortedSet接口的接口,提供了最接近匹配原则的检索元素的方法。
  • 实现类:TreeSet

2.常用方法

  • floor():小于等于指定参数的最大元素(地板之下)
  • ceiling():大于等于指定参数的最小元素(天花板之上)
  • descendingSet():降序集合
  • descendingIterator():降序迭代器
  • pollFirst():移除第一个元素
  • pollLast():移除最后一个元素

3.示例

import java.util.NavigableSet;
import java.util.TreeSet;
public class TestNavigableSet {
	public static void main(String[] args) {
		NavigableSet<Integer> set = new TreeSet<>();
		set.add(22);
		set.add(11);
		set.add(55);
		set.add(33);
		System.out.println(set);
		//小于等于指定参数的最大元素
		System.out.println(set.floor(44));
		//大于等于指定参数的最小元素
		System.out.println(set.ceiling(15));
		//降序集合
		set.descendingSet().forEach(System.out::println);
		//降序迭代器
		set.descendingIterator().forEachRemaining(System.out::println);
		System.out.println(set);
		//移除第一个元素
		set.pollFirst();
		System.out.println(set);
		//移除最后一个元素
		set.pollLast();
		System.out.println(set);
	}
}

九、HashSet、LinkedHashSet以及TreeSet之间的区别

类型 数据结构 元素是否可重复 是否有序
HashSet 哈希表 不可,唯一的 无序
LinkedHashSet 链表+哈希表 不可,唯一的。重写hashCode方法和equals方法自定义去重规则。 有序,由链表来维护元素添加的顺序
TreeSet 二叉树 不可,唯一的。实现Comparable接口,重写compareTo()方法,只要返回0,则认为是重复的。 有序,默认自然升序,可以通过Comparator自己指定排序规则。

十、Collections 工具类

1.常用方法

  • addAll():添加
  • sort():自然升序排序
  • sort(集合,比较器):自定义规则:降序排序
  • binarySearch():二分查找:前提升序排序 若找到,返回位置索引,未找到,则返回负的插入点-1
  • max():返回集合中最大
  • min():最小的元素 
  • reverse():反转集合中的元素
  • frequency():返回第二个参数元素在第一个参数集合中出现的次数
  • fill():填充,用第二个参数元素替换掉集合中的所有元素

2.示例

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestCollections {
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		//添加
		Collections.addAll(list, "aa","cc","bb","xx");
		System.out.println(list);
		//自然升序排序
		Collections.sort(list);
		System.out.println(list);
		//自定义规则:降序排序
		Collections.sort(list, (s1,s2)->s2.compareTo(s1));
		System.out.println(list);
		//二分查找:前提升序排序 若找到,返回位置索引,未找到,则返回负的插入点-1
		System.out.println(Collections.binarySearch(list, "ee"));
		//返回集合中最大和最小的元素
		System.out.println(Collections.max(list));
		System.out.println(Collections.min(list));
		//反转集合中的元素
		Collections.reverse(list);
		System.out.println(list);
		list.add("xx");
		//返回第二个参数元素在第一个参数集合中出现的次数
		System.out.println(Collections.frequency(list, "xx"));
		//填充,用第二个参数元素替换掉集合中的所有元素
		Collections.fill(list, "hello");
		System.out.println(list);
	}
}

十一、Queue 队列接口

1.介绍

  • 数据结构:队列
  • 队列:是一组操作受限的线性表,只能在队尾增加队头删除。特点是先进先出。
  • 注意:队列不允许加入null值。只有LinkedList特殊,可以加入null,因为它出现的比较早。

2.常用方法

添加 删除 获取列表头元素 操作失败时
add remove element 会产生异常
offer poll peek (常用下面这些方法)不会产生异常,而是返回特定的值

3.示例

import java.util.LinkedList;
import java.util.Queue;
public class TestQueue {
	public static void main(String[] args) {
		//队列
		Queue<String> q = new LinkedList<>();
		//入队:向对尾添加元素
		//添加成功返回true,添加失败引发异常
		q.add("aa");
		q.offer("bb");
		//添加成功返回true,添加失败引发异常
		q.offer("cc");
		System.out.println(q);
		q.forEach(System.out::println);
		//出队
		//删除失败引发异常
//		System.out.println(q.remove());
		//删除失败,返回null
//		System.out.println(q.poll());
//		System.out.println(q.poll());
//		System.out.println(q);
		while(q.size() > 0){
//			System.out.println(q.poll());
			System.out.println(q.peek());
		}
	}
}

十二、PriorityQueue类

1.介绍

  • 优先队列:元素按照一定优先级排列过的队列。
  • 违背了队列先进先出的原则。

2.示例

import java.util.PriorityQueue;
import java.util.Queue;
public class TestPriorityQueue {
	public static void main(String[] args) {
		//优先队列
		//默认自然升序
		Queue<String> q = new PriorityQueue<>((s1,s2)->s2.compareTo(s1));
		q.add("bb");
		q.add("aa");
		q.add("cc");
//		q.add(null);//报错:空指针异常。
		//出队
		while(q.size() > 0){
			System.out.println(q.poll());
		}
	}
}

十三、Deque 接口

1.介绍

  • 双向队列,前后都可以操作。
  • 可以用于构建队列,也可以用来构建栈结构。
  • 栈:后进先出。方法包括push和pop,即压栈和弹栈。

2.常用方法

添加 删除 获取列表头元素 操作失败时

addFirst

addLast

removeFirst

removeLast

getFirst

getLast

会产生异常

offerFirst

offerLast

pollFirst

pollLast

peekFirst

peekLast

不会产生异常,而是返回特定的值

3.示例

import java.util.ArrayDeque;
import java.util.Deque;
public class TestDeque {
	public static void main(String[] args) {
		//队列:先进先出
		Deque<String> q = new ArrayDeque<>();
		//入队
		q.addLast("aa");
		q.add("bb");
		q.offer("cc");
		q.offerLast("dd");
		//出队
		while(q.size() > 0){
			System.out.println(q.pollFirst());
//			System.out.println(q.poll());
		}
		//栈:后进先出
		Deque<String> q1 = new ArrayDeque<>();
		//入栈
		/*q1.addFirst("aa");
		q1.offerFirst("bb");
		q1.offerFirst("cc");*/
		q1.push("aa");
		q1.push("bb");
		q1.push("cc");
		//出栈
		while(q1.size() > 0){
//			System.out.println(q1.pollFirst());
//			System.out.println(q1.poll());
			System.out.println(q1.pop());
		}
	}
}

十四、Map 接口

1.介绍

  • 是一个接口,映射,键值对。
  • 子接口包括SortedMap、NavigableMap;
  • 实现类包括HashMap、LinkedHashMap、HashTable、Priority(优先队列)、TreeMap
  • Set是通过Map创建的,是一个只有键的Map。
  • 继承层次图,如下:

2.常用方法

  • size():键值对的数目
  • isEmpty():是否为空
  • containsKey():指定的参数的键对应的键值对信息是否包含在集合中,存在返回true
  • containsValue():指定的参数的值对应的键值对信息是否包含在集合中,存在返回true
  • remove():根据指定的键删除对应的键值对
  • keySet():键是唯一,都是Set,获得键的集合
  • values():获得值的集合
  • clear():清空

示例

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class TestMap {
	public static void main(String[] args) {
		//Map
		//Hash表的数组初始容量是16
		HashMap<Integer, String> map = new HashMap<>();
		Set<String> set = new HashSet<>();//可以看到底层调用的就是HashMap
		//size() 键值对的数目
		System.out.println(map.size());
		//空的 true
		System.out.println(map.isEmpty());
		//添加
		map.put(11, "aa");
		map.put(22, "bb");
		map.put(33, "cc");
		System.out.println(map);
		//键是唯一,都是Set,获得键的集合
		System.out.println(map.keySet());
		//获得值的集合
		System.out.println(map.values());
		//指定的参数的键对应的键值对信息是否包含在集合中,存在返回true
		System.out.println(map.containsKey(11));
		//指定的参数的值对应的键值对信息是否包含在集合中,存在返回true
		System.out.println(map.containsValue("aa"));
		//根据指定的键删除对应的键值对
		map.remove(33);
		//替换(修改)
		map.replace(11, "hello");
		System.out.println(map);
		map.clear();
		System.out.println(map.size());
	}
}

3.HashMap类

  • 默认的初始容量: 16 (数组长度)(static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;)
  • 最大的容量:1*2^30(static final int MAXIMUM_CAPACITY = 1 << 30;)
  • 负载因子: 0.75(static final float DEFAULT_LOAD_FACTOR = 0.75f;),控制是否扩容的量
  • 键值个数 :size 0
  • 数组的容量:length 16
  • 负载因子; 0.75 size / length
  • 扩容: 2倍扩容(从源码中得知)

注:HashMap的源码要认真阅读

4.遍历Map

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

public class TestMap {
	public static void main(String[] args) {
		HashMap<Integer, String> map = new HashMap<>();
		//添加
		map.put(11, "aa");
		map.put(22, "bb");
		map.put(33, "cc");
//		System.out.println(map);
		map.put(33, "hello");
//		System.out.println(map);
		//遍历
		//1.集合forEach方法
		/*map.forEach(new BiConsumer<Integer, String>() {
			@Override
			public void accept(Integer t, String u) {
				System.out.println(t + ":" + u); 
			}
		});*/
		map.forEach((k,v)->System.out.println(k + ":" + v));//lambda表达式
		//2.Iterator
		/*map.keySet().iterator().forEachRemaining(new Consumer<Integer>() {
			@Override
			public void accept(Integer t) {
				System.out.println(t);
			}
		});*/
		map.keySet().iterator().forEachRemaining(System.out::println);
		/*map.values().iterator().forEachRemaining(new Consumer<String>(){
			@Override
			public void accept(String t) {
				System.out.println(t);
			}
		});*/
		map.values().iterator().forEachRemaining(System.out::println);
		//3.键值对的遍历Entry
		Iterator<Entry<Integer, String>> it = map.entrySet().iterator();
		while(it.hasNext()){
			Entry<Integer, String> e = it.next();
			System.out.println(e.getKey() + ":" + e.getValue());
		}
	}
}

5.比较HashMap、HashTable、LinkedHashMap、TreeMap

  • HashMap底层是哈希表,无序,可以添加空键空值,是线程非安全的。
  • HashTable是线程安全的,无序,但性能差,一般不用。
  • LinkedHashMap底层是链表和哈希表,有序,由链表维护添加顺序。
  • TreeMap底层是二叉树,默认顺序是自然升序,可以自定义排序规则。

十五、Stream 流操作

1.介绍

  • 可以在流中存储并操作数据。
  • 提供了对数据的聚集操作,也就是统计性操作。
  • 特点:用流中的方法进行计算,速度快。

2.常用方法

末端方法:统计出一个最终的结果,流就被消耗掉了,也就是释放了,不能再用了。包括

  • max():最大值
  • min():最小值
  • sum():总和
  • average():平均值
  • count():流中元素的个数
  • allMatch():流中所有元素都满足条件,结果是true,否则为false
  • anyMatch():流中只要有一个元素满足条件,结果就是true,否则false

末端方法示例:

import java.util.stream.IntStream;
public class TestStream {
	public static void main(String[] args) {
		//Stream
		//创建一个IntStream
		IntStream i = IntStream.builder().add(11).add(22).add(33).add(44).build();
		//末端方法
//		System.out.println(i.max());
		//最大值
//		System.out.println(i.max().getAsInt());
		//最小值
//		System.out.println(i.min().getAsInt());
		//总和
//		System.out.println(i.sum());
		//平均值
//		System.out.println(i.average().getAsDouble());
		//流中元素的个数
//		System.out.println(i.count());
		//流中所有元素都满足条件,结果是true,否则为false
		/*System.out.println(i.allMatch(new IntPredicate() {
			
			@Override
			public boolean test(int value) {
				// TODO Auto-generated method stub
				return value > 33;
			}
		}));*/
//		System.out.println(i.allMatch(v->v>3));
		//流中只要有一个元素满足条件,结果就是true,否则false
		System.out.println(i.anyMatch(v->v>33));
	}
}

中间方法:使用中间方法可以得到一个新的流,新的流可以继续调用方法进行操作。包括

  • filter():过滤
  • map/mapToInt/mapToLong/mapToDouble():映射
  • distinct():去除重复的元素
  • sorted():排序
  • peek():作用与forEach一样,peek是中间方法,forEach是末端方法
  • limit():取前几个数据
  • skip():略过前几个数据

中间方法示例:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.ToIntFunction;
class Student implements Comparable<Student>{
	private String name;
	private int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Student arg0) {
		// TODO Auto-generated method stub
		return this.age - arg0.age;
	}
}
public class TestStream3 {
	public static void main(String[] args) {
		//中间方法
		List<Student> list = new ArrayList<>();
		Student guojing = new Student("郭靖",22);
		Student yangkang = new Student("杨康",21);
		Student huangrong = new Student("黄蓉",19);
		Collections.addAll(list, guojing,yangkang,huangrong,huangrong,guojing,yangkang);
		list.stream().forEach(System.out::println);
		//中间方法,返回一个值
		//1.过滤
		list.stream().filter(stu->stu.getAge()>20).forEach(System.out::println);
		//2.映射
		list.stream().map(new Function<Student, String>(){
			@Override
			public String apply(Student t) {
				return t.getName();
			}
		}).forEach(System.out::println);
		list.stream().mapToInt(new ToIntFunction<Student>() {
			@Override
			public int applyAsInt(Student value) {
				return value.getAge();
			}
		}).forEach(System.out::println);
		//3.
//		list.stream().forEach(System.out::println);
		//3.去除重复的元素
		list.stream().distinct().forEach(System.out::println);
		//4.排序
		list.stream().sorted().forEach(System.out::println);
		//5.peek作用与forEach一样,peek是中间方法,forEach是末端方法
		list.stream().peek(System.out::println).forEach(System.out::println);
		System.out.println(list.stream().peek(System.out::println).count());
		//取前几个数据
		list.stream().limit(2).forEach(System.out::println);
		//7.略过前几个数据
		list.stream().skip(1).forEach(System.out::println);
	}
}

十六、Predicate 过滤器接口

直接看例程:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
class Child{
	private String name;
	private int age;
	public Child(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Child [name=" + name + ", age=" + age + "]";
	}
}
public class TestPredicate {
	public void childInfo(List<Child> list, Predicate<Child> p){
		for (Child child : list) {
			if(p.test(child)){
				System.out.println(child);
			}
		}
	}
	public static void main(String[] args) {
		List<Child> list = new ArrayList<>();
		list.add(new Child("guojing" ,22));
		list.add(new Child("yankan" ,33));
		list.add(new Child("huangrong" ,20));
		TestPredicate t = new TestPredicate();
		t.childInfo(list, e->e.getAge()>30 && e.getName().contains("g"));
	}
}

猜你喜欢

转载自blog.csdn.net/qq_1018944104/article/details/82839561