java高级篇

目录

(一)泛型与枚举

(二)多线程基础

(三)注解与反射

(四)函数式编程

(五)IO流

(六)网络编程入门

(七)Optional类

(八)集合框架进阶


(一)泛型与枚举

  • 泛型 实质是一个类型占位符,单一字母表示
//泛型类 -在加载时声明 
public class person<T,E>{ 
 T son;
 E wife;
} 
-非T类型 
public class person<T>{
 void play(M operation){}
} 
//泛型方法 
-在类加载时声明 
public class Person<T>{
 void play(T operation){}
}
//静态泛型方法 
-静态方法和类无关也需声明 
public class Person{
 static <Q> void eat(Q food){}
} 
//泛型接口 
-实现类声明
public interface Person<T>{
 void eat(T food);
}
public class Niger implements Person<String>{
 void eat(String food);
} 
public class Niger<E> implements Person<E>{
 void eat(E food);
}
//泛型擦除模式 
-在代码运行阶段,类型被擦除
public class Person<T>{
 void play(T operation){}
}
Person<String> perS = new Person<String>();
Person<Integer> perI = new Person<Integer>();
perI.getClass() === perS.getClass();
//泛型通配符 -泛型的继承关系与java原生不一致 
public class Person<T>{
 void play(Person<T> operation){}
}
Person<Number> perN = new Person<Number>();
Person<Integer> perI = new Person<Integer>();
erro:perN.operation(perI);
-重新绑定 ?为所有泛型类的父类,所有不受声明的限制 
public class Person<T>{
 void play(Person<?> operation){}
} 
Person<String> perS = new Person<String>();
Person<Integer> perI = new Person<Integer>();
success:perS.operation(perI);
//泛型的上下边界 
public class Person<T>{
 -传入必须是T或T的子类,用于查看
 void play(Person<? extends T> operation){}
 -传入必须是T或T的父类,用于写入 
 void play(Person<? super T> operation){} 
}
  • 枚举 系统变量有固定的取值选择,预先定义的常量类,封装存自己的静态常量类
//语法 
public enmu 类名{
 枚举项2; 枚举项1;
 枚举项属性声明;
 构造器; 
 geter取值器;
}
//规则
 -枚举项名 大写用下划线分割,相当于对象名 
-枚举项属性 可以初始化值,调构造方法 
-继承 默认Enum类 -封装 只含有私有属性 
-多态 允许实现接口 
public enum Code implements Val{ 
    REQUEST_FAIL_PARAMS(200,"请求参数错误!"),
    REQUEST_FAIL_METHON(201,"请求方式错误!"),
    REQUEST_FAIL_URL(202,"请求地址错误!");
 private Integer status;
 private String message;
 piblic Code(){}
 public Integer getStatus(){
     return this.status;
  } 
 public String getMessage(){
   return this.message; 
 }
} 
//枚举类的比较 
Code.REQUEST_FAIL_PARAMS == Code.REQUEST_FAIL_PARAMS
 -因此可使用Switch匹配 
switch(ca){
 case Code.REQUEST_FAIL_PARAMS:
  throw new Exception();
  break; 
default: 
 break; 
}

(二)多线程基础

  • 基础知识

-任务:在一个时间做的一件事情。

-线程: 进程中的一个执行单元,负责程序的执行。一个进程至少包含一个线程。

-进程:内存中运行的应用程序,每个进程有独立的内存空间,一个应用程序可同时运行

多个进程,是系统运行的基本单位,

-并发:多件事情在同一时间段内发生。相对于一个cpu,交替运行。

-并行:多件事情在同一时刻在发生。相对于多cop,同时运行。

-同步:消息通讯机制,等待调用结果

-异步:消息通讯机制,不影响调用方

-线程调度:资源的分配问题。

-分时调度:轮流使用cpu,平均分配cpu时间。

-抢占式调度:取优先级高的,相同则随机。(java选择)

  • 线程的创建方式
//继承Thread类,实现抽象方法run()
 -匿名内部类
 -不适合资源的共享
 -不适合在继承 
new MyThread extends Thread{ 
@Override 
public void run(){} 
} 
-匿名对象
new Thread(new MyThread()).start();
MyThread thread = new MyThread();
-重新分配栈空间
thread.start();
//实现Runnable接口,实现run方法
//函数式接口
class MyThread implements Runnable{
 @Override public void run(){} 
} 
MyThread interface = new MyThread();
Thread thread = (Thread) interface;
thread.start();
 //常用方法
thread.setPriority();
 -抢占资源的可能性改变
 -Thread.MAX_PRIORITY
 -Thread.MIN_PRIOTITY
 -Thread.NORM_PRIORITY
thread.currentThread().getName(); thread.setName(); 
-当前线程睡眠多少毫秒 
Thread.sleep(); 
-可能性让步资源,放手后会在竞争 
Thread.yield(); 
-线程合并,打断调用线程的执行,完成后继续,等待个结果 
thread.join();
-设置为守护线程,调用线程结束则结束 
thread.setDasemon(true);
  • 线程的生命周期

-new 新建状态:创建对象后进入

-runnable 就绪状态:start() 运行后进入

-running 运行状态:获得资源后,CPU调度时进入

-block 阻塞状态:运行时,暂时放弃资源时进入 -等待阻塞:运行时,执行了wait()

-同步阻塞:获取同步锁失败,竞争失败时

-其他阻塞:调通了线程的sleep(),join()等方法,或者I/O处理中, 结束后进入就绪状态。 -dead 死亡状态:线程执行完,或异常退出进入

  • 线程的安全问题

-多个线程竞争资源时,同一资源在切换时,被其他线程抢占,非原子操作,导致数据不一致,导致读写操作冲突。

//同步代码块
synchronized(同步锁){
-相当于原子操作了
-锁可以为任意对象的实例
-多个线程使用一把锁
-保证唯一,且能拿到
-this
-new Object()
-MyThread.class
}
//同步方法
-修饰普通方法锁就是本类对象
public synchronized void operation(){}
//Lock
-互斥锁
Runnable run = new MyThread();
new Runnable(
    @Override
    public void run(){}
)
Thread thread1 = new Thread(run,"thread1");
-对数据加锁
private Lock l = new ReenternLock();
try{
    l.lock(resoure);
}finally{
    l.unlock(resoure);
}
//线程的协作
-有序的完成事务,需要通知
-等待唤醒机制,线程通信
-协调锁
-必须在同步块中,由锁作为中间者调用这个方法
Object lock = new Object();
-线程一
-线程二
-线程一
-线程一等待
synchronized(lock){
    -等待时,会释放锁,进入等待池
    lock.wait();
    -唤醒后重新竞争
    lock.wait(timeout)
    -自己唤醒,不在执行后面的代码
}
-线程二唤醒
synchronized(lock){
    lock.notify();
    -唤醒所有线程
    lock.notifyAll();
}
//线程的死锁
-当线程互相等待对方唤醒时,会进入死锁
-拿到对方需要的资源不释放
-线程一
synchronized(lock2){
    lock2.sleep();
    -不释放
    synchronized(lock1){        
    }
}
-线程二
synchronized(lock1){
    lock1.sleep();
    -不释放
    synchronized(lock2){
    }
}
  • 线程的线程池

-对线程的管理,需要时使用,重复利用。

-执行和销毁很消耗CPU。

-提高响应速度,提交创建了。

-Excutors执行线程池,为创建工具
-ExcutorsService为线程池接口
-固定数量
Excutors.newFixedThreadPool(size);
-可伸缩
Excutors.newCacheThreadPool();
-单线程(有序)
Excutors.newSingleThreadPool();
-定时线程池
Excutors.newScheduledThreadPool(size);
pool.schedule(Runnable,delay,TimeUnit.SECONDS);
pool.isTerminated() //是否完成

MyRunnab thread = (MyRunnable) new Runnable();
//提交Runnable接口对象
pool.sumbit(thread);
pool.sumbit(thread);
pool.sumbit(thread);
//关闭线程池
pool.shutdowm();
  • 线程的有返回值创建
//Callable
class HandleCallable implements Callable<返回值类型>{
    @OverRide
    public 返回值类型 call(){}
}
//借助线程池
ExcutorService pool = Excutors.newFixredThreadPool();
HandleCallable t1 =  new HandleCallable();
HandleCallable t1 =  new HandleCallable();
Future<Integer> result = pool.sumbit();
pool.shutshowm();
  • 线程安全的集合

-CopyOnWriteArryList<> ----ArrayList 写入锁,加锁,通过拷贝,还给原来数组

-CopyOnWriteArrySet<> --- Set

-CopycurrentHashMap<>---对默认容量Segement,分段加锁

(三)注解与反射

  • 注解(Annotation) JDK5.0引入,可被编译器读取,配合反射实现功能
//格式
@注释名(参数列表)
//常见注解
@Override    重写
@Deprecated    废弃的方法
@SupressWarmings 镇压警告
//元注解
@Target    用于描述注解的使用范围和位置
@Rentention    注解信息的保存范围(SOURCE>CLASS>RUNTIME)
@Document    说明注解保存在javadoc文档中,转字节码还能生效
@Inherited    说明子类可以继承该注解
//自定义注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Renention(value = RenrntionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation{
-类型 类型名();
    String name();
    String sex() default "男";
-一个参数命名为value()时可以省略
}
@MyAnnation(name = "小付")
void method();
  • 反射 动态性改变和运行
//动态语言
-在运行时,可以改变自身结构
-java准动态性,会损失效率
Reflection
-正常方式
引入需要的包类名称->通过new实例化->取得实例对象
-反射方式
实例化对象->getClass()方法->得到完整的"包类"名称

//加载完后,方法区会产生一个Class对象,可以得到完整的结构信息
-可以实现动态的创建对象和编译
-本质是一种解释操作,会影响效率
-获取Class对象
-一个类类型和维度只含有一个Class对象
Person person = new Person();
Class c1 = person.getClass();
Class<Person> c2 = Person.class;
Class c3 = Class.forName("com.fzy.reflection.user");
Class c4 = Integer.TYPE;
Class c5 = c1.getSuperclass();

//一些类的class()对象
Class c1 = Object.class;
Class c2 = Comparable.class;
Class c3 = String[].class;
Class c4 = int[][].class;
Class c5 = ElementType.class;
Class c6 = Integer.class;
Class c7 = void.class;
Class c8 = Override.class;
Class c9 = Class.class;
-获取类信息
Class c = Class.forName("com.fzy.reflection.User");
-获得包名加类名
c.getName();
-获得类名
c.getSimpleName();
-获得属性
Filed[] fields = c.getField();
-获得指定属性的值,public
Field name = c.getField("属性名");
-获得指定属性的值,全部
Field name = c.getDeclaradField();
-获得方法,本类及父类public
Method[] methods = c.getMethods("属性名");
-获得方法,本类
Method[] methods = c.getDeclaradMethod();
-获得指定方法
Method method = c.getMethon("setName");
-获得指定构造器 public
Constuctor[] constuctors = c.getCostructors();
-获得构造器 全部
Constuctor[] constuctors = c.getDeclaredCostructors();
-获取指定,参数列表
Constuctor constuctor = c.getCostructor();
  • 底层原理

-加载 将class文件字节码内容加载到内存中,将静态数据转化到方法区

-连接 将java二进制代码合并到JVM的过程

-验证 确保加载类符合规范,没有安全问题

-准备 为static信息在方法区分配空间并且初始化默认值

-解析 虚拟机常量池符号替换为地址的过程

-初始化 执行类构造i器,初始化父类,线程加锁

.JAVA文件(源程序) -编译器 .class字节码文件 -类装载器 类缓存 -字节码校验器 -解释器 操作系统平台

-类加载器

ClassLoader systemClass = ClassLoader.getSystemClassLoader();
ClassLoader parnet = systemClass.getParent();
Class.forName().getClassLoader()
//BootStrap Classloaer -- 加载rt.jar核心包    -c++编写
//Extension Classloader --ext下包加载器
//System.Classloader    --App,项目包加载器
//自定义加载器
-获取系统加载器加载路径
System.getProperties("java.class.path")
//双亲委派机制
当已有加载文件加载器,则自定义同名类无法加载
  • 实践使用
 Class clazz = Class.forName();
 -默认调用无参构造器
 String str = clazz.newInstance();
 -有参实例化
 Consturctor cs = clazz.getyDelareConstuctor(param..);
 String str = cs.newInstance(param...);
 -通过反射调用方法
 Method setName = c.getDeclaradMethod(setName,String.class);
 setName.invoke(str,"name");
 -通过反射调用属性
 Field name = class.getDeclaraField("name")
 name.set(str,"name");
 //关闭权限检查 private 提高效率
 name.setAccessible(true);
 str.getName()
 //当前系统时间戳
 System.currentTimeMillis()

-泛型的反射

-ParameterizedType    参数化类型 List<String>
Student.class.getMehod()
//获得泛型参数类型
method.getGenericParamterTypes()
(ParameterizedType) paramTypes
//获得泛型返回性类型
method.getGenericReturnTypes()
(ParameterizedType) paramTypes

-注解的反射

ORM --对象关系映射
//注解
@Target(ElementType.TYPE)
@Retention(RentenionPolicy.RUNTIME)
@interface TraslateClass{
    String value();
}
@Target(ElementType.FIELD)
@Retention(RentenionPolicy.RUNTIME)
@interface TraslateField{
    String column();
    String type();
    int length();
}
@TraslateClass("db_student")
class Student{
    @TraslateField(
    column = "stu_name"
    ,type = "varchar"
    ,length = 10)
    private String name;
    @TraslateField(
    column = "stu_id"
    ,type = "int"
    ,length = 10)
    private Integer id;
}
//类注解值
Class c = Student.class;
TraslateClass traslateClass = (TraslateClass)c.getAnnotation(TraslateClass.class);
String value = traslateClass.value();
//字段注解值
Field f = c.getDeclaredField("name");
TraslateField traslateField = (TraslateField) f.getAnnotation(TraslateField.class);
String column = annotation.column();

(四)函数式编程

  • 定义:有且只有一个抽象方法的接口,使用于lambad.
  • 语法糖:指简化代码而不改变功能的代码。例如foreach()利用的迭代器
@FunctionalInterface
public interface Lambad{
    /public abstract/ void method();
    //@FunctionalInterface用于接口检测是否为函数式接口,导致编译成功或失败
}
  • 函数式接口的使用
//作为参数使用
static void show(Lambda interface){}
show(new LambdaImpl())
show(new Lambda(){
    //匿名内部类方式简化
    //拥有class文件
    @Override
    void method();
})
show(()->{
    //lambda表达式简化
    //代表重写其唯一的抽象方法
});
show(()-> sout;);
//优化参数浪费    会在使用时调用执行
@FunctionalInterface
public interface Message{
    String builder();
}
void show(int level,String message){
    if(level == 1){
        sout;    
    }
}
show(2,()->{
    return msg1+msg2;
})
  • 函数式编程
//接口作为参数
class MyRunnable{
    static void start(Runnable run){
        new Thread(run),start();    
    }
}
start(new Runnable(){
    @Override
    void run{}
})
start.(()->{
    //重写方法run()
})
//作为返回值替代函数式接口     按字符串长度排序
static Copmarator<String> getComparator(){
    //匿名内部类方式
    return new Comparator<String>(){
        @Override
        int compare(String str1,String str2){
            return str1.length()-str2.length();        
        }    
    }
    //lambad简化方式
    return (String str1,String str2)->{
        return str1.length()-str2.length();    
    }
    //再次简化    代表就是接口的抽象方法的实现
    return (str1,str2)-> str1.length()-str2.length();    
}
String[] arr = {"aa","a"};
Arrays.sort(arr,getComparator());
  • 常用的函数式接口
-Supplier接口    get()获取一个指定泛型对象 生产型接口
static String getString(Suppiler<String> sup){
    return sup.get();//返回的是String对象
}
getString(()->{
    //get方法体
    return "初始化";
})
getString(()->"初始化");
//自己尝试
static User builderUser(Suppiler<User> sup){
    return sup.get();//返回的是String对象
}
 builderUser(()->User
                .builder()
                .name("软件工程师")
                .age(22)
                .build());
                
//Consumer 消费型接口,accpect()使用指定泛型的数据
static void using(String thing,Consumer<String> con){
    con.accept(name);//将数据传入重写方法使用
}
using("软件工程师",()->{
    new StringBuilder(name).reverse().toString();
})
-原生方法 andThen() 需要两个Conmuser接口方法组合后使用
Consumwer<> con1;
Consumwer<> con2;
String name = "";
con1.andThen(con2);//一用完二用
//可以形成一条链路
static void using(String thing,Consumer<String> con1,Consumer<String> con2){
    con1.accept(name);
    con2.accept(name);
    String name = thing;
    === con1.andThen(con2).accpet(name);//一用完二用
}
using("软件工程师",
(name)->{
    new StringBuilder(name).reverse().toString();
},
(name)->{
    new StringBuilder(name).reverse().toString();
})

// Predicate 对数据进行判断返回布尔 test()
static boolean check(String s, Predicate<String> pre){
    //test()的lambda是判断逻辑
    return pre.test();
}
多条件拼接 and(),or()
pre.or(pre2)

//Function    数据类型转换apply()
private static Record paras(Order order,Function<Order,Record> pas){
    return pas.apply(order);
    //Function<R,T>第二个参数为返回值类型
}
-andThem 连续转换

(五)IO流

  • 文件
//计算机文件
转义字符--\ 斜杠
linux系统下
相对路径:./(当前路径) ../(上级路径)
绝对路径:硬盘路径 /usr/soft/
windows系统下
绝对路径:C:\\soft\\
//对File的操作映射实例    实现Comparablie和Serializable接口
Output:将内存持久化(硬盘,数据库)设备为输出
cenput:将持久设备中读取到内存

-创建 
new File(String name); //文件夹
new File(String path,String name);
new File(String parent,String child);
dir,createNewFile()
-操作
file.getPath()
file.getName();
file.getAbsolutePath();
file.getParent();
file.isAbsolute();
file.isDirectory();
file.isFile();
file.exists();
-文件删除
file.delete();
dir.delete() //无子文件
  • 输入输出流
-字符流:处理字符相关,文本数据,以一字节(8位)为单位,
-字节流:处理字节相关,如声音,图像。能处理所有文件。
字符:
-Reader(字符读取流)
    -BufferedReader(缓冲读取流)
    -InputStreamReader(字符读取流)
        -FileReader(文件读取流)
    -StringReader (字符数组读取流)
-Writer(字符写入流)
    -BufferedWriter(缓冲写入流)
    -OutputStreamWriter(字符写入流)
        -FileWriter(文件写入流)
    -StringWriter(字符数组写入流)
字节:
-InputStream (字节输入流)
    -FileputStream(文件输入流)
        -BuffereInputStream(缓冲输入流)
    -ObjectInputStream(对象输入流)
    -ByteArrayInputStrean(字节数组输入流)
-OutputStream(字节输出流)
    -FileOutputStream(文件输出流)
        -BuferedOutputStream(缓冲输出流)
    -ByteArrrayOutputStream(字节数组输出流)
    -ObjectOutStream(对象输出流)
  • 常用字节流详解

-InputStream 字节输入流

//读取单个字节,返回0-255范围内的int字节值,无则返回-1
int read();
//从管道中读取一定数量的字节,并缓冲到数组buf中,返回读取数量
int read(byte[] buf);
//从管道中,跳过并丢弃n个字节的数据
long skip(long n);
//返回管道中字节数
int available();
//关闭流并释放系统资源(线程的阻塞)
void close();

-FileInputStream 文件字节输入流

//创建相关流对象
File file = new File(path,name);
InputStream in = new FileInputStream(file);
//操作
-对于汉字等UNICODE读取不正常
int point = in.read();
char data = (char)int;
long skippoint = in.skip(2);
byte[] data = new byte[2];
//一次性读完
byte[] dataAll = new byte[in.available()];
//读取缓冲区长度的数据
while(int dataLength = in,read(data)){
    //GBK中英文占两个字节
    //UTF-8中文占三个,英文占一个
    sout(
    new String(data,0,dataLength,"UTF-8")
    );
}

-OutputStream 字节输出流

//写入一个字节到缓冲管道
void write(int data);
//写入一个字节数组的数据到缓冲管道
void write(byte[] buf);
//将缓冲管道中数据清空,同时写入硬盘
void flush();
//释放资源
void close();

-FileOutputStream 文件字节输出流

//输出文件地址
new FielOutputStream(String name);
//输出文件对象
new FileOutputStream(File file);
//是否可以追加内容
new FileOutputStream(File file,boolean append);
//操作
OutputStream out = new FileOutputStream(dir+name);
  • 缓冲字符输入输出流
-缓冲区:预留数据,临时存储,像漏斗
-避免大量的直接IO操作磁盘,磁盘读取慢
-采用中包装设计模式,预先读取,少了再读
-默认缓冲区大小8192(8kb)
-缓冲区满时,则会自动操作磁盘
//BuferedInputStream
//BuferedOutputStream
int read();
int read(byte[] buf,int off,int len)
int write();
int write(byte[] buf,int off,int len)
void flush()
void close()
  • 常用字符流

-Reader 字符写入流

//读取单个字符
int read();
//读取一定量的字符。进入缓冲数组中
int read(char[] chuf)
//创建 调用父类的FileInputStream的构造方法
-FileReader
new FileReader(String path);
while(isOverAndData = reader.read() == -1){
    (char)isOver;
}
char[] c = new char(1024);
int length = reader.read(c,0,len)
  • Writer 字符写入流
new FileWriter(String name,isappend)
//按照ascll码表转换
void write(int c);
//实现了
void flush()
int write();
int write(byte[] buf,int off,int len)
void flush()

(六)网络编程入门

-BIO,NIO,AIO

  • NIO JDK1.4替代IO的网络编程工具(同步非阻塞)

-阻塞IO 通常在同步I/O操作时,流打开会阻塞线程运行,就要多个线程,也叫传统IO(串行)

-非阻塞IO 采用Reactor的工作方式,延迟IO操作,等待系统通知,也称NIO (并行)

-核心组成

-Channels 双工通信,FileChannel,DoubleChannel

-Buffers 缓冲区

-Selectors 单线程处理多个Channel的操作,多路复用

  • Channel
-封装了对数据源的操作
-依赖于缓冲区
-不同操作系统实现不同
-可以异步操作
-通道之间的数据传输transferform
-分散和聚集scatter(多个buffer写入)和gahter(多个buffer读取)
channel.read(ByteBuffer[])
channel.write(ByteBuffer[])
-FileChannel
interface Channel extends Closeable{
    boolean isOpen();
    void close();
}
  • -FileChannel
//读取    随机访问流
RandomAccessFile file = new RandomAccessFile(String path,rw--read/write)
FileChannel channel = file.getChannel();
//分配缓冲区
buf = ByteBuffer.allocate(1024);
int read = channel.read(buf);
while(read != -1){
    //因为刚从磁盘写入buf,得移动指针到第一位置(读写模式切换)
    buf.filp();
    //在从buf中调取,是否有剩余
    while(buf.hasRemaining){
         (char)buf.get();   
    }
    //清空后才能在读
    buf.clear();
    read = channel.read(buf);
}
channel.close();
===================
磁盘-通道-缓冲区-系统
===================
//写入
RandomAccessFile file = new RandomAccessFile(path,"rw");
FileChannel channel = file.getChannel();
ByteBuffere buf = ByteBuffer.allcate(1024);
String data;
buf.clear();
buf.put(data.getBytes());
buf.filp();
while(buffer.hasRemaining()){
    channel.write(buf);
}
channel.close();
===================
系统-缓冲区-管道-磁盘
===================
channel.position();//文件空洞
  • SocketChannel interface
-extends Seclecor 管理多个Socket连接
-本身不存数据,负责监听
-Socket和Socket通道(可复用)
-阻塞和非阻塞可选择 isBlockingLock()
三种监听器
-DatagramChannel UDP
...见专门笔记
-SocketChannel TCP
...见专门笔记
-ServerSocketChannel 网络通信
使用
int port = 8080;
//自定义缓冲区
ByteBuffer buf = ByteBuffer.wrap("".getBytes())
ServerSocketChannel ssc = ServerSocketChannel.open();
//绑定监听端口
ssc.socket().bind(new InetSocketAddress(port));
//设置非阻塞模式
ssc.configureBlocking(false);
//监听端口连接
while(true){
    //获取连接的socket
   SocketChannel sc = ssc.accpet()
   if(sc != null){
       //指向0
       buf.rewind();
       //通过管道写入磁盘文件
       sc.write(buf);   
       sc.close();
   }
}
  • Buffer
-数据传输的中介,一个内存非磁盘
写入buffer
调用filp()模式切换
读取buffer
clear()全部compact()读过的
-capacity 固定容量
-position 绝对位置
-limit 每次读写的长度
缓存区分片 slice 子缓冲区 数据共享
只读缓存区
直接缓冲区
内存映射文件 IO

  • Selector
多路复用器
-检查多个通道的状态(网络连接)
-单线程处理
-复用继承的SelectableChannel
-通道注册Channel.register(Selector sel,int opts)
SelectionKey.OP_READ
SelectionKey.OP_WRITE
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCPECT
监听事件类型,将要发生的就绪状态
//创建
Seclector.open();
//注册(不能是FileChannel)
ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc,bind(new InetSocketAddress(port))
ssc.register(selector,SelectionKey.OP_ACCPECT);
//轮询查询就绪的通道操作 就绪状态集合
Set<SelectionKey> sk-= selector.selectionKeys();
Iterator<SelectionKey> it = sk.iterator();
while(it.hasNect(){
    SelectionKey k = it.next();
    //就绪状态操作
    if(key.isAccpet()){
            
    }
    it.remove()
})
  • 线程通讯 Pipe

//获取管道
Pipe p = Pipe.open();
//获取sink通道
Pipe.SinkChannel sink  = pipe.sink();
//写入数据
ByteBuffer data = ByteBuffer.allocate(1024);
data.put("".getBytes())
data.filp();
sink.write(data);
//获取source通道
PipeSourceChannel sc = pipe.source();
//创建缓冲区,读取数据
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.flip();
int length = sc.read(buf);
new String(buf.array(),0,length);
//关闭通道
sc.close();
==================================================
线程A缓冲区->sink通道->pipe->source通道->线程B缓冲区
==================================================
  • 文件锁 FileLock
排他锁:又叫独占锁,阻止其他进程读锁
共享锁:其他进程只能读,不能写
new FileChannel()
FileLock lock = channel.lock();
lock.release()
//阻塞式
lock(long position,long size,booleam share);
//非阻塞
tryLock();
isShared();
AsychronousFileChannel
//创建异步文件通道
Parh path  = Path.get(String path);
AsychronousFileChannel asy = AsychronousFileChannel.open()
//创建缓冲区
ButeBuffer.allocation(1024)
//调用read
Future<Integer> f = asy.read(buf)
//是否完成
while(f.isdone()){
    读取
    buf.filp();
    byte[] data = new byte[buf.limit]
    buf.get(data)
    while(buf.remaining()>0){
        buffer.get()
    }
    buf.clear;
}

(七)Optional类

//创建optional    
-为空指传递会抛出异常
Oprional<Student> opt = Optional.of(stu1);
-对象可能为空可能不为空
Optional<Student> opt = Optional.ofNullable(stu2);
//获取包装对象
opt.isPresent();
opt.get();
//兜底方法 没有则返回默认对象
stu4 = Optional.ofNullable(stu3)
.orElse(defaultStu);
OR     返回某个属性
stu = Optional.ofNullable(stu4)
.map(templeStu->templeStu.getName())
orElse("xiaoming")

(八)集合框架进阶

  • stream 串行的集合操作处理
数据元素集合-->生成流-->中间操作-->最后操作
//生成
List list =  Arrays.asList("","";)
list.stream()
//遍历操作
.map(obj -> {
    obj处理
})
//收集
.collect(类型);
  • filter
list.stream()
.filter(obj -> {
    返回布尔(过滤条件)
})
.collect(Collectors.toList);
  • map
list.stream()
.map(obj -> {
    UserDTO给前端
})
.collect(Collectors.toList);
  • limit
list.stream()
.map(obj -> {
    UserDTO给前端
})
限制数量
.limit()
.collect(Collectors.toList);
  • sorted
.collect(Collectors.toList);
sorted
list.stream()
//默认升序
.sorted(
    Comparator.comparing(Student::getAge())
)
/.reversed()
.collect(Collectors.toList);
  • allMatch/anyMatch
-一个元素符合
boolean = list.stream()
.allMatch(obj -> {
    条件
})
-符合全部
boolean = list.stream()
.anyMatch(obj -> {
    条件
})
  • max/min
list.stream()
.max( 
    Comparator.comparing(Student::getAge())
       返回布尔(过滤条件)
)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值