【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.mzph.cn/bicheng/42456.shtml

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

相关文章

爱了!8款超好用的PC端办公软件!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 你电脑中用的最久的软件是哪些&#xff1f;以下是否有你曾经使用过的软件呢&#xff1f;工欲善其事&#xff0c;必先利其器&#xff0c;今天继续…

无人机便携式侦测干扰设备(定全向)技术详解

无人机便携式侦测干扰设备&#xff08;定全向&#xff09;是一种专门针对无人机进行侦测和干扰的设备。它具备定向和全向两种工作模式&#xff0c;能够覆盖较宽的频率范围&#xff0c;有效侦测并干扰无人机与遥控器之间的通信信号&#xff0c;从而达到控制或驱离无人机的目的。…

验证回文串-string题目

用双指针&#xff0c;left right从两头往中间对比&#xff0c;不是字母的都略过&#xff0c;比的时候化成小写字母 125. 验证回文串 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool isPalindrome(string s) {if(s.size() < 1)return true;int left …

论文复现-基于决策树算法构建银行贷款审批预测模型(金融风控场景)

作者Toby&#xff0c;来源公众号&#xff1a;Python风控模型&#xff0c;基于决策树算法构建银行贷款审批预测模型 目录 1.金融风控论文复现 2.项目背景介绍 3.决策树介绍 4.数据集介绍 5.合规风险提醒 6.技术工具 7.实验过程 7.1导入数据 7.2数据预处理 7.3数据可…

SpringBoot3+Vue3开发园区管理系统

介绍 在当今快速发展的城市化进程中&#xff0c;高效、智能的园区管理成为了提升居民生活品质、优化企业运营环境的关键。为此&#xff0c;我们精心打造了全方位、一体化的园区综合管理系统&#xff0c;该系统深度融合了园区管理、楼栋管理、楼层管理、房间管理以及车位管理等…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【明文导入密钥(ArkTS)】

明文导入密钥(ArkTS) 分别以导入AES256与RSA2048密钥为例&#xff0c;具体的场景介绍及支持的算法规格 开发步骤 指定密钥别名keyAlias。 密钥别名的最大长度为64字节。 封装密钥属性集和密钥材料。 密钥属性集同样与密钥生成中指定的密钥属性一致&#xff0c;须包含[HuksKe…

昇思MindSpore学习总结十——ResNet50迁移学习

1、迁移学习 &#xff08;抄自CS231n Convolutional Neural Networks for Visual Recognition&#xff09; 在实践中&#xff0c;很少有人从头开始训练整个卷积网络&#xff08;使用随机初始化&#xff09;&#xff0c;因为拥有足够大小的数据集相对罕见。相反&#xff0c;通常…

【机器学习】机器学习与时间序列分析的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在时间序列分析中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 数据增强 1.2 模型选择1.2.1 自回归模型1.2.2 移动平均模型1.2.3 长短期记忆网络1.2.4 卷积神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 A…

SpringCloud学习Day7:Seata

概念 Seata是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务 工作流程 TC以Seata服务器形式独立部署&#xff0c;TM和RM则是以Seata Client的形式集成在微服务中运行

240707_昇思学习打卡-Day19-基于MindSpore通过GPT实现情感分类

240707_昇思学习打卡-Day19-基于MindSpore通过GPT实现情感分类 今天基于GPT实现一个情感分类的功能&#xff0c;假设已经安装好了MindSpore环境。 # 该案例在 mindnlp 0.3.1 版本完成适配&#xff0c;如果发现案例跑不通&#xff0c;可以指定mindnlp版本&#xff0c;执行!pip…

Mysql数据库索引、事务相关知识

索引 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c; 并指定索引的类型&#xff0c;各类索引有各自的数据结构实现 查看索引 show index from 表名;创建索引对于非主键、非唯一约束、非外键的字段&#…

基于贝叶斯优化的卷积神经网络-循环神经网络混合模型的的模拟股票时间序列预测(MATLAB R2021B)

将机器学习和深度学习方法运用到股市分析中, 不仅具有一定的理论价值, 也具有一定的实践价值。从理论价值上讲, 中国的量化投资技术&#xff08;投资观念、方法与决策等&#xff09;还不够成熟, 尚处在起步阶段, 能够将量化投资技术运用到投资决策中的公司寥寥无几。目前, 国内…

端口被占用,使用小黑框查杀

netstat -ano &#xff08;查看目前所有被占的端口&#xff09; netstat -ano|findstr " 8080" 查一下目前被占用的端口号 &#xff0c;目前我要查的端口号是&#xff1a;8080&#xff0c;注意 后面打8080的时候&#xff0c;要有空格&#xff0c;要不然报错 **task…

Zabbix 的部署和自定义监控内容

前言 一个完整的项目的业务架构包括 客户端 -> 防火墙 -> 负载均衡层&#xff08;四层、七层 LVS/HAProxy/nginx&#xff09; -> Web缓存/应用层&#xff08;nginx、tomcat&#xff09; -> 业务逻辑层(php/java动态应用服务) -> 数据缓存/持久层&#xff08;r…

操作系统智能助手OS Copilot评测报告

背景 如果不是朋友告知&#xff0c;我还不知道阿里云推出了【操作系统智能助手OS Copilot】这样一款产品。 我做系统运维的工作还是挺多的&#xff0c;知道系统运维工作的一些痛点&#xff1b;例如&#xff1a; Linux命令繁杂&#xff0c;想全部记住不太可能&#xff0c;多数…

软件测试《用例篇》

测试用例 测试用例的概念 测试用例是被测试人员向被测试系统发起的一组集合&#xff0c;包括测试环境&#xff0c;操作步骤&#xff0c;预期结果&#xff0c;测试数据等 使用测试用例的好处 使用测试用例进行测试的好处主要有&#xff1a;提高测试效率&#xff0c;降低测试的重…

WAWA鱼曲折的大学四年回忆录

声明&#xff1a;本文内容纯属个人主观臆断&#xff0c;如与事实不符&#xff0c;请参考事实 前言&#xff1a; 早想写一下大学四年的总结了&#xff0c;但总是感觉无从下手&#xff0c;不知道从哪里开始写&#xff0c;通过这篇文章主要想做一个记录&#xff0c;并从现在的认…

中国智能制造装备产业发展机遇

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 更多的海量【智能制造】相关资料&#xff0c;请到智能制造online知识星球自行下载。 随着全球第四次工业革命的浪潮&#xff0c;智能制造装备产业…

C++ 函数高级——函数的默认参数

函数默认参数 在C中&#xff0c;函数的形参列表中的形参是可以有默认值的 语法&#xff1a;返回值类型 函数名 &#xff08;参数 默认值&#xff09;{ } 示例&#xff1a; 正确代码&#xff1a; 运行结果&#xff1a;

开源六轴协作机械臂myCobot 280接入GPT4大模型!实现更复杂和智能化的任务

本文已经或者同济子豪兄作者授权对文章进行编辑和转载 引言 随着人工智能和机器人技术的快速发展&#xff0c;机械臂在工业、医疗和服务业等领域的应用越来越广泛。通过结合大模型和多模态AI&#xff0c;机械臂能够实现更加复杂和智能化的任务&#xff0c;提升了人机协作的效率…