【JavaSE复习】数据结构、集合

JavaSE 复习

  • 1.数据结构
    • 1.1 查找
      • 1.1.1 基本查找
      • 1.1.2 二分查找
      • 1.1.3 插值查找
      • 1.1.4 斐波那契查找
      • 1.1.5 分块查找
      • 1.1.6 分块查找的扩展(无规律数据)
    • 1.2 排序
      • 1.2.1 冒泡排序
      • 1.2.2 选择排序
      • 1.2.3 插入排序
      • 1.2.4 快速排序
  • 2. 集合
    • 2.1 基础集合
      • 2.1.1 集合和数组的对比
      • 2.1.2 ArrayList
    • 2.2 单列集合
      • 2.2.1 Collection单列集合
        • 2.2.1.1 Collection的遍历方式一:迭代器遍历
        • 2.2.1.2 Collection的遍历方式二:增强for遍历
        • 2.2.1.3 Collection的遍历方式三:Lambda表达式遍历
      • 2.2.2 List集合
        • 2.2.2.1 迭代器遍历
        • 2.2.2.2 增强for遍历方式
        • 2.2.2.3 Lambda表达式方式
        • 2.2.2.4 普通for循环
        • 2.2.2.5 列表迭代器
        • 2.2.2.6 五种遍历方式对比
      • 2.2.3 ArrayList集合
      • 2.2.4 LinkedList集合
      • 2.2.5 泛型深入
        • 2.2.5.1 泛型类
        • 2.2.5.2 泛型方法
        • 2.2.5.3 泛型接口
      • 2.2.6 Set集合
      • 2.2.6 HashSet集合
      • 2.2.7 HashSet集合
      • 2.2.8 TreeSet集合
    • 2.3 双列集合
      • 2.3.1 Map集合
        • 2.3.1.1 Map集合常用的API
        • 2.3.1.2 遍历方式一:键找值
        • 2.3.1.3 遍历方式二:键值对
        • 2.3.1.4 遍历方式三:Lambda表达式
      • 2.3.2 HashMap集合
      • 2.3.3 LinkedHashMap
      • 2.3.4 TreeMap
      • 2.3.5 集合工具类Collections
  • 3 Stream流和方法引用
    • 3.1 Stream流的思想
      • 3.1.1 得到stram流,把数据放上去
      • 3.1.2 中间方法
      • 3.1.3 终结方法
  • 其他
    • Arrays
    • Lambda表达式

1.数据结构

1.1 查找

1.1.1 基本查找

for 循环直接查找

package searchdemo;public class SearchDemo1 {public static void main(String[] args) {//基本查找int[] arr = {131,127,147,81,103,23,7,79};boolean b = basicSearch(arr, 81);System.out.println(b);}public static boolean basicSearch(int[] arr,int number){for (int i = 0; i < arr.length; i++) {if(number == arr[i])return true;}return false;}
}

1.1.2 二分查找

折半查找,每次改变中间指针的位置,要求原序列有序

public class SearchDemo3 {public static void main(String[] args) {//折半查找//min和max表示当前要查找的范围,mid是在min和max中间.int[] arr = {7,23,79,81,103,127,131,147};System.out.println(binarySearch(arr,81));}public static int binarySearch(int[] arr,int number){int min = 0;int max = arr.length-1;while(true){if(min > max){return -1;}int mid = (min + max) / 2;if(arr[mid] > number){max = mid - 1;}else if(arr[mid] < number){min = mid + 1;}else{return mid;}}}
}

1.1.3 插值查找

mid = min+ key-arr[min]/arr[max]-arr[min] * (max-min)
在这里插入图片描述

1.1.4 斐波那契查找

根据黄金分割点来计算mid指向的位置

1.1.5 分块查找

原则:

  1. 前一块所有数据小于后一块所有数据(块内无序、块间有序)
  2. 块数的等于总数字个数开根号
  3. 思路:先确定查找的元素在哪一块,然后在块内查找
public class BlockSearch {public static void main(String[] args) {int[] arr = {16, 5, 9, 12, 21, 18, 32, 23, 37, 26, 45, 34, 50, 48, 61, 52, 73, 66};// Creating blocks with their maximum values and their start and end indices in the arrayBlock b1 = new Block(21, 0, 5);Block b2 = new Block(45, 6, 11);Block b3 = new Block(73, 12, 17);Block[] blockArr = {b1, b2, b3};int number = 32; // The number we are searching for// Find the block that might contain the numberint indexBlock = findIndexBlock(blockArr, number);if (indexBlock == -1) {System.out.println(false);} else {boolean found = false;// Linear search within the identified blockfor (int i = blockArr[indexBlock].getStartIndex(); i <= blockArr[indexBlock].getEndIndex(); i++) {if (number == arr[i]) {found = true;System.out.println(true);break;}}if (!found) {System.out.println(false);}}}private static int findIndexBlock(Block[] blockArr, int number) {for (int i = 0; i < blockArr.length; i++) {if (blockArr[i].getMax() >= number) {return i;}}return -1;}
}class Block {private int max;private int startIndex;private int endIndex;public Block(int max, int startIndex, int endIndex) {this.max = max;this.startIndex = startIndex;this.endIndex = endIndex;}public int getMax() {return max;}public int getStartIndex() {return startIndex;}public int getEndIndex() {return endIndex;}@Overridepublic String toString() {return "Block{max = " + max + ", startIndex = " + startIndex + ", endIndex = " + endIndex + "}";}
}

1.1.6 分块查找的扩展(无规律数据)

数据本身没有明显的规律,那么定义块的时候将(最大值,起始索引,结束索引)换成(最小值,最大值,起始索引),块的分割需要手动定义

public class BlockSearchDemo2 {public static void main(String[] args) {int[] arr = {27,22,30,40,36,13,19,16,20,7,10,43,50,48};int number = 30;BlockSearch2 block1 = new BlockSearch2(22,40,0);BlockSearch2 block2 = new BlockSearch2(13,20,5);BlockSearch2 block3 = new BlockSearch2(7,10,9);BlockSearch2 block4 = new BlockSearch2(43,50,11);BlockSearch2[] blockArr = {block1,block2,block3,block4};int index = findIndex(blockArr, number);if(index == -1) {System.out.println(false);}else{boolean flag = false;for (int i = blockArr[index].getIndex(); i < blockArr[index + 1].getIndex(); i++) {if(number == arr[i]){flag = true;System.out.println(true);break;}}if(!flag){System.out.println(false);}}}private static int findIndex(BlockSearch2[] blockArr,int number){for (int i = 0; i < blockArr.length; i++) {if(number >= blockArr[i].getMin() && number <= blockArr[i].getMax()){return i;}}return -1;}
}
class BlockSearch2 {private int min;private int max;private int index;public BlockSearch2() {}public BlockSearch2(int min, int max, int index) {this.min = min;this.max = max;this.index = index;}/*** 获取* @return min*/public int getMin() {return min;}/*** 设置* @param min*/public void setMin(int min) {this.min = min;}/*** 获取* @return max*/public int getMax() {return max;}/*** 设置* @param max*/public void setMax(int max) {this.max = max;}/*** 获取* @return index*/public int getIndex() {return index;}/*** 设置* @param index*/public void setIndex(int index) {this.index = index;}public String toString() {return "BlockSearch2{min = " + min + ", max = " + max + ", index = " + index + "}";}
}

1.2 排序

1.2.1 冒泡排序

1.相邻元素两两比较,小的放前面,大的放后面
2.一轮循环结束,最大值已经找到,在数组最右
3.第二轮循环在剩余元素中找最大值
4.N个数据,进行N-1轮比较

public class sortdemo1 {public static void main(String[] args) {int[] arr = {2,4,5,3,1};for(int i = 0; i < arr.length - 1;i++){//轮数for(int j = 0;j < arr.length - i - 1;j++){//每一轮中如何比较数据并找到当前的最大值if(arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}

1.2.2 选择排序

从0索引开始,拿着每一个元素跟后面的元素一次比较,小的放前面,大的放后面,以此类推.

public class SortDemo2 {public static void main(String[] args) {int[] arr = {2,4,5,3,1};for (int i = 0; i < arr.length - 1; i++) {//这一轮拿哪个索引跟后面的数据比较for (int j = i + 1; j < arr.length; j++) {//每一轮的比较if(arr[i] > arr[j]){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}

1.2.3 插入排序

将0索引到N索引元素看作有序,将N+1索引到最后元素看作无序。遍历无序数据,将遍历到的元素插入适当位置,如果遇到相同数据,插在后面。

public class SortDemo3 {public static void main(String[] args) {int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};//找到无序的那一组数据是从哪个索引开始的int startIndex = -1;for(int i = 0;i < arr.length; i++){if(arr[i] > arr[i+1]){startIndex = i; //有序的最后一个元素break;}}//遍历startindex开始到最后一个元素,依次得到无序的那一组每一个元素for (int i = startIndex; i < arr.length-1; i++) {for(int j = i + 1;j > 0;j--){ //从后往前找位置if(arr[j] < arr[j-1]){int temp = arr[j];arr[j] = arr[j - 1];arr[j - 1] = temp;}else if(arr[j] >= arr[j-1]){break;}}}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}}
}

1.2.4 快速排序

递归算法
递归指的是方法中调用方法本身的现象
注意: 递归一定要有出口,否则就会出现内存溢出
可以将一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量程序就可以描述出解题过程所需要的多次重复计算.
快速排序
第一轮:把0索引的数组作为基准数,确定基准数在数组中正确的位置,比基准数小的或等于的全部在左边,比基准数大的全部在右边
画图!!!

public class QuickSortDemo {public static void main(String[] args) {int[] arr = {27, 22, 30, 40, 36, 13, 19, 16, 20, 7, 10, 43, 50, 48};System.out.println("Unsorted array:");printArray(arr);quickSort(arr, 0, arr.length - 1);System.out.println("Sorted array:");printArray(arr);}// 快速排序主方法public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high); // 获取分区索引quickSort(arr, low, pi - 1); // 递归排序左子数组quickSort(arr, pi + 1, high); // 递归排序右子数组}}// 分区方法public static int partition(int[] arr, int low, int high) {int pivot = arr[low]; // 选择最左元素为基准int i = low + 1; // 从第二个元素开始int j = high;while (i <= j){  // 找到第一个大于基准的元素while (i <= j && arr[i] <= pivot) {i++;}// 找到第一个小于基准的元素while (i <= j && arr[j] > pivot) {j--;}// 交换 arr[i] 和 arr[j]if (i < j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将基准放到正确的位置int temp = arr[low];arr[low] = arr[j];arr[j] = temp;return j; // 返回基准的索引}// 打印数组方法public static void printArray(int[] arr) {for (int i : arr) {System.out.print(i + " ");}System.out.println();}
}

2. 集合

2.1 基础集合

2.1.1 集合和数组的对比

1.长度:数组长度固定,集合长度可变
2.存储类型:数组:基本数据类型和引用数据类型;集合:引用数据类型,基本数据类型需要借用包装类来存储

2.1.2 ArrayList

1.打印:打印一个对象,默认情况下打印的是对象的类型名加上它的哈希码的十六进制形式,
ArrrayList重写了toString()方法,打印集合中存储的元素内容。
2.泛型: 进一步限定了集合中存储的对象类型,确保类型安全和明确的类型定义。(下面的String)

ArrayList<String> list = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<Integer> intList = new ArrayList<>();

在这里插入图片描述
3.基本数据类型对应的包装类
byte->Byte
short->Short
char->Character
int->Integer
long->Long
float->Float
double->Double
boolean->Boolean

2.2 单列集合

List系列集合: 元素有序,可重复,有索引,添加元素永远返回值为True
Set系列集合: 元素无序,不可重复,无索引,添加元素已存在返回值为False
在这里插入图片描述

2.2.1 Collection单列集合

Collection 是单列集合的祖宗接口,功能是全部单列集合都可以继承使用
1.不能通过索引删除
2.删除元素不存在返回False
3.判断是否存在时,底层用equals方法实现的,集合存储自定义对象想通过contains方法判断,一定要重写equals方法
在这里插入图片描述

public class CollectionDemo1 {public static void main(String[] args) {Collection<String> coll= new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");coll.clear();coll.remove("ccc");coll.contains("aaa");boolean result2 = coll.isEmpty();int size = coll.size();}
}
2.2.1.1 Collection的遍历方式一:迭代器遍历
public class CollectionDemo2 {public static void main(String[] args) {Collection<String> coll = new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");coll.add("ddd");//获取迭代器对象,迭代器对象就好比是一个箭头,指向集合的0索引Iterator<String> it = coll.iterator();while(it.hasNext()){String next = it.next();System.out.println(next);}}
}
2.2.1.2 Collection的遍历方式二:增强for遍历
public class CollectionDemo3 {public static void main(String[] args) {Collection<String> coll = new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");coll.add("ddd");//简写:coll.for+回车//注意:S其实就是一个第三方变量,在循环过程中依次表示集合中的每一个数据for (String s : coll) {System.out.println(s);}}
}
2.2.1.3 Collection的遍历方式三:Lambda表达式遍历
 coll.forEach(s->System.out.println(s));

2.2.2 List集合

List集合独有的方法
在这里插入图片描述

public class ListDemo1 {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");//再次集合中的指定位置插入指定元素//细节:原来索引上的元素会依次后移list.add(2,"ddd");list.remove("ddd");list.remove(0);//删除0索引上对应元素,并且将被删除元素作为返回值,其他元素前移list.set(0,"qqq");//修改之后会将被修改的元素做一个返回String s = list.get(0);}
}
2.2.2.1 迭代器遍历
Iterator<String> it = list.iterator();
while(it.hasNext()){sout(it.next());
}
2.2.2.2 增强for遍历方式
for(String s : list){System.out.println(s);
}
2.2.2.3 Lambda表达式方式
list.forEach(s -> System.out.println(S));
2.2.2.4 普通for循环
for (int i = 0; i < list.size(); i++) {//集合的大小是list.size()System.out.println(list.get(i));}
2.2.2.5 列表迭代器
//列表迭代器//获取列表迭代器的对象,里面的指针默认也是指向0索引的//额外添加了一个方法:在便利的过程中,可以添加元素ListIterator<String> it2 = list.listIterator();while(it2.hasNext()){String s = it2.next();if(s.equals("bbb")){it2.add("eee");}}
2.2.2.6 五种遍历方式对比

在这里插入图片描述

2.2.3 ArrayList集合

ArrayList集合底层原理
1.利用空参创建的集合,在底层创建一个默认长度为0的数组
2.添加第一个元素时,底层会创建一个新的长度为10的数组
3.存满时,会扩容1.5倍
4.如果一次添加多个元素,1.5倍放不下则新创建数组长度以实际为准

在这里插入图片描述

2.2.4 LinkedList集合

底层数据结构是双链表,查询慢,增删快,但是如果操作的是首尾元素,速度也是极快的
LinkList本身多了很多直接操作首尾元素的特有API
在这里插入图片描述

2.2.5 泛型深入

1.泛型: 是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
2.格式: List
3.限制: 泛型只能支持引用数据类型
4.好处: 如果没有给集合指定类型,Java 默认认为集合中的所有数据类型都是 Object。这样,集合可以存储任意类型的数据。
在运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来。
5.劣势: 在获取数据时,由于数据类型被认为是 Object,无法直接使用其特有的方法和行为,需要进行类型转换。
6.泛型的扩展: Java中的泛型是伪泛型
当集合中想要添加元素时,集合验证数据类型与集合泛型是否符合,若符合加入集合。在集合内的存储中,数据类型为Object,当将数据取出集合后,又将数据类型转换为原来数据类型。
7.泛型的细节:
指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类类型
如果不写泛型,类型默认是Object

2.2.5.1 泛型类

当一个类中,某个变量的数据类型不确定时,就可以定义带有泛型的类

public class ArrayList<E>{
//此处E可以理解为变量,但是不是用来记录数据的,而是记录数据的类型,可以写成:T,E,K,V等
}
2.2.5.2 泛型方法

方法中形参类型不确定时,可以使用类名后面定义的泛型
1.使用类名后面定义的泛型-所有方法都能用
2.在方法申明上定义自己的泛型-只有本方法能用

public <T> void show(T t){}
public static<E> void addAll(ArrayList<E> list,E...e){
// public:方法的访问修饰符,表示该方法可以被任何类调用。
// static:方法是静态的,可以直接通过类名调用,而不需要实例化该类。
// <E>:这是方法的泛型类型参数声明,表示方法是泛型方法。
// ArrayList<E> list:方法的第一个参数,类型为 ArrayList<E>,表示要添加元素的列表。
// E... e:方法的第二个参数,是一个可变参数,类型为 E。可变参数表示可以传入任意数量的 E 类型的参数(包括零个)。for (E e1 : e) {list.add(e1);}}
2.2.5.3 泛型接口
public interface List<E>{}

使用方式
1.实现类给出具体类型
2.实现类延续泛型,创建对象时再确定
泛型的继承和通配符
1.泛型不具备继承性,但数据具备继承性
在泛型中,List 并不是 List 的子类,即使 Dog 是 Animal 的子类。
这意味着你不能将 List 赋值给 List。可以将 Dog 类型的数据放入 Animal 类型的容器中(例如 ArrayList)

2.2.6 Set集合

HashSet: 无序,不重复,无索引
LinkedHashSet: 有序,不重复,无索引
TreeSet: 可排序,不重复,无索引
Set接口中的方法上基本上与Collection的API一致

public class SetDemo1 {public static void main(String[] args) {Set<String> s= new HashSet<>();boolean r1 = s.add("张三");boolean r2 = s.add("lisi");boolean r3 = s.add("wangwu");//迭代器的方法遍历Iterator<String> it = s.iterator();while(it.hasNext()){System.out.println(it.next());}//Lamdba表达式方法s.forEach(i-> System.out.println(i));}
}

2.2.6 HashSet集合

HashSet底层原理
HashSet集合底层采取哈希表 存储数据
哈希值
1.哈希值根据HashCode方法算出来的int类型的整数
2.该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
3.一般情况下,会重写HashCode方法,利用对象内部的属性值计算哈希值
对象的哈希值特点
1.如果没有重写HashCode方法,不同对象 计算出的哈希值是不同的
2.如果已经重写HashCode方法,不同的对象只要属性值 相同,计算出的哈希值就是一样的
3.在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样(哈希碰撞
HashSet底层原理
1.创建一个默认长度为16,默认加载因子为0.75的数组,数组名为table
2.根据元素的哈希值跟数组长度计算出应存入的位置
3.判断当前位置是否为null,如果是null直接存入
4.如果位置不为null,表示有元素,则调用equals方法比较属性值
5.一样:不存 不一样:存入数组,形成链表
JDK8以前:新元素存入数组,老元素挂在新元素下面
JDK8以后:新元素直接挂在老元素下面

2.2.7 HashSet集合

有序,不重复,无索引
原理: 底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储顺序

2.2.8 TreeSet集合

无重复,无索引,可排序
可排序:按照元素的默认规则(有小有大)排序
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好
TreeSet集合默认的规则
1.对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
2.对于字符,字符串:按照字符在ASCII码表中的数字升序进行排序a->b->c->…
TreeSet的两种比较方式
方式一:默认排序/自然排序: Javabean实现Comparable接口指定比较规则
方式二:比较器排序 创建TreeSet对象的时候,传递比较器Comparator制定规则
使用原则:默认使用第一种,如果第一种不能满足条件,再使用第二种
在这里插入图片描述

2.3 双列集合

特点:
1.单列集合每次添加一个元素,双列集合每次添加一对元素(键——不可重复,值——可以重复)
2.一对键和值称为键值对对象、键值对、Entry对象
在这里插入图片描述

2.3.1 Map集合

2.3.1.1 Map集合常用的API

1.Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的
在这里插入图片描述
2.put方法的细节:添加、覆盖
在添加数据时,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回null。
在添加数据时,如果键存在,那么会把原有的键值对对象覆盖,会把覆盖的原值进行返回。
3.remove方法的细节
在删除数据时,如果键存在,那么把键值对对象删除,返回被删除对象的值
在删除数据时,如果键不存在,返回null

2.3.1.2 遍历方式一:键找值

键不能重复,所以用set
1)将双列集合中的键统一提取出来,存入一个单列集合。
map.KeySet();返回值为双列集合的所有键,直接存入单列set集合
2)在单列集合中通过get方法获得对应的值
map.get(Key);通过键值找到双列集合中对应的值

public class A02_MapDemo2 {public static void main(String[] args) {//Map集合的第一种遍历方式//创建Map对象Map<String,String> m = new HashMap<>();//添加元素m.put("a","b");m.put("c","d");m.put("e","f");//获取所有键,将键存入一个 单列集合当中Set<String> keys = m.keySet();//遍历单列集合,得到每一个键for (String key : keys) {String value = m.get(key);System.out.println(key + "=" + value);}}
}
2.3.1.3 遍历方式二:键值对

1)获取双列集合中的所有键值对
map.entrySet();返回值为键值对对象entry的单列set集合,set集合里面的对象为entry对象
2)分别获取每一个键值对中的键和值
entry.getKey();
entry.getValue();

public class A03_MapDemo3 {public static void main(String[] args) {Map<String, String> map = new HashMap<>();map.put("a","b");map.put("c","d");map.put("e","f");//通过键值对对象进行遍历Set<Map.Entry<String, String>> entries = map.entrySet();//set里面是entry对象,entry里面装键和值//由于entry是map接口里面的内部接口,所以需要外部接口.调用即Map.Entry//遍历entries集合for (Map.Entry<String, String> entry : entries) {String key = entry.getKey();String value = entry.getValue();System.out.println(key);System.out.println(value);}}
}
2.3.1.4 遍历方式三:Lambda表达式
public class A04_MapDemo4 {public static void main(String[] args) {Map<String,String> map = new HashMap<>();map.put("a","b");map.put("c","d");map.put("e","f");//匿名内部类遍历map.forEach(new BiConsumer<String, String>() {@Overridepublic void accept(String key, String value) {System.out.println(key + " " + value);}});//lambda表达式遍历map.forEach((String key, String value)-> {System.out.println(key + " " + value);});map.forEach((key,value)->System.out.println(key + " " + value));}
}

2.3.2 HashMap集合

在这里插入图片描述

2.3.3 LinkedHashMap

1)由键决定:有序、无重复、无索引
2)这里的有序指的是保证存储和取出元素的顺序一致
3)原理:底层数据元素依然是哈希表,只是每个键值对元素又额外多了一个双链表的机制记录存储的顺序。
在这里插入图片描述

2.3.4 TreeMap

1)TreeMap和TreeSet底层原理一样,都是红黑树结构的
2)由键决定特性:不重要、无索引、可排序
3)可排序:对键进行排序
4)注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
代码书写两种规则

1)实现Comparable接口,指定比较规则
2)创建 集合时传递Comparator比较器对象,指定比较规则(二者都存在,以2为准)

2.3.5 集合工具类Collections

1)java.util.Collections:是集合工具类
2)作用:Collection不是集合,而是集合的工具类
在这里插入图片描述

public class CollectionsDemo1 {public static void main(String[] args) {//1.创建集合对象ArrayList<String> list = new ArrayList<>();//2.批量添加Collections.addAll(list,"abc","aa","bb","cc");System.out.println(list);//3.打乱shuffleCollections.shuffle(list);System.out.println(list);}
}

3 Stream流和方法引用

3.1 Stream流的思想

作用
结合了Lambda表达式,简化集合、数组的操作
使用步骤
1.得到stram流,把数据放上去
2.利用stream中的API进行各种操作
分类
1.中间方法:过滤、转换
2.终结方法:统计、打印

3.1.1 得到stram流,把数据放上去

1.单列集合


public class StreamDemo2 {public static void main(String[] args) {//1.单列集合获取Stream流ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"a","b","c","d","e");//获取到一条流水线,并把集合中的数据放到流水线上Stream<String> stream1 = list.stream();//使用终结方法打印流水线上的数据stream1.forEach(name-> System.out.println(name));//list.stream().forEach(name-> System.out.println(name));}
}

2.双列集合

public class SreamDemo3 {public static void main(String[] args) {//1.创建双列集合HashMap<String,Integer> hm = new HashMap<>();//2.添加数据hm.put("aaa",111);hm.put("bbb",222);hm.put("ccc",333);hm.put("ddd",444);//3.获取stream流hm.keySet().stream().forEach(s -> System.out.println(s));hm.entrySet().stream().forEach(s -> System.out.println(s));}
}

3.数组

public class StreamDemo4 {public static void main(String[] args) {//1.创建数组int[] arr = {1,2,3,4,5,6,7,8,9,10};String[] arr2 = {"a","b","c"};//2.获取Stream流Arrays.stream(arr).forEach(s-> System.out.println(s));Arrays.stream(arr2).forEach(s-> System.out.println(s));}
}

4.其他零散数据

public class StreamDemo5 {public static void main(String[] args) {//一堆零散数据,要求数据的种类相同Stream.of(1,2,3,4,5).forEach(s-> System.out.println(s));Stream.of("a","b","c","d","e").forEach(s-> System.out.println(s));}
}

注意
1)方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
2)但是数组必须是引用数据类型,如果传递基本数据类型,是会把整个数组当作一个元素,放到Stream当中。

3.1.2 中间方法

在这里插入图片描述
1)中间方法返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
2)修改Stream流中的数据,不会影响原来集合或者数组中的数据

//filter 过滤,把开头的留下,其余的数据不要
list.stream().filter(s->s.startsWith("张")).forEach(s-> System.out.println(s));//limit获取前几个元素list.stream().limit(3).forEach(s-> System.out.println(s));//skip跳过前几个元素list.stream().skip(3).forEach(s-> System.out.println(s));//distinct 元素去重,依赖(hashCode和equals方法)list1.stream().distinct().forEach(s-> System.out.println(s));//concat 合并a和b两个流为一个流Stream.concat(list1.stream(),list2.stream()).forEach(s-> System.out.println(s));list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));

3.1.3 终结方法

在这里插入图片描述

list.stream().forEach(s-> System.out.println(s));
long count = list.stream().count();System.out.println(count);
String[] arr2 = list.stream().toArray(value -> new String[value]);

其他

Arrays

操作数组的工具类
在这里插入图片描述

import java.util.Arrays;public class ToStringDemo {public static void main(String[] args) {int[] intArray = {1, 2, 3, 4, 5};System.out.println(Arrays.toString(intArray)); // 输出: [1, 2, 3, 4, 5]String[] stringArray = {"Hello", "World", "Java"};System.out.println(Arrays.toString(stringArray)); // 输出: [Hello, World, Java]char[] charArray = {'a', 'b', 'c', 'd'};System.out.println(Arrays.toString(charArray)); // 输出: [a, b, c, d]double[] doubleArray = {1.1, 2.2, 3.3, 4.4};System.out.println(Arrays.toString(doubleArray)); // 输出: [1.1, 2.2, 3.3, 4.4]}
}

Lambda表达式

函数式编程
面向对象先找对象,让对象做事情

Arrays.sort(arr,new Comparator<Integer>(){public int compare(Integer o1,Integer o2){return o1 - o2;}
});

函数式编程忽略面向对象的复杂语法,强调做什么,而不是谁去做
Lambda表达式就是函数式思想的体现
格式

() -> {
}

1.() 对应着方法的形参
2.-> 固定格式
3.{} 对应方法的方法体

Arrays.sort(arr,(Integer o1,Integer o2)->{return o1 - o2;
});

注意:
1.Lambda表达式可以用来简化匿名内部类的书写
2.Lambda表达式只能简化函数式接口 的匿名内部类的写法
3.函数式接口 :有且只有一个抽象方法的接口叫做函数式接口,接口上方可以加@FunctionalInterface注解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/371234.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

53-1 内网代理3 - Netsh端口转发(推荐)

靶场还是用上一篇文章搭建的靶场 :52-5 内网代理2 - LCX端口转发(不推荐使用LCX)-CSDN博客 一、Netsh 实现端口转发 Netsh是Windows自带的命令行脚本工具,可用于配置端口转发。在一个典型的场景中,如果我们位于公网无法直接访问内网的Web服务器,可以利用中间的跳板机通过…

设计模式探索:责任链模式

1. 什么是责任链模式 责任链模式 (Chain of Responsibility Pattern) 是一种行为型设计模式。定义如下&#xff1a; 避免将一个请求的发送者与接收者耦合在一起&#xff0c;让多个对象都有机会处理请求。将接收请求的对象连接成一条链&#xff0c;并且沿着这条链传递请求&…

【Linux进阶】文件系统6——理解文件操作

目录 1.文件的读取 1.1.目录 1.2.文件 1.3.目录树读取 1.4.文件系统大小与磁盘读取性能 2.增添文件 2.1.数据的不一致&#xff08;Inconsistent&#xff09;状态 2.2.日志式文件系统&#xff08;Journaling filesystem&#xff09; 3.Linux文件系统的运行 4、文件的删…

【YOLOv9教程】如何使用YOLOv9进行图像与视频检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

14-40 剑和诗人14 - 为什么机器学习需要合成数据

​​​​​​ 数据是人工智能的命脉。如果没有高质量、有代表性的训练数据&#xff0c;我们的机器学习模型将毫无用处。但随着神经网络规模越来越大、人工智能项目越来越雄心勃勃&#xff0c;人们对数据的需求也越来越大&#xff0c;我们面临着一场危机——现实世界的数据收集和…

字符串和正则表达式踩坑

// 中石化加油卡号格式&#xff1a;以 100011 开头共19位public static final String ZHONGSHIYOU_OIL_CARD_PATTERN "^100011\\d{13}$";// 中石油加油卡号格式&#xff1a;以90、95、70开头共16位public static final String ZHONGYOU_OIL_CARD_PATTERN "^(9…

Ubuntu20.04 有线网络图标消失解决方案

Ubuntu20.04 有线网络图标消失解决方案 问题描述&#xff1a; ubuntu20.04系统提示的software updater有软件包更新&#xff0c;按提示安装更新软件包&#xff0c;重启系统后&#xff0c;ubuntu系统的网络图标消失不见&#xff1b;无法正常上网&#xff1b;检查网口&#xff0…

【SpringCloud应用框架】Nacos集群架构说明

第六章 Spring Cloud Alibaba Nacos之集群架构说明 文章目录 前言一、Nacos支持三种部署模式二、集群部署说明三、预备环境 前言 到目前为止&#xff0c;已经完成了对Nacos的一些基本使用和配置&#xff0c;接下来还需要了解一个非常重要的点&#xff0c;就是Nacos的集群相关的…

有一个日期(Date)类的对象和一个时间(Time)类的对象,均已指定了内容,要求一次输出其中的日期和时间

可以使用友元成员函数。在本例中除了介绍有关友元成员函数的简单应用外&#xff0c;还将用到类的提前引用声明&#xff0c;请读者注意。编写程序&#xff1a; 运行结果&#xff1a; 程序分析&#xff1a; 在一般情况下&#xff0c;两个不同的类是互不相干的。display函…

【Rust入门】生成随机数

文章目录 前言随机数库rand添加rand库到我们的工程生成一个随机数示例代码 总结 前言 在编程中&#xff0c;生成随机数是一种常见的需求&#xff0c;无论是用于数据分析、游戏开发还是模拟实验。Rust提供了强大的库来帮助我们生成随机数。在这篇文章中&#xff0c;我们将通过一…

计算两个经纬度之间的球面距离(基于Mysql和PHP实现)

计算两个经纬度之间的球面距离 1、MySQL实现方式 - 基于空间函数(ST_Distance_Sphere)实现 前置条件&#xff1a;确保您使用的是 MySQL 8.0 或更高版本&#xff0c;因为较早的版本对地理空间的支持有限。 1.1 创建表和索引 说明&#xff1a;设置 location 为 point 类型 #…

DNS正向解析与反向解析实验

正向解析 安装bind软件 [rootlocalhost ~]# dnf install bind bind-utils -y修改主配置文件/etc/named.conf [rootlocalhost ~]# vim /etc/named.conf重启DNS服务&#xff08;named&#xff09; [rootlocalhost ~]# systemctl restart named编辑数据配置文件。在/var/named…

确认下单:购物车页面点击 去结算 按钮发起两个请求trade(显示购物车的商品信息和计算商品的总金额)findUserAddressList

文章目录 1、确认下单&#xff1a;购物车页面点击去结算1.1、在OrderController类中创建 trade 方法1.2、在CartController类中创建 checkedCartInfos1.3、CartServiceImpl 实现 checkedCartInfos的业务功能1.4、在service-cart-client模块下定义远程openFeign接口1.5、在SpzxO…

数据结构--二叉树和堆

目录 1.基本概念 2.树的遍历方法 3.满二叉树&&完全二叉树 4.逻辑结构&&物理结构 5.推理公式 6.二叉树应用--堆 7.简单实现堆 1.基本概念 &#xff08;1&#xff09;这个里面的概念还是比较多的&#xff0c;但是大部分我们只需要了解即可&#xff0c;因为…

【Linux进阶】文件系统5——ext2文件系统(inode)

1.再谈inode (1) 理解inode&#xff0c;要从文件储存说起。 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。操作系统读取硬盘的时候&#xff0c;不会一个个…

数智化配补调:零售品牌增长新引擎

随着科技的不断进步和消费者需求的日益个性化、多元化&#xff0c;传统服装行业正面临着前所未有的挑战与机遇。在这个快速变化的时代&#xff0c;如何精准把握市场脉搏&#xff0c;实现库存的高效管理&#xff0c;成为了服装品牌生存与发展的关键。数智化配补调策略应运而生&a…

广州佛山中山数据中心机房搬迁公司

随着数据中心的发展和迭代&#xff0c;必然面临数据中心搬迁。数据中心搬迁听来简单&#xff0c;其实涉及诸多方面&#xff0c;如信息迁移的安全性、业务的连续性、搬迁的规范性、方案的可行性、组织的统一性等。友力科技&#xff08;广州&#xff09;有限公司&#xff0c;自原…

快速解决找不到krpt.dll,无法继续执行代码问题

对于那些遇到计算机开机出现由于无法找到krpt.dll&#xff0c;进而无法继续执行代码问题的用户。 krpt.dll是计算机系统中与DirectX紧密相关的重要文件&#xff0c;如果它出现问题&#xff0c;可能会对一些特定的软件或游戏的运行产生影响。实际上&#xff0c;我们有多种解决该…

音视频开发35 FFmpeg 编码- 将YUV 和 pcm合成一个mp4文件

一 程序的目的 /*** *该程序的目的是: * 将 一个pcm文件 和 一个 yuv文件&#xff0c;合成为一个 0804_out.mp4文件 * pcm文件和yuv文件是从哪里来的呢&#xff1f;是从 sound_in_sync_test.mp4 文件中&#xff0c;使用ffmpeg命令 抽取出来的。 * 这样做的目的是为了对比前…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第55课-芝麻开门(语音 识别 控制3D纪念馆开门 和 关门)

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第55课-芝麻开门&#xff08;语音识别控制3D纪念馆开门和关门&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtn…