赞
踩
Java高级在我看来就是认识,了解,掌握并熟练使用Java中各种常用的类。思维代码能力体现不强,主要需要我们记忆,在哪种情况下,需要怎样。
String是一个类,属于数据类型中的引用类型。
Java中一切使用""引起来的内容,都是这个类的实例,称为字符串对象。
在频繁更改字符串时,不要使用String类变量。
方法名 | 返回值 | 作用 |
---|---|---|
length() | int | 得到字符串的长度 |
toLowerCase() | String | 转换为小写 |
toUpperCase() | String | 转换为大写 |
trim() | String | 去除字符串首尾的所有空格 |
isEmpty() | boolean | 判断字符串是否为空白字符串"" |
getBytes() | byte[] | 将字符串转换为字节数组 |
toCharArray() | char[] | 将字符串转换为字符数组 |
equalsIgnoreCase(String str) | boolean | 忽略大小写判断两个字符串是否相同 |
equals(String str) | boolean | 判断两个字符串是否相同 |
charAt(int index) | char | 得到字符串指定索引上的字符 |
indexOf(String str) | int | 得到字符串中某个子字符串第一次出现的索引,如果不存在,返回-1 |
lastIndexOf(String str) | int | 得到字符串中某个子字符串最后一次出现的索引,如果不存在,返回-1 |
contains(字符序列) | boolean | 判断某个子字符串是否在原字符串中出现 |
concat(String str) | String | 将参数字符串拼接到原字符串末尾 |
startsWith(String str) | boolean | 判断是否以指定字符串开头 |
endsWith(String str) | boolean | 判断是否以指定字符串结尾 |
substring(int begin) | String | 从指定索引开始截取字符串至末尾 |
substring(int being,int end) | String | 截取[begin,end)区间内的字符串 |
split(String regex) | String[] | 按执行字符串或正则表达式切分原字符串。如果指定内容不再末尾,n个指定字符能得到n+1个子串;如果指定内容在末尾,n个指定字符能得到n个子串(不包含末尾的无效字符) |
replace(char oldChar,char newChar) | String | 将原字符串中的所有指定字符替换为新字符 |
String.valueOf(参数) | String | 将任意参数转换为字符串。通常用于原始类型转换为字符串。 |
String.formart(String 格式,Object… obj) | String | 根据指定格式转换参数。常用于将浮点数保留小数。如String.format(“%4.2f”,10.0/3)表示将计算的结果四舍五入保留2位小数转换为字符串;如果最终数据所占位置小于4,原样输出,大于4在最前补充空格。 |
用于表示可变字符串的一个类,是非线程安全的,建议在单线程环境下使用。
用于表示可变字符串的一个类,是线程安全的,建议在多线程环境下使用。
StringBuilder和StringBuffer中的方法都一致,只不过StringBuffer中的方法使用了synchoronized关键字修饰,表示是一个同步方法,在多线程环境下不会出现问题。
这里以StringBuilder为例
常用构造方法 | 作用 |
---|---|
StringBuilder() | 创建一个大小为16的字符串数组,表示一个空白字符。类似于String str=“”; |
StringBuilder(String str) | 创建一个str长度+16的字符数组后,将str添加到其中。类似于String str=“初始值”; |
常用方法 | 作用 |
---|---|
append(Object obj) | 将任意类型的参数添加到原可变字符串末尾 |
delete(int start,int end) | 删除[start,end)区间内的字符 |
deleteCharAt(int index) | 删除index索引上的字符 |
insert(int index,Object obj) | 在索引index上插入obj |
replace(int start,int end,String str) | 将[start,end)区间内的字符替换为str |
reverse() | 反转字符串 |
这个类中包含了一些系统相关的信息和一些方法。其中的属性和方法都是静态的。
该类不能创建对象,不是因为它是一个抽象类,而是因为它的构造方法是私有的。
常用属性和方法 | |
---|---|
System.out | 获取打印输出流PrintStream对象,用于控制台打印信息。 |
System.in | 获取输入流InputStream对象,用于获取输入的信息 |
System.err | 获取打印输出流PrintStream对象,用于控制台打印异常信息。 |
System.exit(int statues) | 终止虚拟机运行,参数0表示正常终止。 |
System.currentTimeMillis() | 获取从1970.1.1 0:0:0至今进过了多少毫秒。中国是UTC(+8),所以是从1970.1.1 8:0:0至今经过了多少毫秒。返回long类型。 |
System.arraycopy(原数组,原数组起始位置,目标数组,目标数组起始位置,原数组要复制的元素数量) | 将原数组中指定长度的元素复制到新数组中 |
Runtime类的对象,表示程序运行时对象(程序运行环境对象)。
包含了程序运行环境相关的信息。常用于获取运行环境信息(如虚拟机内存)或执行某个命令。
这个类不是一个抽象类,但不能创建对象,因为它的构造方法是私有的。
这个类提供了一个静态方法getRuntime(),通过这个方法,可以获取一个Runtime类的对象。
这是Java中的一种设计模式–单例模式(一个类只能有一个创建对象)。
public class Runtime {
//定义了私有的一个静态成员:当前类的对象
//由于静态成员只在类加载时执行一次,所以这里只会创建唯一一个当前类的对象
private static Runtime currentRuntime = new Runtime();
//定义了一个公共的静态方法,用于获取创建的唯一的当前类的对象
public static Runtime getRuntime() {
return currentRuntime;
}
//构造方法是私有的,不能在当前类之外创建对象
private Runtime() {}
}
用于表示日期时间的类,位于java.util包下
常用构造方法 | 说明 |
---|---|
Date() | 创建当前瞬间对应的日期对象 |
Date(long l) | 创建指定瞬间对应的日期对象 |
Date(int year,int month,int day) | 该构造方法已过时。创建指定年月日的日期对象(年是1900年起经过的年数,月用0-11表示1到12月) |
常用方法 | 作用 |
---|---|
getTime() | 得到对应Date对象表示的毫秒数 |
setTime(long l) | 设置Date对象的毫秒数 |
after(Date when) | 判断调用日期对象是否在when之后 |
before(Date when) | 判断调用日期对象是否在when之前 |
用于格式化日期的类。
常用构造方法 | 作用 |
---|---|
SimpleDateFormat(String pattern); | 创建一个指定日期模板的格式化日期对象 |
特殊字符 | 作用 |
---|---|
yyyy | 年份 |
MM | 月份 |
dd | 日期 |
HH | 小时 |
mm | 分钟 |
ss | 秒 |
E | 星期 |
以上两个字母都可以写成一个,如月份5 | M:5,MM:05 |
yyyy/MM/dd HH:mm:ss E | 2022/11/24 16:24:09 星期四 |
常用方法 | 返回值 | 作用 |
---|---|---|
format(Date date) | String | 将Date对象按日期模板转换为字符串 |
parse(String str) | Date | 将满足日期模板的字符串转换为Date对象 |
package com.hqyj.test3; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatTest { public static void main(String[] args) throws ParseException { //定义格式化日期类所需的时间模板 /* * yyyy 年 * MM 月份 * dd 日期 * HH 24小时制 * hh 12小时制 * mm 分钟 * ss 秒 * E 星期 * * 两个字母都可以写成一个,如月份MM和M * MM 5月实际为05 * M 5月实际为5 * */ String patten = "yyyy/MM/dd HH:mm:ss E";//年/月/日 时:分:秒 星期 //创建格式化日期类对象,参数为日期模板 SimpleDateFormat sdf = new SimpleDateFormat(patten); //创建当前日期对象 Date now = new Date(); //调用格式化日期对象的format(Date date),将Date对象转换为指定日期格式的字符串 String format = sdf.format(now); //输出 System.out.println(format); //parse(String str)将指定日期模板的字符串转换为Date对象 Date date = sdf.parse("2000/5/3 2:1:3 星期一"); System.out.println(date); } }
表示日历的类,包含了很多日历相关的信息。
是一个抽象类,无法创建对象。可以通过静态方法getInstance()获取该类的一个实例。
//获取Calendar类的对象
Calendar cal = Calendar.getInstance();
在Calendar类中,定义了很多被final和static修饰的常量,称为日历字段,实际一个数字,用于获取指定信息
值 | 作用 |
---|---|
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份(0-11表示1-12月) |
Calendar.DATE | 日期 |
Calendar.DAY_OF_WEEK | 星期(1-7表示周天到周六) |
Calendar.HOUR | 12进制小时 |
Calendar.HOUR_OF_DAY | 24进制小时 |
Calendar.MINUTE | 分钟 |
Calendar.SECOND | 秒 |
Calendar.DAY_OF_MONTH | 本月第几天 |
Calendar.DAY_OF_YEAR | 本年第几天 |
Calendar.WEEK_OF_MONTH | 本月第几周 |
Calendar.WEEK_OF_YEAR | 本年第几周 |
常用方法 | 作用 |
---|---|
get(int field) | 根据日历字段获取对应的值 |
getTime() | 获取对应的Date对象(Calendar对象转换为Date对象) |
getMaximum(int field) | 获取指定日历字段支持的最大值,如Calendar.DATE最大31 |
getActualMaximum(int field) | 获取指定日历字段在当前日期下的实际最大值,如11月,Calendar.DATE最大30 |
set(int field,int value) | 将指定的日历字段设置为指定值 |
set(int year,int month,int date) | 同时设置日历对象的年月日 |
setTime(Date date) | 将Date对象作为参数设置日历对象的信息 |
当程序没有按开发人员的意愿正常执行,中途出现错误导致程序中断,出现这种情况,就称为异常。学习异常就是认识异常的种类,如何处理异常和避免异常出现。
异常在程序中以对象的形式存在。当代码执行过程中出现异常,虚拟机会自动创建一个异常对象,如果没有对象该异常对象进行处理,就会导致程序中断,不再执行后续代码。
异常在程序中以对象的形式存在,就有相应的类。所有的异常类,组成了一个"异常家族"
所有集合的根接口为Collection接口和Map接口,位于java.util包中。图上的所有实现类,都是非线程安全的,在多线程的环境下使用以上任意集合,都会产生不确定的结果。
该接口有两个核心子接口:List和Set。
这两个接口都可以保存一组元素,List接口保存元素时,是有序可重复的;Set接口保存元素时,是无序不重复的。
常用方法 | 返回值 | 作用 |
---|---|---|
add(Object obj) | boolean | 将元素添加到集合中 |
size() | int | 获取集合中的元素数量 |
isEmpty() | boolean | 判断集合是否为空 |
clear() | void | 清空集合 |
contains(Object obj) | boolean | 判断集合中是否存在指定元素 |
remove(Object obj) | boolean | 移除集合中的指定元素 |
toArray() | Object[] | 将集合转换为数组 |
iterator() | Iterator | 获取集合的迭代器对象,用于遍历集合 |
ArrayList和LinkedList的区别
无序集合,元素不可以重复,允许保存null,没有索引。
Set接口中没有自己定义的方法,都是继承于Collection接口中的方法
Map称为映射,数据以键值对的形式保存。保存的是键与值的对应关系。
键称为Key,值称为Value,键不能重复,键允许出现一个null作为键,值无限制。
键和值都是引用类型。
常用方法 | 作用 |
---|---|
size() | 得到键值对的数量 |
clear() | 清空所有键值对 |
put(Object key,Object value) | 向集合中添加一组键值对 |
get(Object key) | 在集合中根据键得到对应的值 |
remove(Object key)/remove(Object key,Object key) | 根据键或键值对移除 |
keyset() | 获取键的集合 |
values() | 获取值的集合 |
containsKey(Object key) | 判断是否存在某个键 |
containsValue(Object value) | 判断是否存在某个值 |
entrySet() | 得到键值对的集合 |
常用方法 | 说明 |
---|---|
Collections.shuffle(List list) | 打乱List集合中元素的顺序 |
Collections.sort(List list) | 对List集合中的元素进行排序,元素必须实现Comparable接口 |
Collections.swap(List list,int a,int b) | 交换List集合中元素的索引 |
Collections.replaceAll(List list,Object oldObj,Object newObj) | 替换List集合中的旧元素为新元素 |
Collections.reverse(List list) | 将List集合中的元素反转 |
Collections.fill(List list , Object obj) | 使用指定元素填充List集合 |
Collections.rotate(List list , int n) | 将集合中最后n个元素放在最前 |
Collections.max(Collection col)/min(Collection col) | 得到集合中的最大/最小值,集合中的元素必须实现Comparable接口 |
Java中的File类,表示本地硬盘中的文件(文件和目录)的一个类。
通过这个类创建的对象,可以操作对应的文件。
常用构造方法 | 说明 |
---|---|
File(String pathName) | 根据文件的完整路径创建File对象 |
File(String parent,String child) | 根据文件的父目录路径和自身路径创建File对象 |
File(File parent,String child) | 根据文件的父目录对应的File对象和自身路径创建File对象 |
//如想要表示 “F:\221001\笔记\面向对象部分回顾.pdf” 这个文件
//File(String pathName)
File file1 = new File("F:\\221001\\笔记\\面向对象部分回顾.pdf");
//File(String parent,String child)
File file2 = new File("F:\\221001\\笔记", "面向对象部分回顾.pdf");
//File(File parent,String child)
File parent = new File("F:\\221001\\笔记");
File file3 = new File(parent, "面向对象部分回顾.pdf");
//file1、file2、file3都表示同一个文件
常用方法 | 说明 |
---|---|
exists() | 判断文件是否存在 |
isFile() | 判断是否为文件 |
isDirectory() | 判断是否为目录 |
getName() | 获取文件名 |
getPath() | 获取文件相对路径 |
getAbsolutePath() | 获取文件绝对路径 |
getParent() | 获取父目录的名称 |
getParentFile() | 获取父目录对象 |
lastModified() | 获取最后一次修改时间对应的毫秒数 |
length() | 获取文件所占字节 |
isHidden() | 判断文件是否隐藏 |
delete() | 删除文件或空目录 |
renameTo(File newFile) | 将原文件重命名且移动到指定目录 |
mkdir() | 创建目录 |
list() | 获取某个目录下的第一层子文件的名称的数组 |
listFiles() | 获取某个目录下的第一层子文件对象的数组 |
Java中将流定义为类,以对象的形式表现流。流有"四大家族",是所有流的父类。
FileInpuStream、ObjectInputStream
FileOutputStream、ObjectOutputStream
FileReader、BufferedReader、OutputStreamWriter
FileWriter、BufferedWriter、InputStreamReader
按方向分类
输入流:InputStream、Reader
输出流:OutputStream、Writer
按类型分
如要将硬盘中某个txt文件中的内容读取到程序中,使用Reader
如要将硬盘中的某个图片读取到程序中,使用InputStream
如要将程序中的文本写入到硬盘中为txt类型文件时,使用Writer
如要将程序中的数据写入到硬盘中为非文本文件时,使用OutputStream
文件类的综合练习:
package homework; import java.io.IOException; import java.io.*; import java.util.ArrayList; public class Main { static ArrayList<Person> list = new ArrayList<>(); public void fun(File source) { if (source.isDirectory()) { //将其展开 for (File child : source.listFiles()) { //因为子文件有可能是目录,继续调用本方法 fun(child); } } else { String s=source.getName(); String ID=s.substring(0,s.indexOf(" ")); String name=s.substring(s.indexOf(" ")+1,s.indexOf(".")); Person p=new Person(); p.setNo(ID); p.setName(name); list.add(p); } } public static void main(String[] args) throws IOException, ClassNotFoundException { Main main1=new Main(); File file = new File("C:\\Users\\hnn\\Desktop\\信息"); main1.fun(file); //创建OutStream的实现类,设置写入的文件路径 OutputStream os = new FileOutputStream("C:\\Users\\hnn\\Desktop\\123.txt"); //创建对象输出字节流,参数为OutStream类型 ObjectOutputStream oos = new ObjectOutputStream(os); //调用writeObject(Object obj)方法,将对象写入到硬盘中(序列化) oos.writeObject(list); oos.close(); //创建对象输入字节流,将上一步保存的文件进行反序列化 ObjectInputStream ois = new ObjectInputStream( new FileInputStream("C:\\Users\\hnn\\Desktop\\123.txt")); //使用readObject()方法,将写入的文件进行读取(反序列化) ArrayList<Person> pList = (ArrayList<Person>) ois.readObject(); for (Person person : pList) { System.out.println(person); } ois.close(); } }
表示IP对象的一个类
public static void main(String[] args) throws UnknownHostException { //获取本机的ip对象 // InetAddress ip = InetAddress.getLocalHost(); //获取域名 // System.out.println(ip.getHostName()); //获取真实ip地址 // System.out.println(ip.getHostAddress()); //getByName(域名) 得到域名对应的ip对象 //localhost域名表示本机,对应的ip地址为127.0.0.1 InetAddress ip = InetAddress.getByName("localhost"); //获取域名 System.out.println(ip.getHostName()); //获取ip地址 System.out.println(ip.getHostAddress()); }
都属于Socket(套接字)对象,表示网络中的某个端点
进程就是操作系统中执行的程序。一个程序就是一个执行的进程实体。
每个运行中的进程,都有属于它独立的内存空间,各个进程互不影响。
线程是一个进程中的执行单元,一个进程中可以有多个线程。
多个线程,可以访问同一个进程中的资源。
每个线程都有一个独立的栈空间,这些线程所在的栈空间位于同一个进程空间中。
如果一个进程中,同时在执行着多个线程,就称为多线程。
多线程可以提高程序执行效率。如多个窗口卖票,可以加快卖票的效率。
其实每个执行的Java程序,都是多线程执行,main方法称为主线程,还有gc线程(守护线程)在同时运行。
如有一个工厂,工厂中有很多车间,每个车间有很多流水线。
工厂就是内存,车间就是各个进程,每个流水线都是一个进程中的一个线程。
各个进程同时执行,称为并行。
多个线程同时执行,称为并发。
所有的任务排队执行,称为同步执行。
在执行任务A的同时,执行任务B,称为异步执行。
Java中,线程以对象的形式存在。
Thread类表示线程类
获取当前正在运行的线程对象
Thread ct = Thread.cuurentThread();
创建一个线程对象
常用构造方法 | 说明 |
---|---|
Thread() | 创建一个默认的线程对象 |
Thread(String name) | 创建一个指定名称的线程对象 |
Thread(Runnable target) | 将一个Runnable对象包装为线程对象 |
Thread(Runnable target,String name) | 将一个Runnable对象包装为线程对象同时设置线程名 |
方法 | 作用 |
---|---|
getId() | 获取线程id |
getName() | 获取线程名,默认Thread-n |
getPriority() | 获取线程优先级,默认为5 |
getState() | 获取线程状态 |
setName(String str) | 设置线程名 |
setPriority(int priority) | 设置线程优先级,范围在1-10,值越大越优先执行 |
isDaemon() | 判断线程是否为守护线程 |
setDaemon(boolean f) | 参数为true表示设置线程为守护线程 |
start() | 让线程进入就绪状态 |
run() | 线程获得执行权时执行的方法(线程要做的事情) |
Thread.sleep(long m) | 设置当前线程休眠m毫秒 |
Thread.currentThread() | 获取当前执行的线程对象 |
Thread.yield() | 线程让步 |
线程的初始化到终止的整个过程,称为线程的生命周期。
当线程对象被创建后,就进入了新生状态。
当某个线程对象调用了start()方法后,就进入了就绪状态。
在这个状态下,线程对象不会做任何事情,只在等他CPU调度。
当某个线程对象得到CPU时间片(CPU执行这个线程的机会所给的时间),则进入运行状态,开始执行run()方法。
不会等待run()方法执行完毕,只会在指定的时间内尽可能地执行run()方法。只要调用玩run()方法后,就会再进入就绪状态。
如果某个线程遇到了sleep()方法或wait()方法时,就会进入阻塞状态。
sleep()方法会在指定时间后,让线程重新就绪。
wait()方法只有在被调用notify()或notifyAll()方法唤醒后才能重新就绪。
当某个线程的run()方法中的所有内容都执行完,就会进入终止状态,意味着该线程的使命已经完成。
如果将一个线程设置setDeamon(true),表示该线程为守护线程。
守护线程会随着其他非守护线程终止而终止。
package com.hqyj.DaemonTest; /* * Test类是一个自定义线程类,死循环输出 * */ public class Test implements Runnable { public static void main(String[] args) { Thread thread = new Thread(new Test()); //将自定义线程类设置为守护线程 thread.setDaemon(true); thread.start(); //main线程终止,守护线程也会终止 for (int i = 0; i < 100; i++) { System.out.println("main方法中的循环执行中"); } } @Override public void run() { while (true) { System.out.println("守护线程执行中。。。"); } } }
如银行存款100,同一时刻在手机和ATM一起取出,如果用多线程模拟,可能会出现两个线程都取出100的情况。要避免这种情况发生。
本应该大于售出后再减,再打印剩余,由于线程A在打印"售出一张"后,还没来得及执行后续内容,其他线程就开始执行了。
由于线程调用start()方法后,就进入就绪状态。如果获得了CPU时间片,就开始调用run()方法,调用run()方法后,就会再次进入就绪状态,不会等待run()方法执行完毕,所以在线程A执行run()方法的时候,线程B也开始执行了,这样就会出现数据共享的问题。
因为现在所有的线程都是异步(同时)执行。
让线程同步(排队)执行即可。这样一来,某个线程执行run()方法的时候,让其他线程等待run()方法的内容执行完毕。
这个关键字可以修饰方法或代码块
写在方法的返回值之前,这时该方法就称为同步方法。
public synchronized void fun(){
//会排队执行的代码
}
写在一个独立的{}前,这时该段内容称为同步代码块。
synchronized(要同步的对象或this){
//会排队执行的代码
}
每个对象默认都有一把"锁",当某个线程运行到被synchronized修饰的方法时,该对象就会拥有这把锁,在拥有锁的过程中,其他线程不能同时访问该方法,只有等待其结束后,才会释放这把锁。
使用synchronized修饰后的锁称为"悲观锁"。
方法被synchronized修饰后,称为同步方法,就会让原本多线程变成了单线程(异步变为同步)。
让两个线程获取资源的顺序保持一致。
如两个线程都先获取knife,再获取fork
@Override
public void run() {
synchronized (knife) {
System.out.println(Thread.currentThread().getName() + "获取了knife,3s后获取fork");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (fork) {
System.out.println(Thread.currentThread().getName() + "获取了fork,可以吃饭了");
}
}
}
让两个线程在获取资源A和B之前,再获取第三个资源,对第三个资源使用synchronized进行同步,这样某个线程在获取第三个资源后,将后续内容执行完毕,其他线程才能开始执行。
如在获取knife和fork之前,先获取paper对象
@Override public void run() { //先获取paper,再进行后续操作 synchronized (paper) { synchronized (knife) { System.out.println(Thread.currentThread().getName() + "获取了knife,3s后获取fork"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (fork) { System.out.println(Thread.currentThread().getName() + "获取了fork,可以吃饭了"); } } } }
Java高级包含的东西很多很多,并不是短期内就能学习完,完全掌握的,需要我们在以后的开发之路上不断探索,不断学习,不断掌握,不断总结的,越来越觉得自己的探索之路任重而道远。加油!!!
() + “获取了fork,可以吃饭了”);
}
}
}
### 方式二 让两个线程在获取资源A和B之前,再获取第三个资源,对第三个资源使用synchronized进行同步,这样某个线程在获取第三个资源后,将后续内容执行完毕,其他线程才能开始执行。 如在获取knife和fork之前,先获取paper对象 ```java @Override public void run() { //先获取paper,再进行后续操作 synchronized (paper) { synchronized (knife) { System.out.println(Thread.currentThread().getName() + "获取了knife,3s后获取fork"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (fork) { System.out.println(Thread.currentThread().getName() + "获取了fork,可以吃饭了"); } } } }
Java高级包含的东西很多很多,并不是短期内就能学习完,完全掌握的,需要我们在以后的开发之路上不断探索,不断学习,不断掌握,不断总结的,越来越觉得自己的探索之路任重而道远。加油!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。