集合
- 集合和数组的对比:
1.数组的长度是不可变的,集合的长度是可变的
2.数组可以存基本数据类型和引用数据类型,集合只能存储引用数据类型,如果要存储基本数据类型,需要存对应的包装类
Collection
- Collection是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
Collection集合常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
boolean removeIf(Object o) | 根据条件进行删除 |
void clear() | 清空集合 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合长度,也就是集合中元素的个数 |
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author DW-CHEN
* 单列集合Collection
*/
public class Demo45 {
public static void main(String[] args) {
Collection<Integer> collection = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
collection.add(i);
}
System.out.println("添加数据后的集合:"+collection);
System.out.println("从集合中移除指定的元素4:" + collection.remove(4) +" "+ collection);
boolean b = collection.removeIf((Integer i) -> {
return i == 3;
});
System.out.println("根据条件进行删除,条件元素为3进行删除:" + b + " " + collection);
System.out.println("集合中是否包含指定的元素5:" + collection.contains(5) + " " + collection);
System.out.println("集合是否为空:" + collection.isEmpty() + " " + collection);
System.out.println("集合长度:" + collection.size() + " " + collection);
collection.clear();
System.out.println("清空集合后的集合:" + collection);
}
}
Collection集合遍历
Iterator:迭代器
Iterator< E > iterator():返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引
Iterator常用方法
方法名 | 说明 |
---|---|
boolean hasNext() | 判断当前位置是否有元素被取出 |
E next() | 获取当前位置的元素,将迭代器对象移向下一个索引位置 |
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author DW-CHEN
* 迭代器Iterator
*/
public class Demo46 {
public static void main(String[] args) {
Collection<Integer> collection = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
collection.add(i);
}
Iterator<Integer> iterator = collection.iterator();//遍历
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
迭代器的删除方法
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author DW-CHEN
* 迭代器的删除方法
*/
public class Demo47 {
public static void main(String[] args) {
Collection<Integer> collection = new ArrayList<>();
collection.add(1);
collection.add(2);
collection.add(2);
collection.add(3);
Iterator<Integer> iterator = collection.iterator();
while (iterator.hasNext()) {
if (2 == iterator.next()) {//日过有2这个元素,则删除
iterator.remove();
}
}
System.out.println(collection);
}
}
增强for循环
简化了数组和Collection集合的遍历
- 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
- 实现Iterator接口的类才可以使用迭代器和增强for
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author DW-CHEN
* 增强for循环
*/
public class Demo48 {
public static void main(String[] args) {
Collection<Character> collection = new ArrayList<>();
for (int i = 0; i < 26; i++) {
collection.add((char) ('a' + i));//添加a-z到集合
}
for (Character character : collection) {//遍历
System.out.println(character);
}
}
}
- 定义学生对象存储到集合中并遍历
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;
/**
* @author DW-CHEN
* 定义学生对象存储到集合中并遍历
*/
public class Demo49 {
public static void main(String[] args) {
Collection<Student3> collection = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 2; i++) {//键盘录入2个学生对象数据存储到集合
System.out.print("请输入第"+ (i+1)+"个学生的姓名:");
String name = scanner.next();
System.out.print("请输入第"+ (i+1)+"个学生的年龄:");
Integer age = scanner.nextInt();
Student3 student3 = new Student3(name, age);
collection.add(student3);
}
System.out.println("=========================迭代器方式遍历==============================");
Iterator<Student3> iterator = collection.iterator();
while (iterator.hasNext()) {
Student3 student3 = iterator.next();
System.out.println("姓名:" + student3.getName() + " 年龄:" + student3.getAge());
}
System.out.println("=========================增强for方式遍历==============================");
for (Student3 student3 : collection) {
System.out.println("姓名:" + student3.getName() + " 年龄:" + student3.getAge());
}
}
}
class Student3{
private String name;
private Integer age;
public Student3(){
}
public Student3(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
三种循环的使用场景
- 如果需要操作索引,使用普通的for循环
- 如果遍历的过程中需要删除元素,使用迭代器
- 如果仅仅是想遍历,使用增强for循环
List
- 有序集合,这里的有序是指存取顺序
- 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表允许重复的元素
List集合特点
- 有序,存储和取出的元素顺序一致
- 有索引,可以通过索引操作元素
- 可重复,存储的元素可以重复
List集合特有的方法
方法名 | 说明 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.List;
/**
* @author DW-CHEN
* List集合
*/
public class Demo50 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
list.add(i);
}
System.out.println("添加了6个元素到集合中后的集合:" + list);
list.add(0, 00);
System.out.println("在指定0索引处添加一个00元素后的集合:" + list);
System.out.println("删除指定0索引的的元素:"+list.remove(0) + " " + list);
System.out.println("设置指定的第5个索引的的元素修改为66:"+list.set(5, 66) + " " + list);
System.out.println("获得指定的第5个索引处的元素:"+list.get(5));
}
}
数据结构
数据结构是计算存储,组织数据的方式。指相互之间存在一种或多种特定关系的数据元素和集合,选择合适的数据结构可以给我们带来更高的运行或者存储效率
- 栈:先进后出
- 队列:先进先出
- 数组:查询块,增删慢
- 链表:查询慢,增删块
List集合常用实现类
- ArrayList:底层数据结构是数组,查询快,增删慢
- LinkedList:底层数据结构是列表,查询慢,增删快
ArrayList
底层的数据结构是数组,查询快,增删慢
package cn.cdw.demo;
import java.util.ArrayList;
/**
* @author DW-CHEN
* ArrayList
*/
public class Demo51 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
arrayList.add(i);
}
System.out.println(arrayList);
}
}
LinkedList
底层数据结构是列表,查询慢,增删快
Linked集合的特有功能
方法名 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
package cn.cdw.demo;
import java.util.LinkedList;
/**
* @author DW-CHEN
* LinkedList
*/
public class Demo52 {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
for (int i = 1; i <= 6; i++) {
linkedList.add(i);
}
System.out.println(linkedList);
}
}
泛型
JDK5中引入的特征,它提供了编译时类型安全检测机制
- 泛型的好处
- 把运行时期的问题提前到编译时期
- 避免了强制类型转换
-
泛型可以使用的地方
1.类后面:修饰符 class 类名<类型> { }
2.方法声明上: 修饰符<类型> 返回值类型 方法名(类名 变量名){ }
3.接口后面 : 修饰符 interface 接口名<类型> { } -
类型的通配符<?>
- 类型通配符上限:<? extends 类型>
- 类型通配符下限:<? super 类型>
Set
无须
无索引
不重复
Set集合的特点
- 可以去除重复元素
- 存取顺序不一致
- 没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取/删除Set集合的元素
package cn.cdw.demo;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author DW-CHEN
* Set
*/
public class Demo53 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
for (int i = 1; i <= 6; i++) {
set.add(i);
}
System.out.println(set);
for (int i = 1; i <= 6; i++) {//添加重复元素
set.add(i);
}
System.out.println(set);
for (Integer s : set) {//增强for遍历
System.out.println(s);
}
System.out.println("======================================================================");
Iterator<Integer> iterator = set.iterator();//迭代器遍历
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
TreeSet
底层数据结构:红黑树,必须给定排序规则
TreeSet集合特点
- 不包含重复元素的集合
- 没有带索引的方法
- 可以将元素按照规则进行排序
自然排序Comparable
- 使用空参构造创建TreeSet集合
- 自定义的学生类对象实现Comparable接口
- 重写compareTo方法
在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序
package cn.cdw.demo;
import java.util.TreeSet;
/**
* @author DW-CHEN
* 排序之Comparable
* 在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序
*/
public class Demo54 {
public static void main(String[] args) {
TreeSet<Student4> treeSet = new TreeSet<>();
Student4 s1 = new Student4("c", 12);
Student4 s2 = new Student4("b", 12);
Student4 s3 = new Student4("a", 15);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
for (Student4 student4 : treeSet) {//遍历
System.out.println("姓名:" + student4.getName() + " 年龄:" + student4.getAge());
}
}
}
class Student4 implements Comparable<Student4>{
private String name;
private Integer age;
public Student4(){
}
public Student4(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public int compareTo(Student4 o) {
int result = this.age - o.age;
result = result == 0 ? this.name.compareTo(o.name) : result;//如果年龄相同根据姓名字母排序
return result;
}
}
比较器排序Comparator
- TreeSet的带参数构造方法使用的时比较强排序对元素进行排序的
- 比较强排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件写
在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序
package cn.cdw.demo;
import java.util.TreeSet;
/**
* @author DW-CHEN
* 排序之comparator
* 在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序
*/
public class Demo55 {
public static void main(String[] args) {
/* Comparator<Student5> comparator = new Comparator<Student5>() {//方式一:外部定义比较器
@Override
public int compare(Student5 o1, Student5 o2) {
int result = o1.getAge() - o2.getAge();
result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
return result;
}
};
TreeSet<Student5> treeSet = new TreeSet<>(comparator);*/
/*TreeSet<Student5> treeSet = new TreeSet<>(new Comparator<Student5>() {//方式二:使用匿名内部类直接在参数中定义比较器
@Override
public int compare(Student5 o1, Student5 o2) {
int result = o1.getAge() - o2.getAge();
result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
return result;
}
});*/
TreeSet<Student5> treeSet = new TreeSet<>((Student5 o1, Student5 o2) -> {//方式三:使用lambda表达式直接在参数中定义比较器
int result = o1.getAge() - o2.getAge();
result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
return result;
});
Student5 s1 = new Student5("c", 12);
Student5 s2 = new Student5("b", 12);
Student5 s3 = new Student5("a", 15);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
for (Student5 student5 : treeSet) {//遍历
System.out.println("姓名:" + student5.getName() + " 年龄:" + student5.getAge());
}
}
}
class Student5 {
private String name;
private Integer age;
public Student5() {
}
public Student5(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
两种比较方式结论
- 自然排序:自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
- 比较器排序:创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
- 在使用的时候,默认使用自然排序,当自然排序不满足现在需求时,使用比较器排序
两种方式中,关于返回值的规则
- 如果返回值为负数,表示当前存入的元素时较小值,存左边
- 如果返回值为0,表示当前存入的元素跟集合中的元素重复了,不存
- 如果返回值为正数,表示当前存入的元素时较大值,存右边
对TreeSet集合中不同长度的字符串进行从段到长进行排序,如果长度相同则根据字母自然排序
package cn.cdw.demo;
import java.util.TreeSet;
/**
* @author DW-CHEN
* 对TreeSet集合中不同长度的字符串进行从段到长进行排序,如果长度相同则根据字母自然排序
*/
public class Demo56 {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>((String s1,String s2) -> {
int result = s1.length() - s2.length();
result = result == 0 ? s1.compareTo(s2) : result;
return result;
});
String s1 = "da";
String s2 = "daed";
String s3 = "dda";
String s4 = "daad";
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
for (String s : treeSet) {//b遍历
System.out.println(s);
}
}
}
HashSet
- 底层数据结构:哈希表,重写hashCode和equals方法
JDK8之前,底层采用数组 + 链表实现
JDK8之后,底层进行了优化,由数组 + 链表 + 红黑树实现
HashSet集合特点
- 底层数据结构时哈希表
- 存取顺序不一致
- 没有带索引的方法,索引不能使用普通for循环遍历
- 元素不重复
package cn.cdw.demo;
import java.util.HashSet;
/**
* @author DW-CHEN
* HashSet
*/
public class Demo57 {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
for (int i = 1; i <= 6; i++) {
hashSet.add(i);
}
System.out.println(hashSet);
for (Integer i : hashSet) {
System.out.println(i);
}
}
}
哈希值
是JDK根据对象的地址或者属性值,算出来的int类型的整数
- 获取对象的哈希值:public int hashCode();
对象的哈希值特点
- 如果没有重写hashCode方法,那么根据对象的地址值算出哈希值。同一个对象多次调用hashCode()方法返回的哈希值是相同的,不同的对象的哈希值是不一样的
- 如果重写了hashCode方法,一般都是通过对象的属性值计算出哈希值。如果不同对象的属性值一样,那么计算出来的哈希值也是一样的
在HashSet 集合中存储学生对象,如果姓名和年龄都相同,那么不存储(需重写hashCode方法)
package cn.cdw.demo;
import java.util.HashSet;
/**
* @author DW-CHEN
* 在HashSet 集合中存储学生对象,如果姓名和年龄都相同,那么不存储(需重写hashCode方法)
*/
public class Demo58 {
public static void main(String[] args) {
HashSet<Student6> hashSet = new HashSet<>();
Student6 s1 = new Student6("小明", 12);
Student6 s2 = new Student6("小明", 12);
Student6 s3 = new Student6("小小", 21);
hashSet.add(s1);
hashSet.add(s2);
hashSet.add(s3);
for (Student6 student6 : hashSet) {
System.out.println("姓名:" + student6.getName() + " 年龄:" + student6.getAge());
}
}
}
class Student6 {
private String name;
private Integer age;
public Student6() {
}
public Student6(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student6 student6 = (Student6) o;
if (!name.equals(student6.name)) return false;
return age.equals(student6.age);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age.hashCode();
return result;
}
}
Map
- Interface Map<K,V> -------------K:键的数据类型,V:值的数据类型
- 键不能重复,值可以重复
- 键和值一一对应的,每一个键只能找到自己对应的值
- (键 + 值)这个整体称为 ”键值对" 或者 “键值对对象”,在Java中叫做 “entry对象”
package cn.cdw.demo;
import java.util.HashMap;
import java.util.Map;
/**
* @author DW-CHEN
* 双列集合Map
*/
public class Demo59 {
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
for (int i = 1; i <= 6; i++) {
map.put(("s") + i, i);
}
System.out.println(map);
}
}
Map集合的基本功能
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 清空所有的键值对元素 |
boolean containsKey(Object key) | 判断集合中是否包含指定的键 |
boolean containsValue(Object value) | 判断集合中是否包含指定的值 |
boolean inEmpty() | 判断集合是否为空 |
int size() | 集合的长度,就是集合中键值对的个数 |
package cn.cdw.demo;
import java.util.HashMap;
import java.util.Map;
/**
* @author DW-CHEN
* Map
*/
public class Demo60 {
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
for (int i = 1; i <= 6; i++) {
map.put("s" + i, i);
}
System.out.println("在map集合中添加数据后的map:"+map);
System.out.println("map集合中根据指定的键删除键为s1的数据进行删除后的map:" + map.remove("s1") + " " + map);
System.out.println("是否包含指定的键s1的键在map中:"+map.containsKey("s1")+" "+map);
System.out.println("是否包含指定的键2的值在map中:" + map.containsValue(2) + " " + map);
System.out.println("map是否为空:" + map.isEmpty() + " " + map);
System.out.println("map的长度: "+map.size() + " "+map);
map.clear();
System.out.println("清空后的map:"+map);
}
}
Map集合的获取功能(遍历)
方法名 | 说明 |
---|---|
Set< K > keySet | 获取所有的键集合 |
V get(Object key) | 根据键获取值 |
Set<Map.Entry<K,V> >entrySet() | 获取所有键值对对象的集合 |
K getKey() | 获得键 |
V getValue() | 获得值 |
package cn.cdw.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author DW-CHEN
* 遍历map集合
*/
public class Demo61 {
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
for (int i = 1; i <= 6; i++) {
map.put("s" + i, i);
}
Set<String> keySet = map.keySet();//方式一遍历
for (String key : keySet) {
System.out.println("key:" + key + " value:" +map.get(key));
}
System.out.println("========================================================================");
Set<Map.Entry<String, Object>> entries = map.entrySet();//方式二遍历
for (Map.Entry<String, Object> entry : entries) {
System.out.println("key:" + entry.getKey() + " value:" + entry.getValue());
}
}
}
HashMap
HashMap的特点
- HashMap是Map里面的一个实现类,直接使用Map里面的方法就可以了
- HashMap和HashSet底层都是哈希表结构
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键存储的是自定义对象,需要重写hashCode和equals方法保证键的唯一
HashMap中存储自定义学生对象,然后遍历
package cn.cdw.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author DW-CHEN
* HashMap中存储自定义学生对象,然后遍历
*/
public class Demo62 {
public static void main(String[] args) {
Map<String, Student7> map = new HashMap<>();
Student7 s1 = new Student7("小明", 12);
Student7 s2 = new Student7("小明", 12);
Student7 s3 = new Student7("小李", 21);
map.put("s1", s1);
map.put("s2", s2);
map.put("s3", s3);
Set<String> keySet = map.keySet();//方式一遍历,keySet
for (String key : keySet) {
System.out.println(key + "----------" + "姓名:" + map.get(key).getName() + " 年龄:" + map.get(key).getAge());
}
System.out.println("===========================================================================================");
Set<Map.Entry<String, Student7>> entries = map.entrySet();//方式二遍历,entrySet
for (Map.Entry<String, Student7> entry : entries) {
System.out.println(entry.getKey() + "----------" + "姓名:" + entry.getValue().getName() + " 年龄:" + entry.getValue().getAge());
}
System.out.println("===========================================================================================");
map.forEach((String key,Student7 value) -> {//方式三遍历,lambda表达式
System.out.println(key + "----------"+ "姓名:"+value.getName() + " 年龄:"+value.getAge());
});
}
}
class Student7 {
private String name;
private Integer age;
public Student7() {
}
public Student7(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
TreeMap
TreeMap的特点
- TreeMap是Map里面的一个实现类,直接使用Map里面的方法就可以了
- TreeMap和TreeSet底层都是红黑树结构
- 依赖自然排序或者比较强排序,对键进行排序
- 如果键存储的是自定义对象,需要实现Comparable接口或者创建TreeMap对象的时候给出比较器排序规则
在TreeMap集合中存储自定义学生对象,遍历根据年龄排序,如果年龄相同则根据姓名字母排序
package cn.cdw.demo;
import java.util.TreeMap;
/**
* @author DW-CHEN
* 在TreeMap集合中存储自定义学生对象,遍历根据年龄排序,如果年龄相同则根据姓名字母排序
*
* 排序:Comparable/Comparator
*/
public class Demo63 {
public static void main(String[] args) {
TreeMap<Student8,String> treeMap = new TreeMap<>();
Student8 s1 = new Student8("a", 12);
Student8 s2 = new Student8("c", 21);
Student8 s3 = new Student8("ab", 12);
treeMap.put(s1, "深圳");
treeMap.put(s2, "北京");
treeMap.put(s3, "上海");
treeMap.forEach((Student8 key,String value)->{
System.out.println(key+"----------"+value);
});
}
}
class Student8 implements Comparable<Student8> {
private String name;
private Integer age;
public Student8() {
}
public Student8(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student8{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student8 o) {
int result = this.age - age;
result = result == 0 ? this.name.compareTo(o.name) : result;
return result;
}
}
可变参数
就是形参的个数是可以变化的
格式:修饰符 返回值类型 方法名(数据类型… 变量名){ }
注意:
- 这里的变量其实就是一个数组
- 如果这个方法有多个参数,包含可变参数,可变参数要放到最后
使用可变参数计算n个数的和
package cn.cdw.demo;
/**
* @author DW-CHEN
* 使用可变参数计算n个数的和
*/
public class Demo64 {
public static void main(String[] args) {
method(1,2,3,4,5);
}
public static void method(int... ints) {
int sum =0;
for (int i : ints) {
sum +=i;
}
System.out.println("计算的总和为:"+sum);
}
}
Stream流
将集合中开头为 将开头为 “小” 长度为3的存储到另一个集合中并遍历
package cn.cdw.demo;
import java.util.ArrayList;
/**
* @author DW-CHEN
* Stream流
*
* 将集合中开头为 将开头为 “小” 长度为3的存储到另一个集合中并遍历
*/
public class Demo65 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
ArrayList<String> arrayList1 = new ArrayList<>();
ArrayList<String> arrayList2 = new ArrayList<>();
arrayList.add("小明");
arrayList.add("小小名");
arrayList.add("小小红");
arrayList.add("张三");
System.out.println("======================常规方式========================");
for (String s : arrayList) {
if (s.startsWith("小")) {
arrayList1.add(s);
}
}
for (String s : arrayList1) {
if (s.length() == 3) {
arrayList2.add(s);
}
}
for (String s : arrayList2) {
System.out.println(s);
}
System.out.println();
System.out.println("======================Stream流方式========================");
arrayList.stream().filter(s -> s.startsWith("小")).filter(s -> s.length() == 3).forEach(s -> {
System.out.println(s);
});
}
}
Stream流的三类方法
- 获取Stream流:创建一个流水线,并把数据放到流水线上准备进行操作
- 中间方法:流水线上的操作,一次操作完毕之后,还可以继续进行其他的操作
- 终结方法:一个Stream只能有一个终结方法,是流水线上的最后一个操作
Stream流的获取方法
- 单列集合:default Stream< E > stream()
- 双列集合:间接生成流,先通过keySet或者entrySet获取一个Set集合,在获取Stream流
- 数组:Arrays中的静态方法stream生成流
- 同种数据类型的多个数据:Stream.of(T… values)生成流
package cn.cdw.demo;
import java.util.*;
import java.util.stream.Stream;
/**
* @author DW-CHEN
* Stream流的获取方法
*/
public class Demo66 {
public static void main(String[] args) {
System.out.println("======================单列集合获取Stream流=============================");
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("aa");
arrayList.add("cc");
arrayList.add("dd");
arrayList.stream().forEach(s -> { //单列集合获取Stream流
System.out.println(s);
});
System.out.println();
System.out.println("======================双列集合获取Stream流=============================");
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("s1","aa");
hashMap.put("s2","cc");
hashMap.put("s3","dd");
hashMap.keySet().stream().forEach(s -> {
System.out.println(s + "=" + hashMap.get(s));
});
System.out.println("==============================");
hashMap.entrySet().stream().forEach(s -> {
System.out.println(s);
});
System.out.println();
System.out.println("======================数组获取Stream流=============================");
int[] arr = {1,2,3,4,5,6};
Arrays.stream(arr).forEach(s -> {
System.out.println(s);
});
System.out.println();
System.out.println("======================同种数据类型的多个数据获取Stream流=============================");
Stream.of(1, 3, 5, 6, 7).forEach(s -> {
System.out.println(s);
});
}
}
Stream流的常见中间操作方法
- Stream< T >filter(Predicate predicate):对流中的数据进行过滤
Predicate接口中的方法:boolean test(T t)对给定的参数进行判断,返回一个布尔值
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.function.Predicate;
/**
* @author DW-CHEN
* Stream流的常见中间操作方法filter
*
* 将集合中开头为“小”的查询遍历出来
*/
public class Demo67 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("小明");
arrayList.add("小里");
arrayList.add("张张");
System.out.println();
System.out.println("=====================方式一:使用匿名内部类============================");
arrayList.stream().filter(new Predicate<String>() {//方式一:使用匿名内部类
@Override
public boolean test(String s) {
boolean b =s.startsWith("小");
return b;
}
}).forEach(s -> {
System.out.println(s);
});
System.out.println();
System.out.println("=====================方式二:Lambda表达式============================");
arrayList.stream().filter((String s) -> {
boolean b = s.startsWith("小");
return b;
}).forEach(s -> {
System.out.println(s);
});
System.out.println();
System.out.println("=====================方式三:Lambda表达式简化============================");
arrayList.stream().filter(s -> s.startsWith("小")).forEach(s -> {
System.out.println(s);
});
}
}
方法名 | 说明 |
---|---|
Stream< T > limit(long maxSize) | 截取指定参数个数的数据 |
Stream< T > skip(long n) | 跳过指定参数个数的数据 |
static< T > Stream< T > concat(Stream a,Stream b) | 合并a和b两个流为一个流 |
Stream< T > distinct() | 去除流中重复的元素,(依赖hashCode和equals方法) |
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.stream.Stream;
/**
* @author DW-CHEN
* Stream流常见的中间操作方法
*/
public class Demo68 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
ArrayList<Integer> arrayList1 = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
arrayList.add(i);
}
for (int i = 7; i <= 10; i++) {
arrayList1.add(i);
}
arrayList.stream().limit(2).forEach(s -> { //截取集合前面两个数据
System.out.println(+s);
});
System.out.println();
System.out.println("===========================================================");
arrayList.stream().skip(2).forEach(s -> {//跳过集合前面两个参数
System.out.println(s);
});
System.out.println();
System.out.println("===========================================================");
Stream<Integer> concat = Stream.concat(arrayList.stream(), arrayList1.stream());//合并两个流为一个流
concat.forEach(s -> {
System.out.println(s);
});
System.out.println();
System.out.println("===========================================================");
arrayList.add(5);
arrayList.add(6);
System.out.println("没有去重复元素前:"+arrayList);
System.out.println("去除重复元素之后:" );
arrayList.stream().distinct().forEach(s -> {
System.out.println(s);
});
}
}
Stream流常见终结操作方法
-
void forEach(Consumer action):对此流的每个元素指向操作
Consumer接口中的方法------------void accept(T t):对给定的参数执行此操作 -
long count() :返回此流中的元素个数
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.function.Consumer;
/**
* @author DW-CHEN
* Stream常见的终结操作方法
*/
public class Demo69 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
arrayList.add(i);
}
System.out.println();
System.out.println("=====================方式一:使用匿名内部类============================");
arrayList.stream().forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
System.out.println();
System.out.println("=====================方式二:Lambda表达式============================");
arrayList.stream().forEach((Integer i) -> {
System.out.println(i);
});
System.out.println();
System.out.println("=====================方式三:Lambda表达式简化============================");
arrayList.stream().forEach(i -> {
System.out.println(i);
});
System.out.println();
System.out.println("=====================返回此流中元素个数============================");
Long count = arrayList.stream().count();
System.out.println(count);
}
}
集合中存储1到10,使用流输出偶数
package cn.cdw.demo;
import java.util.ArrayList;
/**
* @author DW-CHEN
* 集合中存储1到10,使用流输出偶数
*/
public class Demo70 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
arrayList.add(i);
}
arrayList.stream().filter(s -> s %2 == 0).forEach(s -> {
System.out.println(s);
});
}
}
Stream流的收集操作
- Stream流的收集方法: R collect(Collector collector)
工具类Collectors提供了具体的收集方式
方法名 | 说明 |
---|---|
public static < T > Collector toList() | 把元素收集到List集合中 |
public static < T > Collector toSet() | 把元素集合收集到Set集合中 |
public static Collector toMap(Function keyMapper,Function valuesMapper) | 把元素收集到Map集合中 |
Stream流的收集操作(单列集合)
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author DW-CHEN
* Stream流的收集操作(单列集合)
*/
public class Demo71 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
arrayList.add(i);
}
System.out.println("================将Stream流中的偶数存储到list集合====================");
List<Integer> list = arrayList.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());
System.out.println(list);
System.out.println();
System.out.println("================将Stream流中的奇数存储到Set集合====================");
arrayList.add(1);
arrayList.add(3);
System.out.println("没有去除重复元素:" + arrayList);
Set<Integer> set = arrayList.stream().filter(i -> i % 2 != 0).collect(Collectors.toSet());
System.out.println(set);
}
}
Stream流的收集操作(双列集合)
package cn.cdw.demo;
import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author DW-CHEN
* Stream流的收集操作(双列集合)
*
* 将姓名和年龄存储到一个集合中,姓名和年龄使用逗哈隔开,将年龄大于23岁的保存到map集合中
*/
public class Demo72 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("小明,21");
arrayList.add("小李,25");
arrayList.add("小小,26");
Map<String, Integer> map = arrayList.stream().filter(s -> {
String[] sp = s.split(",");
Integer age = Integer.valueOf(sp[1]);
return age > 23; //过滤条件
}).collect(Collectors.toMap(
s -> s.split(",")[0],//key
s -> Integer.valueOf(s.split(",")[1])//value
));
System.out.println(map);
}
}