深入了解Java 8 新特性:Stream流的实践应用(一)

阅读建议

嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:

  1. 本篇文章大概一万多字,预计阅读时间长需要10分钟(不要害怕字数过多,其中有一大部分是示例代码,读起来是比较轻松的)。
  2. 本篇文章兼具实战性和理论性,是一篇质量分数较高的技术干货文章,建议收藏起来,方便时常学习与回顾,温故而知新。
  3. 创作不易,免费的点赞、关注,请走上一走,算是对博主一些鼓励,让我更有动力输出更多的干货内容。

前言

        早就打算写一篇文章来梳理一下Java8的新特性Stream流的相关应用,终于得空来完成这件事了。原先以为这块内容应该不会太多,当我梳理完成以后,发现居然有两万多字。当然,在这两万字中,有一部分是示例代码。考虑到一口读完这两字,对于我的读者小伙伴来说,太不友好了,于是乎我打算,把这些内容拆成两部分:

        第一部分,主要是梳理Stream的核心方法;

        第二部分,主要是梳理Collectors类的核心方法;Collectors类是Stream实践应用中非常重要的一个工具类,读完这两篇文章相信肯定能意识到这一点。

Stream是什么

        Java的Stream是Java 8 引入的一个新特性,它提供了一种简洁、优雅的方式来处理集合数据。Stream允许你将集合中的元素进行过滤、映射、排序等操作,并将结果转换为一个新的集合。并且使用Stream,你可以将一个集合转换为一个流,然后对这个流进行各种操作,最后将结果收集到一个新的集合中。这种处理方式非常适合处理大量数据,因为它允许你在内存中一次只处理一个或一小批数据,而不是一次性加载整个数据集到内存中。因此Stream是java8新增特性中一个非常有用且强大的。它的核心特性:

  1. 声明性:Stream的操作以声明的方式进行,这使得代码更易读、易懂。声明性编程强调的是“做什么”,而不是“如何做”,这使得代码更具可维护性和可扩展性。
  2. 可复合:Stream的操作可以链式地进行,即可以将多个操作链接起来运行。这种可复合的特性使得对数据的处理更简洁、更易于理解。
  3. 可并行:Stream可以并行处理数据,这是为了适应多核机器的时代,提高系统CPU、内存的利用率。并行流是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。

这些特性的能够给你带来的好处是:

  1. 提高代码的可读性和可维护性:通过使用声明性和链式操作,可以让代码更加简洁、易于理解和维护。
  2. 提高系统的性能:通过并行流的处理方式,可以充分利用多核CPU的性能,提高系统的处理速度和性能。
  3. 适应大数据时代的需求:随着大数据时代的到来,对大量数据的处理成为一项重要的任务。Stream的并行流处理方式可以满足这种需求,提高数据处理的速度和效率。

Stream的核心方法

Stream#filter

        Stream#filter 方法用于根据指定的条件筛选出 Stream 中的元素。filter 方法接收一个 Predicate 参数,Predicate接口在Java中是一个函数式接口,它只有一个抽象方法,即test(T t),用于接受一个参数并返回一个布尔值。这个接口通常用于定义一个断言(即条件),在编程中可以用于对集合进行过滤或者在函数式编程中作为参数使用

        示例:

        使用Stream#filter()过滤出年龄等于18的学生信息

@Test
public void test() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));List<Student> targetList = list.stream().filter(item -> item.getAge() == 18).collect(Collectors.toList());for (Student student : targetList) {Assert.isTrue(student.getAge() == 18, "单元测试结果与预期不匹配");}
}

Stream#map

        Stream#map方法,它用于将 Stream 中的每个元素映射到另一个元素,Stream#map()方法接受一个Function类型的参数,而Function接口是Java 8引入的函数式接口,主要方法是apply(T t),它接受一个参数并返回一个结果。这个方法可以被看作是一个操作或者函数,它对输入进行某种处理并产生输出。

        示例:

        先使用Stream#filter()过滤出年龄大于18的学生信息,再使用Stream#map()方法把过滤到的结果信息映射成为另外一个类型的

@Test
public void test2() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));List<Person> targetList = list.stream().filter(item -> item.getAge() > 18).map(item -> new Person(item.getName(), item.getAge())).collect(Collectors.toList());Assert.notNull(targetList, "单元测试结果与预期不匹配");
}

Stream#mapToInt

        Stream.mapToInt()是Java8中Stream API 的一部分,mapToInt() 方法接受一个函数接口作为参数,可以用于将 Stream 中的元素映射为 int 类型,当调用 mapToInt() 方法时,Java 会遍历原始 Stream 中的每个元素,并将每个元素传递给指定的函数。然后,Java 会收集这些结果,最后返回返回一个 IntStream,在IntStream 上可以执行一些特殊的操作,如求和、统计、排序、最大值、最小值等

                示例:

  • 把学生信息中的年龄数据过滤到一个数组中
  • 统计所有学生信息的总年龄
  • 统计所有学生信息中的最大年龄
@Test
public void test3() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));//把学生信息中的年龄数据过滤到一个数组中int[] ageArr = list.stream().mapToInt(item -> item.getAge()).toArray();for (int age : ageArr) {System.out.println(age);}//统计所有学生信息的总年龄int sum = list.stream().mapToInt(item -> item.getAge()).sum();System.out.println(sum);//统计所有学生信息中的最大年龄Integer maxAge = list.stream().map(item -> item.getAge()).max((v1, v2) -> {if (v1 > v2) {return 1;} else if (v1 < v2) {return -1;}return 0;}).get();System.out.println(maxAge);
}

Stream#distinct

        Stream#distinct 方法用于去除 Stream 中的重复元素,它会返回由不同元素组成的新 Stream。这个方法实际上调用了 Object.equals(Object o) 方法,默认的行为是比较两个对象的引用是否相等。如果两个对象的引用相等,则认为它们相等;反之则认为它们不相等。因此,在使用 distinct 方法时,如果需要比较的元素是自定义对象,需要在自定义类中重写 equals() 和 hashCode() 方法。

        示例:

        给存在重复学生信息的集合进行去重操作并回收结果

@Test
public void test4() {//wangwu的信息存在重复List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17), new Student("wangwu", 17));List<Student> targetList = list.stream().distinct().collect(Collectors.toList());Assert.isTrue(list.size() > targetList.size(), "单元测试结果与预期不匹配");
}

Stream#sorted

        Stream#sorted 方法用于对 Stream 中的元素进行排序。它返回一个包含按指定排序规则排序后元素的新的 Stream,默认情况下,使用自然顺序排序(对于实现了 Comparable 的元素类型)。

        示例

  • 自然排序,默认是升序,这里是首字母升序
  • 自定义排序,lambda表达式定义排序逻辑,这里是降序
@Test
public void test5() {//自然排序,默认是升序,这里是首字母升序List<String> names = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");List<String> sortedCopy = names.stream().sorted().collect(Collectors.toList());String str = sortedCopy.stream().collect(Collectors.joining(","));System.out.println(str); //自定义排序,lambda表达式定义排序逻辑,这里是降序List<Integer> ages = Arrays.asList(18, 17, 19, 20);List<Integer> ages2 = ages.stream().sorted((v1, v2) -> {if (v1 > v2) {return -1;} else if (v1 < v2) {return 1;} else {return 0;}}).collect(Collectors.toList());System.out.println(ages2.toString());
}

Stream#peek

        Stream.peek() ,它为每个元素提供了一个消费函数。该方法返回由该流的元素组成的流,并对每个元素执行所提供的 Consumer 操作方法,Consumer接口是java8的一个函数式接口,它定义了一个名为 accept 的抽象方法,该方法接受一个参数并且不返回任何结果。peek() 方法主要用于调试,以便在元素流过管道中的某个点时查看它们。peek() 是一个中间操作方法,将在调用终端方法时执行。

        示例

        打印输出以z开头的姓名;

@Test
public void test6() {List<String> names = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");Stream<String> stream = names.stream().peek(item -> {if (item.startsWith("z")) {System.out.println(item);}});//在执行collect方法前,peek方法内的lambda表达式不会被执行;只有在终端方法collect()被调用时才会执行List<String> names2 = stream.collect(Collectors.toList());System.out.println(names2);
}

Stream#limit

        Stream#limit 方法用于限制 Stream 中元素的数量。它返回一个包含指定数量元素的新的 Stream,而不会改变原始 Stream 中的元素顺序。

        示例

        获取集合内的前两个元素

@Test
public void test7() {List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");List<String> result = list.stream().limit(2).collect(Collectors.toList());System.out.println(result.toString());
}

Stream#skip

        Stream#skip 方法,用于跳过 Stream 中的前 n 个元素。它返回一个新的 Stream,该 Stream 不包含原始 Stream 中的前 n 个元素。

        示例:

        跳过集合内的前3个元素,而获取剩余其他元素

@Test
public void test8() {List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");List<String> result = list.stream().skip(3).collect(Collectors.toList());System.out.println(result.toString());
}

Stream#forEach

        Stream#forEach 方法,用于对 Stream 中的每个元素执行遍历操作。该方法没有返回值,它只会对 Stream 中的每个元素进行遍历操作,而不会改变 Stream 中的元素或产生新的结果。

示例

@Test
public void test9() {List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");list.stream().forEach(item-> System.out.println(item));
}

Stream#forEachOrdered

        Stream#forEachOrdered方法 ,用于对 Stream 中的每个元素按照它们在 Stream 中的顺序执行一个提供的操作。与 Stream#forEach 方法不同的是,forEachOrdered方法 会保证操作的顺序与 Stream 中元素的顺序一致,而Stream#forEach方法则不保证操作的顺序。

        示例

@Test
public void test10() {List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");list.stream().forEachOrdered(item-> System.out.println(item));
}

Stream#reduce

        Stream#reduce 方法,用于将 Stream 中的元素进行某种聚合操作,并返回一个单一的结果。它接受一个 BinaryOperator 作为参数,该操作接受两个参数并返回一个结果。在聚合过程中,每个元素都会与前一个元素进行操作,并将结果传递给下一个元素,直到处理完所有元素并返回最终结果。使用 Stream#reduce 方法可以对数据进行求和、求积、求最大值、求最小值等各种聚合操作

        示例:

        求集合内所有学生信息中的学生年龄之和

@Test
public void test11() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));Integer totalAge = list.stream().reduce((val1, val2) -> new Student(val1.getAge() + val2.getAge())).get().getAge();System.out.println(totalAge);
}

Stream#collect

        Stream#collect 方法,用于将 Stream 中的元素收集到集合或其他对象中,如 List、Set、Map 等。它接受一个 Collector 作为参数,该 Collector 是一个函数式接口,用于定义将元素收集到目标集合或其他对象中的操作。

        关于Collector,可以参考Collectors类,该类内置很多静态方法,用于获取常见的Collector;

Stream#min

        Stream#min方法,用于找到 Stream 中元素的最小值。它返回 Stream 中元素的最小值,如果 Stream 为空,则返回 Optional.empty。Stream#min方法接受一个比较器作为参数,可以根据特定的业务逻辑或数据类型自定义自己的比较逻辑。

        示例

        获取集合内年龄最大的学生信息

    @Testpublic void test12() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));Student student = list.stream().min((v1, v2) -> {if (v1.getAge() > v2.getAge()) {return 1;} else if (v1.getAge() < v2.getAge()) {return -1;} else {return 0;}}).get();System.out.println(student.toString());}
}

Stream#max

        与Stream#min方法类似,Stream#max用于找到 Stream 中元素的最大值,Stream#max方法接受一个比较器作为参数,可以根据特定的业务逻辑或数据类型自定义自己的比较逻辑。

@Test
public void test13() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));Student student = list.stream().max((v1, v2) -> {if (v1.getAge() > v2.getAge()) {return -1;} else if (v1.getAge() < v2.getAge()) {return 1;} else {return 0;}}).get();System.out.println(student.toString());
}

Stream#count

        Stream#count方法的功能是计算Stream中元素的数量,并返回一个long类型的数值。这个方法不会将Stream中的所有元素收集到一个集合中,而是直接在流上执行计数操作,因此可以高效地计算出Stream中元素的数量。单纯使用count(),与size()效果是一样的,实际使用过程中,一般会结合其他中间方法使用,如filter();

        示例

        统计姓名集合中以z开头的元素有几个

@Test
public void test14() {List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");long num = list.stream().filter(item -> item.startsWith("z")).count();System.out.println(num);
}

Stream#anyMatch

        Stream#anyMatch 方法,用于判断 Stream 中的元素是否满足指定的匹配条件。如果 Stream 中至少有一个元素满足匹配条件,则返回 true;否则返回 false。

        示例

        统计学生信息集合中,是否存在有年龄小于18的学生信息

@Test
public void test15() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));boolean flag = list.stream().anyMatch(item -> item.getAge() < 18);System.out.println(flag);//结果是true
}

Stream#allMatch

        Stream#allMatch 方法用于检查 Stream 中的所有元素是否满足给定的条件函数。如果 Stream 中的所有元素都满足条件函数,则返回 true,否则返回 false,可以用在需要检查 Stream 中所有元素是否满足某个条件的场景中。

        示例

        检查学生集合集合中的学生年龄是否全部大于18

@Test
public void test16() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));boolean flag = list.stream().allMatch(item -> item.getAge() < 18);System.out.println(flag);//结果是false
}

Stream#noneMatch

        Stream#noneMatch方法,它用于检查Stream中的元素是否都不满足给定的断言条件。Stream#noneMatch方法接受一个Predicate(断言)作为参数,该断言用于测试每个元素是否满足某个条件。如果Stream中没有任何一个元素满足断言条件,则noneMatch方法返回true;否则返回false。

        示例

        检查学生信息集合中的学生姓名首字母是否都不是以a开头

@Test
public void test17() {List<Student> list = Arrays.asList(new Student("zhangsan", 18), new Student("lisi", 19), new Student("wangwu", 17));boolean flag = list.stream().noneMatch(item -> item.getName().startsWith("a"));System.out.println(flag);//结果是
}

Stream#findFirst

        Stream#findFirst 方法,用于查找并返回 Stream 中的第一个元素。使用 findFirst 方法可以方便地查找符合特定条件的第一个元素,而无需遍历整个 Stream。findFirst 方法不会在 Stream 为空时抛出异常,而是返回一个空的 Optional 对象。可以结合着filter方法一起使用。

        示例

        检索出学生姓名集合中学生姓名以z开头的第一个姓名

@Test
public void test18() {List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");String name = list.stream().filter(item->item.startsWith("w")).findFirst().get();System.out.println(name);//结果是wangwu
}

Stream#findAny

        在 Java 11 中,Stream.findAny() 方法用于在流中查找满足特定条件的第一个元素。这个方法返回一个 Optional 对象,表示可能的元素。如果流为空,则返回一个空的 Optional。

        示例

@Test
public void test19(){List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");String name = list.stream().findAny().get();System.out.println(name); //结果为zhangsanList<String> list2=new ArrayList<>();boolean flag = list2.stream().findAny().isEmpty();System.out.println(flag);//结果为true
}

Stream#of

        Stream#of() 方法,用于创建一个包含指定元素的 Stream。这个方法接收一个可迭代的数据源,如数组或集合,并返回一个包含该数据源中所有元素的 Stream。

        示例

@Test
public void test20(){long count = Stream.of("zhangsan", "lisi", "wangwu", "zhaoliu").count();System.out.println(count);
}

Stream#iterator

        Stream#iterator 方法,用于获取一个迭代器,用于遍历 Stream 中的元素。这个方法返回一个 Iterator 对象,可以使用 next() 方法依次获取 Stream 中的每个元素。

@Test
public void test21(){Iterator<String> iterator = Stream.of("zhangsan", "lisi", "wangwu", "zhaoliu").iterator();while (iterator.hasNext()){String next = iterator.next();System.out.println(next);}
}

下一篇:深入了解Java 8 新特性:Stream流的实践应用(二) 

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

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

相关文章

数据结构【DS】图的遍历

BFS 要点 需要一个辅助队列visited数组&#xff0c;防止重复访问 复杂度 时间复杂度&#xff1a;访问结点的时间访问所有的边的时间 广度优先生成树 邻接表存储的图的表示方式不唯一&#xff0c;生成树也不唯一 DFS 复杂度 时间复杂度&#xff1a;访问结点的时间访问所有…

万字解析设计模式之桥接模式、外观模式

一、桥接模式 1.1概述 桥接模式是一种结构型设计模式&#xff0c;它的作用是将抽象部分和实现部分分离开来&#xff0c;使它们能够独立地变化。这样&#xff0c;抽象部分和实现部分可以分别进行扩展&#xff0c;而不会相互影响。它是用组合关系代替继承关系来实现&#xff0c;…

全链路压测的步骤及重要性

全链路压测是一种系统性的性能测试方法&#xff0c;旨在模拟真实用户场景下的完整操作流程&#xff0c;全面评估软件系统在不同压力下的性能表现。这种测试方法对于保证应用程序的高可用性、稳定性和可扩展性至关重要。 1. 全链路压测概述 全链路压测是在模拟实际用户使用场景的…

什么是PyQt?

什么是Qt? Qt是一个著名的跨平台C图形用户界面应用程序开发框架。它由Qt公司开发,于1995年首次发布。Qt支持各种桌面,嵌入式和移动平台。 Qt的特点包括: 跨平台支持:Qt应用程序可以编译到多种平台运行,包括Windows,Mac,Linux,Android,iOS等。这大大简化了跨平台应用程序的开…

2019ICPC南京站

A A Hard Problem 题意&#xff1a;给定一个正整数 n &#xff0c;你需要找出最小整数 k&#xff0c;满足&#xff1a;从{1,2,⋯,n}中任意选择长度为k的子集&#xff0c;存在两个不同的整数 u,v∈T, 且 u 是 v 的因数。 思路&#xff1a;打表找规律 #include <bits/std…

JSP:Tag文件的使用

需求&#xff1a;多个JSP页面可能需要使用一些相同的信息 例如:导航栏、标题等。 目标&#xff1a;提高这些相同信息的代码的复用性。 方法&#xff1a;将这些相同的元素形成一种特殊的文件&#xff0c;以便所有页面都可以使用&#xff0c;即&#xff1a;Tag文件 1、Tag对…

MySQL数据库入门到大牛_基础_10_创建和管理表(创建和管理数据库;创建表;修改表;重命名表;删除表;清空表,内容扩展)

前面我们完成了查询结构的介绍&#xff0c;本章介绍DDL和DCL中的COMMIT和ROLL BACK。 文章目录 1. 基础知识1.1 一条数据存储的过程1.2 标识符命名规则1.3 MySQL中的数据类型 2. 创建和管理数据库2.1 创建数据库2.2 使用数据库2.3 修改数据库2.4 删除数据库 3. 创建表3.1 创建…

猫罐头哪个牌子好吃?精选5款好评率高的猫罐头推荐!

很多新手养猫的姐妹们都会为选罐头感到焦虑&#xff01;因为每种猫罐头都有优缺点&#xff0c;每只猫咪的胃口也都不同&#xff0c;所以只有综合考虑选择适合自家猫咪的猫罐头的才是最好的。所以姐妹们在选罐头之前可以先做好功课&#xff0c;了解一下怎么选好的猫罐头。 作为开…

Jmeter监听器

Jmeter监听器 一、监听器介绍二、监听器的类型三、监听器详解3.1 察看结果树3.2 Summary Report3.3 聚合报告3.4 后端监听器3.5 Aggregate Graph3.6 Comparison Assertion Visualizer&#xff08;比较断言可视化器&#xff09;3.7 JSR223 Listener3.8 Response Time Graph3.9 S…

欧科云链研究院:从香港SFC最新文件看链上交易合规必备之选

出品&#xff5c;欧科云链研究院 作者&#xff5c;Hedy Bi 近日&#xff0c;香港证监会在其官网发布“致持牌法团、获证监会发牌的虚拟资产服务提供者及有联系实体的通函 - 打击洗钱&#xff0f;恐怖分子资金筹集经更新的《打击洗钱&#xff0f;恐怖分子资金筹集的自我评估查…

CICD 持续集成与持续交付(2)

目录 gitlab 部署 jenkins 部署 配置 实时触发 自动化构建docker镜像 通过ssh插件交付任务 添加jenkins节点 RBAC pipeline jenkins结合ansible参数化构建 安装ansible 新建gitlab项目 jenkins新建项目playbook gitlab 部署 虚拟机最小需求&#xff1a;4G内存 4核cpu 下载&…

【智能优化算法】从蚁群到动物园

目录 引言蚁群优化算法&#xff08;ACO&#xff09;ACO 机理ACO 模型描述ACO 移动策略 粒子群优化算法&#xff08;PSO&#xff09;PSO 机理PSO 模型描述 萤火虫群优化算法&#xff08;GSO&#xff09;GSO 机理GSO 模型描述 群智能优化算法 引言 21世纪&#xff0c;人类社会已经…

ElementUI用el-table实现表格内嵌套表格

文章目录 一、效果图二、使用场景三、所用组件元素&#xff08;Elementui&#xff09;四、代码部分 一、效果图 二、使用场景 &#x1f6c0;el-form 表单内嵌套el-table表格 &#x1f6c0;el-table 表格内又嵌套el-table表格 三、所用组件元素&#xff08;Elementui&#xff…

Kubeadm部署Kubernetes Containerd集群

文章目录 概述一、硬件系统二、基础配置设置主机名配置主机名与IP地址解析关闭防火墙与selinux时间同步(ntp)升级系统内核配置内核转发及网桥过滤*安装ipset及ipvsadm关闭SWAP分区 三、Containerd准备Containerd获取下载解压Containerd配置文件生成并修改Containerd启动及开机自…

5年经验之谈 —— 性能测试如何定位分析性能瓶颈?

你好&#xff0c;我是小牛&#xff0c;目前在一家准一线互联网大厂做测试开发工程师。 对于一般公司普通测试工程师来说&#xff0c;可能性能测试做的并不是很复杂&#xff0c;可能只是编写下脚本&#xff0c;做个压测&#xff0c;然后输出报告结果&#xff0c;瓶颈分析和调优…

【Hello Go】Go语言复合类型

复合类型 分类指针基本操作new函数指针作为函数的参数 数组概述操作数据数组初始化数组比较在函数之间传递数组 slice概述切片的创建和初始化切片操作切片和底层数组关系内建函数appendcopy 切片作为函数传参 map概述创建和初始化常用操作赋值遍历 删除map作函数参数 结构体结构…

Python (十三) 输出

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

基于Python+TensorFlow+Django的交通标志识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 随着交通网络的不断扩展和智能交通系统的发展&#xff0c;交通标志的自动识别变得愈发重要。本项目旨在利用Python编…

利用SVD对图像进行压缩

利用SVD对图像进行压缩 使用SVD能够对数据进行降维&#xff0c;对图像进行SVD&#xff0c;降维之后然后重构数据&#xff0c;还原后的图像就是压缩后的图像。 SVD SVD进行图像压缩所依据的数学原理就是矩阵的近似表示&#xff1a; A m n ≈ U m k ∑ k k V k n T A_{m\…

基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码

基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于晶体结构优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…