【Java】Java8重要特性——Lambda函数式编程以及Stream流对集合数据的操作

【Java】Java8重要特性——Lambda函数式编程以及Stream流对集合数据的操作

  • 前言
  • Lambda函数式编程
  • Stream流对集合数据操作
    • (一)创建Stream流
    • (二)中间操作之filter
    • (三)中间操作之map
    • (四)中间操作之distinct
    • (五)中间操作之sorted
    • (六)中间操作之limit
    • (七)中间操作之skip
    • (八)中间操作之flatMap
    • (九)终结操作之forEach
    • (十)终结操作之count
    • (十一)终结操作之max&min
    • (十二)终结操作之collect
    • (十三)终结操作之anyMatch&allMatch&noneMatch
    • (十四)终结操作之findAny
    • (十五)终结操作之findFirst
    • (十六)终结操作之reduce
    • (十七)并行流
  • Optional包装类
  • 函数式接口
  • 最后

前言

以下知识总结,是笔者在b站上学完了相关课程视频,总结而来。有意者可直接通过点击下面链接
【Lambda表达式&Stream流-函数式编程-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂】 访问三更草堂课程进行视频学习。

Lambda函数式编程

Lambda表达式是Java 8中引入的一个重要特性,它可以用更简洁的方式来表示匿名函数或闭包,使得代码更加简洁和易读。Lambda表达式可以被视为一个匿名函数,它可以作为参数传递给方法或存储在变量中,并且可以在需要时被调用。

Lambda表达式的语法如下:

(parameter1,parameter2) -> expression
// 或
parameter -> expression
// 或
parameter -> { statements; }
// 或
(parameter1,parameter2) -> { statements; }

其中,参数列表(parameter1,parameter2)是一个逗号分隔的参数列表,箭头符号"->"将参数列表和Lambda表达式的主体部分分隔开来。Lambda表达式的主体可以是一个表达式或者一段代码块。

用建立线程的程序可以举例,如下:

    public static void main(String[] args) {// 新线程的建立 匿名内部类的方法new Thread(new Runnable() {public void run() {System.out.println("LambdaDemo01新线程运行");}}).start();//优化 lambda方式new Thread(() -> { System.out.println("LambdaDemo01新线程优化运行"); }).start();//继续优化new Thread(() -> System.out.println("LambdaDemo01新线程继续优化运行")).start();}

Stream流对集合数据操作

在Java中,Stream是用来处理集合数据的工具,它引入自Java 8,并提供了一种更加便利和高效的方式来对集合进行操作。Stream提供了一系列的操作方法,可以对集合进行过滤、映射、排序、聚合等操作,同时还支持并行处理,可以充分利用多核处理器的性能。

注意事项

  1. 惰性求值 (如果没有终结操作,中间操作是不会得到执行的)
  2. 流是一次性的(一旦一个流对象经过一个终结操作后。这个流就不能再被使用)
  3. 不会影响原数据(我们在流中可以多数据做很多处理。但是正常情况下是不会影响原来集合中的元素的。这往往也是我们期望的

先准备一个集合数据,方便接下来在程序举例中用到。

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的distinct去重使用
public class Author{//idprivate Long id;//姓名private String name;//年龄private Integer age;//简介private String intro;//作品private List<Book> books;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的distinct去重使用
public class Book {//idprivate Long id;//书名private String name;//分类private String category;//评分private Integer score;//简介private String intro;
}
private static List<Author> getAuthors(){//数据初始化Author author1 = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);Author author2 = new Author(2L,"亚拉索",15,"狂风也追逐不上他的思考速度",null);Author author3 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);Author author4 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);//书籍列表List<Book> books1 = new ArrayList<>();List<Book> books2 = new ArrayList<>();List<Book> books3 = new ArrayList<>();books1.add(new Book(1L,"刀的两侧是光明与黑暗","哲学,爱情",88,"用一把刀划分了爱恨"));books1.add(new Book(2L,"一个人不能死在同一把刀下","个人成长,爱情",99,"讲述如何从失败中明悟真理"));books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));books2.add(new Book(4L,"吹或不吹","爱情,个人传记",56,"一个哲学家的恋爱观注定很难把他所在的时代理解"));books3.add(new Book(5L,"你的剑就是我的剑","爱情",56,"无法想象一个武者能对他的伴侣这么的宽容"));books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));author1.setBooks(books1);author2.setBooks(books2);author3.setBooks(books3);author4.setBooks(books3);List<Author> authorlist = new ArrayList<>(Arrays.asList(author1,author2,author3,author4));return authorlist;}

(一)创建Stream流

可以通过多种方式来创建Stream流。以下是一些常见的创建Stream流的方式:

    private static void test02(){// 创建流Integer[] arr = {1, 2, 3, 4, 5};Stream<Integer> stream = Arrays.stream(arr); //Stream.of(arr)stream.distinct().filter(integer -> integer>2).forEach(integer -> System. out.println(integer));//双列集合创建流Map<String,Integer> map = new HashMap<>();map.put("蜡笔小新",19);map.put("黑子",17);map.put("日向翔阳",16);Stream<Map.Entry<String, Integer>> streamDD = map.entrySet().stream();streamDD.filter(entry -> entry.getValue() == 19).forEach(entry -> System.out.println(entry));}

Stream流对集合操作是一种链式编程的方式,以创建获取Stream流为开始操作,这里可以通过中间操作和终结操作进行分类分点总结。

(二)中间操作之filter

filter起到的是过滤的作用,通过判断数据是否满足要求来进行过滤。程序举例如下:

 	private static void test03(){List<Author> authors = getAuthors();//打印所有姓名长度大于1的作家的姓名authors.stream().distinct().filter(author -> author.getName().length()>1).forEach(author -> System.out.println(author.getName()));//testAnd 打印所有姓名长度大于1且年龄大于14的作家的姓名authors.stream().distinct().filter(((Predicate<Author>) author -> author.getName().length() > 1).and(author -> author.getAge()>14)).forEach(author -> System.out.println(author.getName()));//testOr 打印所有姓名长度大于1或年龄大于14的作家的姓名authors.stream().distinct().filter(((Predicate<Author>) author -> author.getName().length() > 1).or(author -> author.getAge()>14)).forEach(author -> System.out.println(author.getName()));//testNegate 打印作家中年龄不大于I7的作家authors.stream().distinct().filter(((Predicate<Author>) author -> author.getAge() > 17).negate()).forEach(author -> System.out.println(author.getName()));}

(三)中间操作之map

map的作用是更改流中的元素,程序举例如下:

    private static void test04(){List<Author> authors = getAuthors();//打印所有作家的姓名//用foreach 直接输出authors.stream().forEach(author -> System.out.println(author.getName()));//用map 可以更改流里的元素 再进行输出authors.stream().map(author -> author.getName()).forEach(name -> System.out.println(name));//一些情况根据更改元素的类型可以提高效率authors.stream().mapToInt(author -> author.getAge()).forEach(age -> System.out.println(age));}

(四)中间操作之distinct

distinct起到的作用是对数据进行去重,distinct方法是依赖Obiect的equals方法来判断是否是相同对象的。所以需要注意重写数据的equals方法。

    private static void test05(){List<Author> authors = getAuthors();//打印所有作家的姓名,并且要求其中不能有重复元素。authors.stream().map(author -> author.getName()).distinct().forEach(name -> System.out.println(name));}

(五)中间操作之sorted

sorted起到的是排序的作用,程序举例如下:

    private static void test06(){List<Author> authors = getAuthors();//对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素authors.stream().distinct().sorted((author1,author2) -> author2.getAge() - author1.getAge()) //如果调用空参的sorted0方法, 需要流中的元素是实现了Comparable.forEach(author -> System.out.println(author.getAge()));//Comparator优化(升序可用,降序的话需要同上写法)authors.stream().distinct().sorted(Comparator.comparingInt(Author::getAge)) //如果调用空参的sorted0方法, 需要流中的元素是实现了Comparable.forEach(author -> System.out.println(author.getAge()));}

(六)中间操作之limit

limit可以设置流的最大长度,超出的部分将被抛弃。程序举例如下:

    private static void test07(){List<Author> authors = getAuthors();//对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中年龄最大的两个作家的姓名。authors.stream().distinct().sorted((author1,author2) -> author2.getAge() - author1.getAge()) //如果调用空参的sorted方法, 需要流中的元素是实现了Comparable.limit(2).forEach(author -> System.out.println(author.getName()));}

(七)中间操作之skip

skip可以跳过流中的前n个元素,返回剩下的元素。程序举例如下:

 	private static void test08(){List<Author> authors = getAuthors();//打印除了年龄最大的作家外的其他作家,要求不能有重复元素,并且按照年龄降序排序。authors.stream().distinct().sorted((author1,author2) -> author2.getAge() - author1.getAge()) //如果调用空参的sorted0方法, 需要流中的元素是实现了Comparable.skip(1).forEach(author -> System.out.println(author.getName()));}

(八)中间操作之flatMap

map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素,类似于展开操作的作用。程序举例如下:

    private static void test09(){List<Author> authors = getAuthors();//打印所有书籍的名字。要求对重复的元素进行去重.authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getName()).distinct().forEach(name -> System.out.println(name));}

(九)终结操作之forEach

forEach对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体操作。程序举例如下:

    private static void test10(){List<Author> authors = getAuthors();//输出所有作家的名字authors.stream().map(Author::getName).distinct().forEach(name -> System.out.println(name));}

(十)终结操作之count

count可以用来获取当前流中元素的个数。程序举例如下:

    private static void test11(){List<Author> authors = getAuthors();//打印这些作家的所出书籍的数目,注意删除重复元素long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();System.out.println(count);}

(十一)终结操作之max&min

max&min可以用来获取流中的最值。程序举例如下:

    private static void test12(){List<Author> authors = getAuthors();//分别获取这些作家的所出书籍的最高分和最低分并打印。long max = authors.stream().flatMap(author -> author.getBooks().stream()).max(Comparator.comparingInt(Book::getScore)).get().getScore();System.out.println(max);long min = authors.stream().flatMap(author -> author.getBooks().stream()).min(Comparator.comparingInt(Book::getScore)).get().getScore();System.out.println(min);}

(十二)终结操作之collect

collect可以把当前流转换成一个集合。程序举例如下

  private static void test13(){List<Author> authors = getAuthors();//获取一个存放所有作者名字的List集合List<String> authorNameList = authors.stream().map(Author::getName).distinct().collect(Collectors.toList());//获取一个所有书名的Set集合。Set<Book> bookNameSet = authors.stream().flatMap(author -> author.getBooks().stream()).collect(Collectors.toSet());//获取一个map集合,map的key为作者名,value为List<Book>Map<String, List<Book>> authorBookMap = authors.stream().distinct().collect(Collectors.toMap(Author::getName, Author::getBooks));}

(十三)终结操作之anyMatch&allMatch&noneMatch

anyMatch可以用来判断是否有任意符合匹配条件的元素,结果为boolean类型。如果都符合结果为true,否则结果为false。

allMatch可以用来判断是否都符合匹配条件,结果为boolean类型。如果都符合结果为true,否则结果为false。

noneMatch可以判断流中的元素是否都不符合匹配条件。如果都不符合结果为true,否则结果为false。

程序举例如下:

    private static void test16(){List<Author> authors = getAuthors();//判断是否有年龄在29以上的作家boolean isExitSomeKindAuthor = authors.stream().anyMatch(author -> author.getAge() > 29);List<Author> authors = getAuthors();//判断是否所有的作家都是成年人boolean isAllAdult = authors.stream().allMatch(author -> author.getAge()>=18);List<Author> authors = getAuthors();//判断作家是否都没有超过100岁的。boolean isAllLowerHundrenAge = authors.stream().noneMatch(author -> author.getAge()>=100);}

(十四)终结操作之findAny

findAny获取流中的任意一个元素。程序举例如下:

    private static void test17(){List<Author> authors = getAuthors();//获取任意一个大于18的作家,如果存在就输出他的名字authors.stream().filter(author -> author.getAge() < 18).findAny().ifPresent(author -> System.out.println(author.getName())); //ifPresent 如果存在}

(十五)终结操作之findFirst

获取流中的第一个元素。程序举例如下:

    private static void test18(){List<Author> authors = getAuthors();//获取一个年龄最小的作家,并输出他的姓名String name = authors.stream().sorted(Comparator.comparingInt(Author::getAge)).findFirst().get().getName();System.out.println(name);}

(十六)终结操作之reduce

reduce的作用是把stream中的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和在初始化值的基础上进行计算,计算结果再和后面的元素计算。

reduce原理示意:

T result = identity;
for (T element : this stream)result = accumulator .apply(result,element)
return result;

使用时程序举例如下:

    private static void test19(){List<Author> authors = getAuthors();//使用reduce求所有作者年龄的和Integer sum = authors.stream().distinct().map(author -> author.getAge()).reduce(0,(result, element) -> Math.addExact(result,element));System.out.println(sum);//使用reduce求所有作者中年龄的最大值Integer max = authors.stream().distinct().map(author -> author.getAge()).reduce(Integer.MIN_VALUE,(result, element) -> Math.max(result,element));System.out.println(max);//使用reduce求所有作者中年龄的最小值Integer min = authors.stream().distinct().map(author -> author.getAge()).reduce(Integer.MAX_VALUE,(result, element) -> Math.min(result,element));System.out.println(min);}

(十七)并行流

当流中有大量元素时,我们可以使用并行流去提高操作的效率。其实并行流就是把任务分配给多个线程去完成。如果我们自己去用代码实现的话其实会非常的复杂,并且要求你对并发编程有足够的理解和认识。而如果我们使用Stream的话,我们只需要修改一个方法的调用就可以使用并行流来帮我们实现,从而提高效率。

程序示例如下:
parallel方法可以把串行流转换成并行流 也可以通过parallelStream直接获取并行流对象

  private static void test20() {Stream<Integer> stream = Stream.of(1,2,3,4, 5,6,7,8,9,10);Integer sum = stream.parallel().peek(num -> System.out.println(num+Thread.currentThread().getName())) //通常用于调试和日志记录,可以在peek()中输出元素的信息,或者对元素进行一些检查操作。.filter(num -> num > 5).reduce((result, ele) -> result + ele).get() ;System.out.println(sum);Integer sum1 = Arrays.asList(1,2,3,4, 5,6,7,8,9,10).parallelStream().peek(num -> System.out.println(num+Thread.currentThread().getName())) //通常用于调试和日志记录,可以在peek()中输出元素的信息,或者对元素进行一些检查操作。.filter(num -> num > 5).reduce((result, ele) -> result + ele).get();System.out.println(sum1);}

Optional包装类

Optional类似于包装类,可以把我们的具体数据封装Optional对象内部。然后我们去使用Optional中封装好的方法操作封装进去的数据就可以非常优雅的避免空指针异常。

Stream中的一些操作可能会返回Optional类型的结果,比如findFirst()、findAny()等操作,这些操作可能会返回一个包含结果的Optional对象,或者一个空的Optional对象。另外,Stream也提供了一些操作可以将Optional对象转换为Stream,比如Stream.ofNullable()方法可以将一个Optional对象转换为包含该对象的Stream。因此,Optional和Stream在处理可能为空的值时可以相互配合使用。

以下是Optional的一些使用示例:

public class OptionalDemo {public static void main(String[] args) {test04();}/** 创建对象* 我们一般使用Optional的静态方法ofNullable来把数据封装成一个Optional对象。无论传入的参数是否为nul都不会出现问题。*/private static void test01() {Optional<Author> authorOptional = getAuthorOptional();authorOptional.ifPresent(author -> System.out.println(author.getName()));}private static Optional<Author> getAuthorOptional(){Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);// Optional.of(T) 无法排除空指针报错情况,或者return author ==nul1?Optional.empty() :Optional.of(author)return Optional.ofNullable(author);}/** 获取值*  可以使用get方法获取,但是不推荐。因为当Optional内部的数据为空的时候会出现异堂,*  orElseGet 获取数据并且设置数据为空时的默认值。*  orElseThrow 获取数据,如果数据不为空就能获取到该数据。如果为空则根据你传入的参数来创建异常抛出。*/private static void test02() {Optional<Author> authorOptional = getAuthorOptional();String name = authorOptional.orElseGet(() -> new Author()).getName();System.out.println(name);String name1 = authorOptional.orElseThrow(() -> new RuntimeException("数据为null")).getName();System.out.println(name1);}/** 过滤* 我们可以使用filter方法对数据进行过滤。* 如果原本是有数据的,但是不符合判断,也会变成一个无数据的Optional对象。**/private static void test03() {Optional<Author> authorOptional = getAuthorOptional();String name = authorOptional.filter(author -> author.getAge() > 100).orElseGet(() -> new Author()).getName();System.out.println(name);}/** 判断* 我们可以使用isPresent方法进行是否存在数据的判断。如果为空返回值为false,如果不为空,返回值为true。但是这种方式并不能体现* Optional的好处,更推荐使用ifPresent方法。*/private static void test04() {Optional<Author> authorOptional = getAuthorOptional();// isPresentif (authorOptional.isPresent()){System.out.println(authorOptional.get().getName());}// ifPresentauthorOptional.ifPresent(author -> System.out.println(author.getName()));}/** 数据转换* Optional还提供了map可以让我们的对数据进行转换,并且转换得到的数据也还是被Optiona包装好的,保证了我们的使用安全* 例如我们想获取作家的书籍集合。*/private static void test05() {Optional<Author> authorOptional = getAuthorOptional();Optional<List<Book>> booksOptional = authorOptional.map(author -> author.getBooks());booksOptional.ifPresent(books -> books.stream().forEach(book -> System.out.println(book.getName())));}
}

函数式接口

只有一个抽象方法的接口我们称之为函数接口。JDK的函数式接口都上了@Functionallnterface 注解进行标识。但是无论是否加上该注解只要接口中只有一个抽象方法,都是函数式接口。

只要是函数式接口就可以使用函数式编程方法,函数式编程方法的目的就是为了专注于业务,而无需花费精力在名称上。

函数式接口示例如下:

@FunctionalInterface
public interface FunctionalInterfaceExample1<T> {void accept(T t);
}
@FunctionalInterface
public interface FunctionalInterfaceExample2<R,T> {R accept(T t);
}

最后

上述知识总结来自于b站up主三更草堂高质的课程视频,链接如下:
【Lambda表达式&Stream流-函数式编程-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂】

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

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

相关文章

2023年山东省职业院校技能大赛信息安全管理与评估二三阶段样题

2023年山东省职业院校技能大赛信息安全管理与评估二三阶段 样题 第二阶段 模块二 网络安全事件响应、数字取证调查、应用程序安全 一、竞赛内容 Geek极安云科专注技能竞赛技术提升&#xff0c;基于各大赛项提供全面的系统性培训&#xff0c;拥有完整的培训体系。团队拥有曾…

docker部署elasticsearch8.x

docker部署elasticsearch8.x 提示1 注意版本差别1.1 docker修改配置1.1.2 docker使用vim报命令不存在的解决办法1.1.3 docker 容器内报错 E: List directory /var/lib/apt/lists/partial is missing. - Acquire ( : No such file or directory) 或者其他权限 PermissionError: …

Flinksql bug :Illegal mixing of types in CASE or COALESCE statement

报错信息 org.apache.flink.table.api.ValidationException: SQL validation failed. From line 66, column 23 to line 68, column 46: Illegal mixing of types in CASE or COALESCE statement org.apache.calcite.runtime.CalciteContextException: From line 66, column 2…

【Delphi】一个函数实现ios,android震动功能 Vibrate(包括3D Touch 中 Peek 震动等)

一、前言 我们在开发移动端APP的时候&#xff0c;有时可能需要APP能够提供震动功能&#xff0c;以便提醒操作者&#xff0c;特别是ios提供的3D Touch触感功能&#xff0c;操作者操作时会有触感震动&#xff0c;给操作者的感觉很友好。那么&#xff0c;在Delphi的移动端FMX开发中…

团建策划信息展示服务预约小程序效果如何

团建是中大型企业商家每年举办的员工活动&#xff0c;其形式多样化、具备全部参与的娱乐性。但在实际策划流程及内容时&#xff0c;部分公司便会难以入手&#xff0c;术业有专攻&#xff0c;这个时候团建策划公司便会发挥效果。 如拓展训练、露营、运动会、体育竞技等往往更具…

【算法】算法题-20231207

这里写目录标题 一、共同路径二、数字列表排序三、给定两个整数 n 和 k&#xff0c;返回 1 … n 中所有可能的 k 个数的组合。 一、共同路径 给你一个完整文件名组成的列表&#xff0c;请编写一个函数&#xff0c;返回他们的共同目录路径。 # nums[/hogwarts/assets/style.cs…

五花八门客户问题(BUG) - 数据库索引损坏

问题 曾经有个客户问题&#xff0c;让我们开发不知所措了很久。简单点说就是客户的index周期性的损坏&#xff0c;即使全部重建后经历大约1~2周数据update后也会坏掉。导致的直接结果&#xff1a;select出来的数据不对。问题很严重。 直接看损坏的index文件看不出什么蛛丝马迹…

做题笔记:SQL Sever 方式做牛客SQL的题目--VQ

----VQ 查询用户刷题日期和下一次刷题日期 现有牛客刷题记录表questions_pass_record &#xff0c;请查询用户user_id&#xff0c;刷题日期date &#xff08;每组按照date降序排列&#xff09;和该用户的下一次刷题日期nextdate&#xff08;若是没有则为None&#xff09;&#…

算法通关村第十七关-黄金挑战跳跃问题

大家好我是苏麟 , 今天说说跳跃问题 . 跳跃游戏 描述 : 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff…

【ML】LSTM应用——预测股票(基于 tensorflow2)

LSTM 应用预测股票数据 所用数据集&#xff1a;https://www.kaggle.com/datasets/yuanheqiuye/bank-stock 基于&#xff1a;tensorFlow 2.x 数据处理 import numpy as np import pandas as pd from matplotlib import pyplot as plt from sklearn.model_selection import tr…

4-Docker命令之docker start

1.docker start介绍 docker start命令是用来启动一个或多个已经被停止的docker容器。 2.docker start用法 docker start [参数] container [container......] [root@centos79 ~]# docker start --helpUsage: docker start [OPTIONS] CONTAINER [CONTAINER...]Start one or…

HBase-架构与设计

HBase架构与设计 一、背景二、HBase概述1.设计特点2.适用场景2.1 海量数据2.2 稀疏数据2.3 多版本数据2.4 半结构或者非结构化数据 三、数据模型1.RowKey2.Column Family3.TimeStamp 四、HBase架构图1.Client2.Zookeeper3.HMaster4.HRegionServer5.HRegion6.Store7.StoreFile8.…

【链表】206.反转链表

题目 法1:递归写法 class Solution {public ListNode reverseList(ListNode head) {if (head null || head.next null) {return head;}ListNode last reverseList(head.next);head.next.next head;head.next null;return last;} }法2:迭代写法 class Solution {public …

Elasticsearch:什么是机器学习?

机器学习定义 机器学习 (ML) 是人工智能 (AI) 的一个分支&#xff0c;专注于使用数据和算法来模仿人类的学习方式&#xff0c;并随着时间的推移逐渐提高准确性。 计算机科学家和人工智能创新者 Arthur Samuel 在 20 世纪 50 年代首次将其定义为 “赋予计算机无需明确编程即可学…

【基于openGauss5.0.0简单使用DBMind】

基于openGauss5.0.0简单使用DBMind 一、环境说明二、初始化tpch测试数据三、使用DBMind索引推荐功能四、使用DBMind实现SQL优化功能 一、环境说明 虚拟机&#xff1a;virtualbox操作系统&#xff1a;openEuler 20.03 TLS数据库&#xff1a;openGauss-5.0.0DBMind&#xff1a;d…

2022年第十一届数学建模国际赛小美赛A题翼龙如何飞行解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 A题 翼龙如何飞行 原题再现&#xff1a; 翼龙是翼龙目中一个已灭绝的飞行爬行动物分支。它们存在于中生代的大部分时期&#xff1a;从三叠纪晚期到白垩纪末期。翼龙是已知最早进化出动力飞行的脊椎动物。它们的翅膀是由皮肤、肌肉和其他组…

Android 10.0 关闭相机开始录像时的快门声音

Android 10.0 关闭相机开始录像时的快门声音 近来接到项目需求反馈提到在使用相机录像时&#xff0c;点击开始录像按钮后快门的声音也会被录进去&#xff0c;需要将开始录像的快门声音关闭&#xff0c;具体修改参照如下&#xff1a; /vendor/mediatek/proprietary/packages/a…

云服务器与nas实现在冷热资源访问,nginx代理

在实际项目中&#xff0c;我们的文件存储是一个必不可少的环节&#xff0c;本博主了解到现在的存储方案有 购买纯系统的云服务器&#xff0c;自己安装个mino,再使用nginx代理给web使用购买OSS服务&#xff0c;现在有云厂商都有提供&#xff0c;储存价格也挺便宜的&#xff0c;…

13款趣味性不错(炫酷)的前端动画特效及源码(预览获取)分享(附源码)

文字激光打印特效 基于canvas实现的动画特效&#xff0c;你既可以设置初始的打印文字也可以在下方输入文字可实现激光字体打印&#xff0c;精简易用。 预览获取 核心代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&q…

生物动力葡萄酒的快速指南

虽然我们大多数人都熟悉有机酿酒和农业&#xff0c;但围绕生物动力学仍有许多困惑和神秘。无论你是否完全陌生&#xff0c;或者你已经听到一些小道消息&#xff0c;我们在这里揭开这种独特的葡萄酒生产方法的神秘面纱。 生物动力葡萄酒就是一个更全面的有机酿酒过程&#xff0c…