Map集合和Collection集合的区别
存储类型
Collection<E>,只能存储一种引用类型属于单例集合
Map<K,V>,可以存储多种类型的引用类型属于双列集合
关系区别
Collection和Map没有直接关系,间接关系
Collection具体的子接口Set--->HashSet/Treeset 直接的去依赖于Map接口的HashMap和TreeMap
Map集合功能:
V put(K key, V value):是给map集合中添加元素使用的方法,如果返回值是null,则键不重复,如果返回值,那么这个值是这个键之前存储的值。将这个值返回,然后将新输入的值进行存储。
void clear():清空Map集合所有的键值对。
V remove(Object key):删除Map集合的指定键,然后返回删除键对应的值。
boolean containsKey(Object key):是否包含指定的键
boolean contains Value(Objecy value):是否包含指定的值
boolean isEmpty():判断Map集合是否为空。
Map集合遍历的方式:
Set<K> keySet():获取Map集合的所有的键的集合。
V get(Object):通过键获取值。
第二种:
Set<Map.Entry<K,V>> entrySet():获取所有键值对对象
getKey()获取键,getValue()获取值
HashMap:
底层通过哈希表实现,put方法依赖hashCode和equals方法。
Map针对键有效,要针对键的类型自定类型,当前类必须重写equals和hashCode(),保证键唯一
TreeMap<K,V> 存储键值对元素,保证键唯一的同时,还有排序功能。
public TreeMap():自然排序,当前键的类型必须实现Compareable接口
public TreeMap(Comparator<? super K> comparator):使用比较器排序 (推荐) 直接可以使用接口匿名内部类
Collections:针对集合后操作工具类:
public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key):
二分搜索在List中查询元素 (不管集合还是Arrays---->binaraySearch方法,(集合或者数组必须有序))
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) :获取Colection中的最大值
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) :获取Colection中的最小值
public static <T extends Comparable<? super T>> void sort(List<T> list):针对List集合进行自然排序
public static <T> void sort(List<T> list,Comparator<? super T> c):针对List集合比较器排序
public static void shuffle(List<?> list):针对List集合随机置换
public static <T> List<T> synchronizedList(List<T> list):将线程不安全ArrayList,变成线程安全的列表
线程:
线程是依赖于进程的,没有进程就没有线程
jvm中至少存在两条线程,分别是用户线程和垃圾回收线程
public final String getName()获取线程的名称
public final void setName(String name):设置线程名称
创建线程的方式:
1.自定义一个类,继承Thread类
2.重写Thread类中的run方法
3.在main方法中,创建当前类的对象。
4.启动线程。
创建线程的方式2:
1.自定义一个类,实现Runnable接口
2.重写run方法
3.在main方法中,创建当前类的对象
4.创建Thread对象,将实现类的对象作为参数传递,启动线程
实现Runnable要好于继承Thread,原因: 实现的方式,解决单继承的局限性。 ②实现的方式针对于共享数据的情况,操作起来更方便 ,实现的方式可以做到代码和数据的分离。
还可以通过线程池、实现Callable接口来实现。
线程的状态:
NEW:新建状态
RUNNABLE:运行状态
BLOCKED:线程阻塞状态
WAITTING:一直进行等待
TIMED_WAITTING:超时等待,超过给定时间之后会自动唤醒。
TERMINATED:线程死亡。
throws和throw的差别:
throws抛出:使用在方法声明上,后面跟的是异常类名,可以跟多个,使用逗号隔开,表示可能会出现问题,throws抛出个调用者。
throw实在方法体中进行使用,创建对应异常类的对象,只可以跟一个,使用时配合try catch进行使用,代表这部分会出现问题,具有肯定性的含义,throw对异常的处理是交给方法逻辑体进行判断。
静态代理:
静态代理需要本类和代理类实现同一个接口,静态代理是对原功能的增强和扩展。
弊端:代理角色对业务功能增强的时候,和"系统监控的代码"不能有效分离!
异常:异常的父类是Throwable
异常分为Error(严重问题)和Exception
严重问题可能存在内存溢出,这种情况出现之后需要借助加内存条,借助硬件来解决问题。
Exception分为编译时期异常和运行时期异常。
编译时期异常会导致无法成功编译
运行时期异常导致原因是因为设计逻辑不够严谨出现的问题。
子类继承父类时。如果子类重写父类的犯法,父类的方法没有throws抛出异常,如果子类的方法中出现异常,那么只能自己通过try catch进行处理。
子类继承父类,子类重写父类的方法时,如果父类方法存在抛出异常的情况,那么子类的 那么子类的该方法最起码要根父类的方法异常保存一致或者大于父类的异常。
public final void setPriority(int newPriority):设置优先级
public final int getPriority():获取优先级
Thread提供三个自定义常量:
public static final int MAX_PRIORITY 10 最大优先级
public static final int MIN_PRIORITY 1 最小优先级
public static final int NORM_PRIORITY 5 默认优先级
创建线程,没有设置优先级,线程的默认优先级就是5(抢占CPU执行权的概率一样大)
join和yieId的区别
join()
当前线程终止(线程调用join()方法会让当前线程执行完毕)
yield()
线程礼让,暂停正在执行的线程,并执行其他线程!
因为线程之间存在竞争性,执行随机,会导致出现线程安全问题,因此提供了同步机制
synchronized(锁对象){
逻辑语句
}
其中的锁对象,可以时任意的Java类对象,但是每个线程都需要使用同一把锁。
同步方法:
将synchronized提到方法声明上,那么这个方法就成为了同步方法
默认的锁对象是this
如果方法是静态方法锁对象则是类名.class
线程死锁:多个线程同时使用同一个锁的情况,比如线程A与线程B都需要用到锁A和锁B,两个线程启动后,有概率会出现线程A占用了一个锁。线程B也占用了一个锁,此时两个线程都在等待对方释放锁,此时进入线程死锁。
多个线程加入同步锁之后,线程互相之间持有对方的锁,每一个线程必须让对方释放锁之后,才能去使用同步中的内容,导致线程之间出现互相等待!(访问的资源不是同一个资源)
可以使用生产者和消费者模式思想,来解决线程死锁问题。
wait()+notify():这个两个必须在synchronzied使用(同步代码块或者同步方法) 使用"信号灯法"来解决死锁问题
wait()和sleep()的区别
wait这个方法在使用时会释放掉锁,但是sleep不会释放锁。
sleep需要传入时间,而wait方法不可以单独使用,必须在同步代码块/方法中进行使用,否则会出现非法参数异常。
wait来自Object类中,sleep来自Thread类
sleep会让线程进入TIMED_WAITTING状态,超过时间将会自动唤醒,wait会进入WAITTING状态。
如果没有锁对象调用notify()或则notifyAll(),线程状态就进入到WAITTING(死死等待),不会自动唤醒
void lock() 获取锁
void unlock()释放锁
线程池:线程池提高了线程的使用率
可以大大减少资源开销
可以通过七大参数对其进行调优
存在弊端:维护成本大。
public static ExecutorService newFixedThreadPool(int nThreads):创建固定的可重用的线程数的线程池
ExecutorService子实现类=--- TreadPoolExecutor完成线程池初始化!
如果涉及到定期让线程进行活动(public static ScheduledExecutorService newScheduledThreadPool)
线程池七大参数:
corePoolSize:核心线程数:是指线程池中长期存活的线程数.
maximumPoolSize:最大线程数:线程池允许创建的最大线程数量,当线程池的任务队列满了之后,可以创建的最大线程数
keepAliveTime:空闲线程存活时间,当线程池中没有任务时,会销毁一些线程,销毁的线程数=maximumPoolSize(最大线程数)- corePoolSize(核心线程数)
TimeUnit:时间单位:空闲线程存活时间的描述单位
BlockingQueue:阻塞队列:线程池存放任务的队列,用来存储线程池的所有待执行任务。
可以设置以下几个值:
ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
SynchronousQueue:一个不存储元素的阻塞队列,即直接提交给线程不保持它们。 PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
DelayQueue:一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素 LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
ThreadFactory:线程工厂:线程池创建线程时调用的工厂方法,通过此方法可以设置线程的优先级、线程命名规则以及线程类型(用户线 程还是守护线程)等。
RejectedExecutionHandler:拒绝策略:当线程池的任务超出线程池队列可以存储的最大值之后,执行的策略.
默认的拒绝策略有以下 4 种:
AbortPolicy:拒绝并抛出异常。
CallerRunsPolicy:使用当前调用的线程来执行此任务。
DiscardOldestPolicy:抛弃队列头部(最旧)的一个任务,并执行当前任务。
DiscardPolicy:忽略并抛弃当前任务。 线程池的默认策略是 AbortPolicy 拒绝并抛出异常
线程池:
可以通过Executors工厂类(当前类构造方法私有化,对外提供静态方法--->简单工厂模式)提供一些创建线程池的功能
可以创建固定的可重用的线程数的线程池
public static ExecutorService newFixedThreadPool(int nThreads):参数为当前的线程数量上面的返回值ExecutorService接口
提供一些方法
Future<?> submit(Runnable task)提交异步任务
<T> Future<T> submit(Callable<T> task):提交异步任务
void shutdown():关闭线程池
创建线程池:固定的可重用的线程数的线程池
提交异步任务<T> Future<T> submit(Callable<T> task):提交异步任务
返回值:Future接口:代表异步计算的结果
V get():获取计算的结果
单列设计模式:
饿汉式(不存在安全问题的单列设计模式)
当前类时具体类
类一加载就创建当前类实例
构造私有化,对外隐藏,不可以实例化
对外提供静态方法,返回值是当前类本身
Java中的类Runtime类:标准的单例(饿汉式),和计算机的运行环境有关系
懒汉式(可能存在安全问题的一种单例模式)
当前类是个具体类
当前类构造方法私有化
当前类的成员位置:声明当前类的一个静态变量
对外提供静态方法,返回值是当前类本身:需要判断当前变量是否为null
开发业务中存在懒加载(按需加载)
IO流:
IO流按照方向分可以分为输入流和输出流
按照类型分可以分为字符型和字节型
java.io.File:表示文件或者文件一种抽象路径方式
构造方法:
File(File parent, String child)从父抽象路径名和子路径名字符串创建新的 File实例。
File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
File(String parent, String child) 父路径名字符串和子路径名字符串创建新的 File实例
使用第二个就可以。
File的基本功能以及特有功能:
public boolean createNewFile()throws IOException:创建文件。
public boolean mkdir():创建文件夹
public boolean mkdirs()创建文件夹,如果父目录不存在,会自动创建
public boolean delete()删除文件夹或者文件路径,如果是删除文件夹,必须要这个文件夹是空文件夹。
public boolean exists():判断次路径名表示的文件或者目录是否存在
public boolean isDirectory():此抽象路径名表示的文件是否是目录
public boolean isFile():是否是文件
public boolean isHidden()是否隐藏
特有功能:高级功能
public String[] list():获取指定抽象路径名表示的文件或者目录的名称(返回字符串数组)
public File[] listFiles():获取指定路径名表示的文件或者目录的File数组
FilenameFilter:文件名称过滤器
public boolean accept(File dir,String name)
public File[] listFiles(FilenameFilter filter)
public String[] list(FilenameFilter filter)
字节输出流
字节输出流:
OutputStream---抽象类--不能new,具体的子类:针对文件操作:FileOutputStream
操作步骤:
创建字节输出流对象
写数据
释放资源
字节输出流可以使用FileOutputStream实现文件的字节数追加
public FileOutputStream(String name,
boolean append)
throws FileNotFoundException
第二个参数是true:自动追加内容
IO流写数据,实现换行效果 widows系统 "\r\n"
如果是图片视频这些需要使用字节输出流进行传递,如果是文本文件,可以使用字符输出流来进行传递。
InputStream:字节输入流--->抽象类--->具体的子类FileInputStream:文件字节输入流
创建文件字节输入流对象FileInputStream(String name) :读取指定的文件 name:文件地址
读数据
继承它父类的方法:public abstract int read()throws IOException:一次读取一个字节
public int read(byte[] b) throws IOException:一次读取一个字节数组。
递归:
方法本身方法调用的一种现象:
定义一个方法
有规律
有出口条件
字节缓冲流:
Java之IO流提供了字节缓冲流:让读取的速度更快一些,提供对应的类
内部提供缓冲区字节数组长度:8192长度
文件的读写复制还的依赖于基本字节流(InputStream/OutputStream)
BufferedInputStream(InputStream in):字节缓冲输入流
BufferedOutputStream(OutputStream out):字节缓冲输出流
字符转换流:不能直接操作文件地址,借助于底层流(字节流),字符转换流提供它的子类 "转换流的便捷类"
InputStreamReader读源文件 ----->FileReader(String pathName)
OutputStreamWriter写目标文件---->FileWriter(String pathName)、
字符输入流---->Reader(抽象类)--->
具体的子类:字符转换输入流InputStreamReader --- 将字节输入流---->转换--->字符输入流
public InputStreamReader(InputStream in):使用平台默认字符集进行解码---读取数据
public InputStreamReader(InputStream in,String charsetName) 使用指定字符集解码---读取数据
读数据:
int read() :一次读取一个字符 --->返回结果:实际的字符数
int read(char[] cbuf) :一次读取一个字符数组
int read(char[] cbuf,int off, int len):读取字符数组的一部分
字符输出流:Writer(抽象类)--->
具体的子类 OutputStreamWriter:字符转换输出流,"可以将字节输出流---转换---字符输出流"
构造方法:
public OutputStreamWriter(OutputStream out):使用平台默认字符集进行编码--输出数据
public OutputStreamWriter(OutputStream out,String charsetName): 使用指定的字符集进行编码---输出数据
写数据:
void write(char[] cbuf) :写入字符数组
void write(char[] cbuf,int off,int len ) :写入字符数组的一部分
void write(int c) :写一个字符
void write(String str) :字符串
void write(String str,int off,int len):写入字符串的一部分
BufferedReader:字符缓冲输入流---可以读取一行内容。
构造方法:
public BufferedReader(Reader in):提供默认缓冲区大小的字符缓冲输入流 (8192个长度)
这个流如果直接操作文件--->参数里面使用FileReader
public String readLine()throws IOException
特有功能:
public String readLine()throws IOException:一次读取一行
返回值是读取到这一行的内容,当流已经到达末尾,则返回null。
键盘录入
Scanner(InputStream in)可以变换成Scanner sc = new Scanner(System.in) ;
new BufferedReader(new InputStreamReader(System.in))
InputStreamReader(InputStream in)可以变为InputStreamReader(System.in)
字符缓冲输出流:提供字符数组/字符/字符串的一种高效写入
BufferedWriter构造方法
public BufferedWriter(Writer out):提供默认缓冲区大小的字符缓冲输出流,默认缓冲区足够大 8192长度
写的功能:
write(字符/字符数组/字符串...)
特有功能:
不需要在使用"\r\n"换行符号, public void newLine()写入行的分隔符。
java.util.Properties:属性集合列表---extends Hashtabl<K,V>-->
本质是Map<K,V>集合
添加功能:put(K key,V value)
遍历方式:Set<K> keySet()
遍历键-->通过键获取值 V get(K key)
特有功能:
java.util.Properties:没有泛型,键和值都只能String---->
作用:用来读取配置文件xx .properties配置文件(src下面)
构造方法:
public Properties()
添加属性列表的键和值:
public Object setProperty(String key,String value)
特有的遍历方式:
public Set<String> stringPropertyNames():获取属性列表中的所有的键(属性名称)
public String getProperty(String key):通过属性列表中的属性名称获取对应的值
java.util.Properties可以保存到流中或从流中加载
将文件的内容加载到属性集合列表中:
public void load(InputStream inStream/Reader)
将属性列表中的内容保存到指定文件中
第二个参数:描述属性列表
public void store(OutputStream out/Writer,String comments)
,property文件需要保存在项目中的src文件夹下。
将src下面的文件内容读取到---属性列表中(键和值都是String)
java.util.Properties 属性集合(没有泛型)--->本质是Map<K,V>
Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串
void load(字符输入流/字节输入) ;将文件内容加载到属性列表中
void store(字符输出/字节输出流,String comments)
将属性列表中的内容保存到指定文件中,第二个参数:文件列表的标题内容
xxx.propertite:配置文件(属性列表文件)
网络编程:
网络三要素:
ip地址/端口号/协议
ip地址:
A/B/C三大类
A类--->前面第一个号段:网络号段 后面的号段:主机号段 (国家部门--机房)
B类--->前面两个号段:网络号段 后面号段:主机号段 (大学校园/公司内网等等)
C类---->属于私人地址 前面三个号段:网络号段 后面号段:主机号段
10.35.165.17 --- "点分十进法"
端口号:
范围 0~65535 这里面 0-1024(属于保留端口号)
如果端口已经被占用会出现Address already in use:BindException:地址被占用。
协议:
UDP/TCP协议区别 (底层网络协议)
UDP协议:
属于不可靠连接,不需要建立连接通道(不安全) ----以"数据报包"的方式进行数据传输的
不同步的,执行效率相对TCP协议,效率高
发送数据大小有限制的!
TCP协议:
属于可靠连接,需要建立连接通道! ----以 "流"的方式发送数据
同步的,执行效率低,安全性相对UDP协议(安全性能高)
发送数据大小无限制!
java.net.InetAddress:代表互联网ip地址对象!
获取ip地址对象---->获取ip地址字符串形式/获取主机名称
参数:要么传入主机名称/要么ip地址字符串
public static InetAddress getByName(String host)throws UnknownHostException :获取互联ip地址对象
InetAddress的成员方法
public String getHostAddress():获取ip地址字符串形式
public String getHostName():获取ip地址的主机名
Udp接收端
创建接收端的Socket对象
创建一个"数据报包"在里面自定义缓冲区:将发送端是数据存储到缓冲区中(字节数组,长度:1024或者1024的整数倍)
使用2)接收容器(缓冲区),接收发送端的数据
解析接收容器中的实际内容
展示数据即可
释放接收端的资源
使用UDP协议发送数据
创建发送端的socket对象
创建"数据报包"--里面包括:数据内容,ip地址,端口号
使用发送端的Socket对象发送"数据报包"
释放资源