Java | Stream流、泛型、多线程 | 整理自用
1、lambda 表达式
lambda 的延迟执行
可以对程序进行优化,尤其是使用 if {} else {} 条件判断,先判断条件是否成立,再传入计算好的参数。
functionName( paramters, () -> { } );
2、stream 流式思想
stream 是jdk8之后出现的语法
拼接流式模型:建立一个生产线,按照生产线来生产商品
经过了过滤、映射、跳过、计数等多步操作,集合元素的处理方案
filter、map、skip,得益于lambda的延迟执行特性。
(1) 获取流
数据源流的来源:集合、数组
java.util.stream.Stream<T>
// 所有的Collention 集合 ( list, map, set.. )都可以通过stream默认方法获取流
ArrayList<String> arrStr = new ArrayList();
stream<String> stream1 = arrStr.stream(); // Stream接口的静态方法 of 可以获取数组对应的流
Stream<Integer> Stream2 = Stream.of(1, 4, 3, 5, 5);
// Stream 流只能使用一次,使用完之后就直接关闭了。即
Stream<String> stream3 = Stream.of("1", "2", "9", "4");
stream3.forEach((String str)-> {
System.out.println(str);
}); // 再重新打印一次,输出异常
stream3.forEach((String str)-> {
System.out.println(str); });
(2)取用前几个:limit 如果当前长度大于参数进行截取,否则不截取。limit 是一个延迟方法,返回的是一个新的流
Stream<String> stream4 = stream3.limit(2);
stream4.forEach( str -> System.out.println(str) );
(3)跳过前几个:skip 与 limit 相反
(4)流拼接: concat
java 泛型
java泛型不允许静态化,类中含有 static 会报错:
// 分类:
// 1、泛型类
public class 类名<T> { } // 2、泛型接口
public interface Generator<T> { } // 3、泛型方法
类型通配符 ?
区别:
<? extends T> 该通配符所代表的类型是T类型的子类
<? super T> 该通配符所代表的类型是T类型的父类
反射提供的是runtime阶段获取类的class 实例、方法、属性、注解, 并且能够调用勒的方法的途径。
java 多线程
PS:查阅了相关资料和视频,这种类似于计算机内核原理的知识,建议翻阅教科书,了解一下什么是堆,栈,缓冲区等计算机专属词汇,网上很多人讲的不严谨,如果有人想深入大体了解内部机制,强烈安利这个教程 计算机系统基础,有好几季,课程比较长,虽然比较难
并行:指两个或多个事件在同一时刻运行(同时运行)。
并发:指两个或多个事件在同一个时间间隔内发生。
线程与进程两者的关系图,推荐看这个图,比较严谨:
https://blog.csdn.net/weixin_41490593/article/details/90704559
多线程编程:
Java中线程有四种创建方式:
l 继承Thread类
l 实现Runnable接口
l 实现Callable接口
l 线程池
前三种方法相应的资料很多,这里仅仅粗略赘述线程池:
/*
java.util.concurrent.ExecutorService 线程池接口 线程池:容器 -- > 集合框架( ArrayList, HashSet, LinkedList<Thread>, HashMap ) 接口: static ExecutorService newFixedThreadPool(int nThreads) 创建一个可重用固定线程数的线程池 ExecutorService 接口,返回的是ExecutorService接口的实现类对象,可用ExecutorService接口接收(面向接口编程) submit() 执行线程 线程池会一直开启,使用完了线程,会自动吧线程归还给线程池,线程可以继续执行。 shutdown() 关闭执行, 如果已经执行了此方法,如果重新 使用 submit 方法, 会报错 。 线程池的使用步骤: 1、使用线程池的工厂类 Executors 里面提供的 newFixedThreadPool 生产一个指定线程池数量的线程池 2、创建一个类,实现 Runnable 接口,重写 run 方法,设置线程任务 3、调用ExecutorService 中的方法 submit ,传递线程任务(实现类), 开启线程, 执行 run 方法 4、调用ExecutorService 中的方法 shutdown ,销毁线程池 */
进程间协作:
wait : 是object 类中的一个方法,当前线程释放自己的锁标记,让出CPU资源,当前的线程进入到等待队列中
notify: 是object 类中的一个方法,唤醒等待队列中的一个进程,使这个线程进入锁池
notifyAll : 唤醒等待队列中的等待当前对象的所有线程,并使这些线程进入锁池
java线程同步机制:
锁,通俗地讲就是告诉其他的线程,这里的鱼塘我承包了,等我解锁你再用
同步锁: 多个线程看到的锁, 需要是同一把锁。
静态方法:同步锁就是类锁, 当前类.class 属性 --> class 文件对象,这一点涉及到 java反射,静态方法优先于对象。
非静态方法: 同步锁 是 this,this 是在创建对象之后产生的。
Runnable r = () -> {
while(TicketCenter.restCount > 0 ) {
// synchronized ("") {
synchronized (Generic.class) {
if (TicketCenter.restCount <= 0) {
return ;
}
System.out.println("当前运行的进程 : " + Thread.currentThread().getName() + " " + --Center.restCount);
}
}
}; Thread t1 = new Thread(r, "thread - 1");
Thread t2 = new Thread(r, "thread - 2");
Thread t3 = new Thread(r, "thread - 3");
Thread t4 = new Thread(r, "thread - 4"); t1.start();
t2.start();
t3.start();
t4.start();
class Center {
public static int restCount = 100; } // 如果一个方法需要执行同步操作,直接加入 synchronize 关键字
// 同步方法
private synchronized static void funControl() {
// synchronized (Generic.class) {
if (TicketCenter.restCount <= 0) {
return ; }
System.out.println("当前运行的进程 : " + Thread.currentThread().getName() + " " + --TicketCenter.restCount);
// }
}
显式锁 : ReentrantLock 重入锁
当接触临界区时 ReentrantLock 是在 Lock 接口实现的。临界资源由 lock() 和 unlock() 组成。lock() 就是让当前工作进程进入资源,然后使其他的试图进入临界资源的进程阻塞。
ReentrantLock 能够让进程不止一次的进入资源。当这个进程第一次进入内存的时候,有一个计数器记为1,在解锁之前,一个进程又进入时,计数器递增1,每一次unlock() 时,计数器递减1。当计数器为0时,资源被解锁。
Reentrant Locks 可重入锁还提供一个公平性参数,通过该参数,锁将遵守锁请求的顺序,即在线程解锁资源后,锁将转到等待时间最长的线程。此公平模式是通过将true传递给锁的构造函数来设置的。
/*
* 实例化一个锁对象
*/
ReentrantLock lock = new ReentrantLock(); Runnable r = () -> {
while(TicketCenter.restCount > 0 ) {
// 临界资源上锁
lock.lock(); if (TicketCenter.restCount <= 0) {
return ;
}
System.out.println("当前运行的进程 : " + Thread.currentThread().getName());
// 解锁
lock.unlock();
}
};
public void some_method()
{
reentrantlock.lock();
try
{
//Do some work
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
reentrantlock.unlock();
} }
// volatile关键字 以及 CAS与原子变量使用的不多,这里就不再赘述了。
Java | Stream流、泛型、多线程 | 整理自用的更多相关文章
- 全面吃透JAVA Stream流操作,让代码更加的优雅
全面吃透JAVA Stream流操作,让代码更加的优雅 在JAVA中,涉及到对数组.Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行 ...
- 一文带你入门Java Stream流,太强了
两个星期以前,就有读者强烈要求我写一篇 Java Stream 流的文章,我说市面上不是已经有很多了吗,结果你猜他怎么说:"就想看你写的啊!"你看你看,多么苍白的喜欢啊.那就&qu ...
- 深度掌握 Java Stream 流操作,让你的代码高出一个逼格!
概念 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选.排序.聚合等. Stream 的操作符大体上分为两种:中间操作符和终止操作符 中 ...
- Java Stream 流如何进行合并操作
1. 前言 Java Stream Api 提供了很多有用的 Api 让我们很方便将集合或者多个同类型的元素转换为流进行操作.今天我们来看看如何合并 Stream 流. 2. Stream 流的合并 ...
- Java Stream 流(JDK 8 新特性)
什么是 Steam Java 8 中新增了 Stream(流)来简化集合类的使用,Stream 本质上是个接口,接口中定义了很多对 Stream 对象的操作. 我们知道,Java 中 List 和 S ...
- Java Stream流的使用
流相关的方法可以分为三种类型,分别是:获取Stream流.中间方法.终结方法.中间方法会返回当前流,可以方便的进行链式调用. 流不可重复使用,否则会报错: java.lang.IllegalState ...
- Java Stream流排序null以及获取指定条数数据
Java8的Stream流的一些用法, //排序 carerVehEntityList = carerVehEntityList.stream().sorted( Comparator.compari ...
- Java Stream简介, 流的基本概念
在Javaor .net编程中, 我们经常见到"stream" 这个字眼. 我们大概知道这是个流的意思, 如果看完本文的话, 应该会有1个大概的概念. 一, Java中什么是St ...
- Java Stream 自定义Collector
Collector的使用 使用Java Stream流操作数据时,经常会用到各种Collector收集器来进行数据收集. 这里便深入了解一点去了解Collector的工作原理和如何自定义Collect ...
随机推荐
- Python 元编程 - 装饰器
Python 中提供了一个叫装饰器的特性,用于在不改变原始对象的情况下,增加新功能或行为. 这也属于 Python "元编程" 的一部分,在编译时一个对象去试图修改另一个对象的信息 ...
- 04- HTML常用标签
HTML标签分类 通过上节博客我们知道了网页的组成:文字 图片 连接 视频 音频.在HTML页面中,带有"< >"符号的元素被称为HTML标签,如上面提到的 <H ...
- 本地使用apache设置绑定多个域名
Apache开启了使用虚拟主机的功能: 打开Apache安装目录下conf/httpd.conf文件,找到 #LoadModule vhost_alias_module modules/mod_vho ...
- PE文件加节感染之Win32.Loader.bx.V病毒分析
一.病毒名称:Win32.Loader.bx.V 二.分析工具:IDA 5.5.OllyDebug.StudPE 三.PE文件加节感染病毒简介 PE病毒感染的方式比较多,也比较复杂也比较难分析,下面就 ...
- Android内核的编译和调试
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/70500488 一.Android内核源码的选择 Android手机设备内核源码的调 ...
- Android平台的so注入--LibInject
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/53890315 大牛古河在看雪论坛分享的Android平台的注入代码,相信很多搞An ...
- LA3027简单带权并查集
题意: 有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少? 思路: ...
- python-文件操作练习-配置文件读取、修改、删除
文件操作练习:http://www.cnblogs.com/wupeiqi/articles/4950799.html global log 127.0.0.1 local2 daemon maxco ...
- 一文带你详细介绍c++中的std::move函数
前言 在探讨c++11中的Move函数前,先介绍两个概念(左值和右值) 左值和右值 首先区分左值和右值 左值是表达式结束后依然存在的持久对象(代表一个在内存中占有确定位置的对象) 右值是表达式结束时不 ...
- Windows反调试技术(下)
OD的DBGHELP模块 检测DBGHELP模块,此模块是用来加载调试符号的,所以一般加载此模块的进程的进程就是调试器.绕过方法也很简单,将DBGHELP.DLL改名. #include <Wi ...