str.charAt(i)函数 :返回字符串第i个位置的字符。
for (int i = 0; i < 7; i++) {
System.out.print(MoneyStr.charAt(i));
System.out.print(str[i]);
}
substring函数
用于截取字符串 第一个参数表示截取起点包含在返回值中,第二个参数表示终点,不在返回值中,例如“helloworld”.substring(2,4)=“bs”
replace函数 替换
String str="helloworld";
str=str.replace("world","chen");
System.out.println(str);
此时str="hellochen"
StringBuilder类
可以创造可变的字符串
StringBuilder stringBuilder=new StringBuilder("hello");
stringBuilder.append("world");
System.out.println(stringBuilder);
System.out.println(stringBuilder.reverse());
输出结果:
helloworld
dlrowolleh
可以看出已经实现了添加与反转。相比于string类型,合并字符串操作更简单,避免产生无用字符串,同时也具有反转,返回长度,转出string类型等功能。
将StringBuilder对象的值清除的一个方法,设置其长度为0.
StringBuilder sb=new StringBuilder(str);
sb.append(str);
sb.setLength(0);//设置StringBuilder对象的长度为0 从而达到清除原来对象的值的目的;
StringBuilder扩容过程
StringJoiner类
方便拼接
public static void main(String[] args) {
StringJoiner sj=new StringJoiner("*","[","]");
sj.add("小陈");
sj.add("小刚");
sj.add("小王");
sj.add("小作文");
System.out.println(sj);
}
输出结果为[小陈*小刚*小王*小作文] 构造函数中,第一个参数*表示间隔符号 第二个参数 [ 表示
起始符号,第三个符号 ] 表示结束符号。对象sj通过调用add方法拼接字符串。方便且规范。
集合ArrayList
集合可以自动扩容,容量是动态变化的。
集合可以存引用数据类型,但是不能直接存基本数据类型。
泛型:<>
一些常用方法:
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("aa"); //向集合中添加元素
arrayList.add("bb");
arrayList.add("cc");
arrayList.remove("aa");//从集合中移除元素
arrayList.remove(3);//根据索引移除元素
arrayList.set(1,"aad");//修改指定索引的元素值
arrayList.get(2);//查询指定索引的元素值
System.out.println(arrayList.size());//返回集合的元素个数
}
题目:建立一个集合储存手机对象,并返回价格低于3000的手机信息
此处给了处理返回值是多个数据的方法。
public static void main(String[] args) {
ArrayList<Phone> arrayList=new ArrayList<>();
Phone p1=new Phone("小米",1000);
Phone p2=new Phone("苹果",8000);
Phone p3=new Phone("锤子",2999);
arrayList.add(p1);
arrayList.add(p2);
arrayList.add(p3);
ReturnPhone(arrayList);
}
//技巧:如果在方法中要返回多个数据,可以先把数据放到一个容器中,再把容器返回
//如果下面的方法不是打印出价格低于3000的信息,而是要返回价格低于3000的Phone对象,可以创建一个<Phone>集合,再返回集合
public static void ReturnPhone(ArrayList<Phone> arrayList){
for (int i = 0; i < arrayList.size(); i++) {
if(arrayList.get(i).getPrice()<3000)
System.out.println(arrayList.get(i).getBrand()+arrayList.get(i).getPrice());
}
}
break,continue和return
continue:直接结束本次循环,重新开始下次循环。
break:跳出当前循环体,执行循环后面的内容。
return:结束所有循环,方法内直接返回。
Static静态变量
Static可以修饰成员方法,成员变量。(共享)
被static修饰的成员变量叫做静态变量,静态变量可以被该类所有对象共享,
可以直接用类名调用或者用对象名调用。
被被static修饰的成员方法叫做静态方法。
静态方法中只能访问静态(变量和方法),非静态方法可以访问所有。
静态方法中没有this关键字。
继承
多态
同种类型的对象,表现出不同的形态。
父类类型 对象名称=子类对象;
前提
1有继承关系
2父类引用指向子类对象 Fu f=new Zi();
3.有方法重写
好处
使用父类型作为参数,可以接收所有子类对象,体现了多态的扩展性和便利性
多态调用成员的特点
变量调用:编译运行均看左边;
方法调用:编译运行均看右边;
Animal animal=new Dog()
此时左边是父类 “动物”,右边是子类“狗”
如果用对象animal调用变量的话,调用的是父类Animal的变量,即“变量看左边”
如果用对象animal调用方法的话,调用的是子类Animal的方法,即“方法看右边”
多态的弊端:
不能调用子类的特有功能,只能调用父类已有的、被子类重写的方法。
解决方案:
将父类类型转换成子类类型 就可以继续调用子类的特有方法。
instanceof
判断对象的类型,用法 a instanceof A,代表对象a是否是A类的对象,如果是返回true,否则为false。
新用法 a instanceof A b 该句意思为,先判断a是否属于A类,如果是的话则转成A类对象,转换之后变量名为d,如果不是的话则不强转,结果直接是false;
子类转父类属于小转大,自动转换
父类转子类属于大转小,需要强制转换,好处是可以调用子类独有功能。
Final
1.用来修饰方法,说明该方法是最终方法,不能被重写;
2.用来修饰类,表明该类是最终类,不能被继承;
3.用来修饰变量,表示该量是常量,只能被赋值一次;
4.用来修饰引用数据类型,记录的地址值不能发生改变,但是内部属性值还是可以改变的。
比如用set函数改变对象的属性。
权限修饰符
抽象类 abstract
用来修饰类和方法,被abstract修饰的方法必须被继承它的子类重写。
抽象类的构造方法是子类创建对象的时候用来给子类对象赋值的。
接口
用interface来声明,用implement来继承。
接口和类之间的关系
接口中带方法体的方法
为了避免在接口中新增抽象方法后,已有的实现类报错。
接口中的静态方法
接口中的私有方法只为接口(的默认方法)提供服务,不需要外类访问。
接口的私有方法也可以设置为静态,是为了静态的默认方法服务。
适配器设计模式
创建一个适配器(本质就是class,)用于接口和实现类中间,当接口中有多个方法、而实现类只需要实现其中某个方法时,可以创建一个适配器对接口进行空实现,然后将实现类继承适配器,并重写适配器中的某个方法即可。 为了适配器类不被创造对象,一般将其设置为抽象类abstract。
内部类
静态内部类
局部内部类
匿名内部类
有的实现了某个接口的实现类只被调用一次,这时使用效率偏低,就可以采用匿名内部类,在调用的地方直接写方法体。
示例(用于按钮绑定事件)
GUI图形界面
制作一个主界面和一些组件的代码。需要JFrame类,可以设置窗口尺寸,标题,关闭方式,初始位置。以及增添了一些组件(JMenuBar,JMenu,JMenuItem,通过add将他们组合在一起,然后在JFrame类中通过this.setJMenuBar(jMenubar)将组件添加到界面中。
public class GameJFrame extends JFrame {
public GameJFrame(){
//设置界面的宽高
setSize(603,608);
this.setTitle("拼图单机版v1.0");
this.setAlwaysOnTop(true);//设置界面置顶
this.setLocationRelativeTo(null);//设置初始位置居中
this.setDefaultCloseOperation(3);//设置界面关闭后程序就关闭
//初始化菜单
//创建菜单对象
JMenuBar jMenuBar=new JMenuBar();
//创建菜单上的两个选项对象
JMenu functionJMenu=new JMenu("功能");
JMenu aboutJMenu=new JMenu("关于我们");
//创建选项下的条目对象
JMenuItem replayItem=new JMenuItem("重新游戏");
JMenuItem reLoginItem=new JMenuItem("重新登陆");
JMenuItem closeItem=new JMenuItem("关闭游戏");
JMenuItem accountItem=new JMenuItem("公众号");
//将条目对象添加到选项对象中
functionJMenu.add(replayItem);
functionJMenu.add(reLoginItem);
functionJMenu.add(closeItem);
aboutJMenu.add(accountItem);
//将选项对象添加到菜单对象中
jMenuBar.add(functionJMenu);
jMenuBar.add(aboutJMenu);
//给整个界面设置菜单
this.setJMenuBar(jMenuBar);
setVisible(true);//设置界面可见 建议写在最后
}
}
将某段代码抽取成方法快捷键ctrl +alt+ m
效果图
添加图片素材并设置位置。
用到了ImageIcon,JLabel.
采用根据坐标循环添加素材的方式,将整型变量number用于图片路径中。
事件
以下是创建一个基本按钮的代码
public class test1 {
public static void main(String[] args) {
JFrame jFrame=new JFrame();
jFrame.setSize(603,608);
jFrame.setAlwaysOnTop(true);
jFrame.setTitle("事件演示");
jFrame.setLocationRelativeTo(null);
jFrame.setLayout(null);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//以上设置主界面
//下面设置按钮
JButton jButton=new JButton("点我");//创建按钮对象 显示为“点我”
jButton.setLocation(0,0);//设置按钮位置
jButton.setSize(100,50);//设置按钮大小
jButton.addActionListener(new MyActionListener());
//包含鼠标点击和空格监听 参数为监听到行为要执行的方法 对象是一个实现了ActionListener接口的对象
jFrame.getContentPane().add(jButton); // 将按钮加入到界面中
jFrame.setVisible(true);
}
}
其中按钮绑定事件可以通过匿名内部类来实现
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("别点我");
}
});
效果图
常用API
Math
几个常用方法
System
System.arraycopy()方法拷贝数组。
Object
可以在自己定义的类中重写Object中的tostring方法,从而使打印出来的不是成员地址值,而是对象的属性值。
clone()方法
BigINteger
大整数。
正则表达式
爬虫
不可变的集合
Stream流
用到了lambda表达式简化。
stream中生成键值对的函数tomap
lambda表达式简写
方法引用
可以在GUI事件中使用成员方法
省去了判断事件e是被哪个组件触发的判断。每个按钮触发的方法可以独立写,可读性高。
引用构造方法
类名::方法规则
异常
自定义异常
File
三个构造方法
file方法
1.createNewFile 创建一个新的空的文件
细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true/ l如果当前路径表示的文件是存在的,则创建失败,方法返回false
细节2:如果父级路径是不存在的,那么方法会有异常IOException
细节3: createNewFile方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件
代码实现
//创建文件,带后缀
//细节:有后缀名直接创建带后缀名的文件,没有则是空文件
File file6 = new File("D:\\JavaStudyDir\\a.txt");
boolean flag1 = file6.createNewFile();
System.out.println(flag1);
//创建文件,不带后缀
File file7 = new File("D:\\JavaStudyDir\\a");
boolean flag2 = file6.createNewFile();
System.out.println(flag2);
mkdir:
细节1: windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false
细节2: mkdir方法只能创建单级文件夹,无法创建多级文件夹。
3.mkdirs创建多级文件夹
细节:既可以创建单级的,又可以创建多级的文件夹
//创建单级文件夹
File file8 = new File("D:\\JavaStudyDir\\aaa");
boolean flag3 = file8.mkdirs();
System.out.println(flag3);
//创建多级文件夹,不是多个
File file9 = new File("D:\\JavaStudyDir\\bbb\\ccc\\ddd");
boolean flag4 = file9.mkdirs();
System.out.println(flag4);
删除细节:
1.如果删除的是文件,则直接删除,不走回收站。
2.如果删除的是空文件夹,则直接删除,不走回收站
3.如果删除的是有内容的文件夹,则删除失败,例如:多级文件不能删除,因为多级里面算是有文件(多级不是指多个)
//删除文件以及文件夹
System.out.println(file6.delete());
System.out.println(file7.delete());
System.out.println(file8.delete());
System.out.println(file9.delete());
IO流
概念介绍
io流自动释放
字符集
编码解码
字符流
FileWriter
缓冲区
缓冲流
就是字节字符流加上了缓冲区提高效率。
转换流
序列化流(对对象操作)
没有抽象方法的接口叫做标记性接口。
打印流
字节打印流printStream
字符打印流printWriter
Hutool
字节流字符流比较
字节流和字符流的区别:
字符流只能处理文本数据,而字节流既可以操作文本文件,也可以操作非文本文件(二进制文件如图片、视频等); 字节流默认不使用缓冲区;字符流使用缓冲区。
结论:仅仅要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
尽管可以使用File进行文件的操作,但是如果要进行文件内容的操作,在Java之中就必须通过两类流操作完成。 Java的流操作分为字节流和字符流两种。
字符流处理的对象单元是Unicode字符,每个Unicode字符占据2个字节,而字节流输入输出的数据是以单个字节(Byte)为读写单位。这种流操作方式给操作一些双字节字符带来了困难。字符流是由Java虚拟机将单个字节转化为2个字节的Unicode字符,所以它对多国语言支持较好。
若将一段二进制数据(如音频、视频和图像)写入某个设备,或从某个设备读出,使用字节流操作进行读写更加方便。
若是读写一段文本,则使用字节流进行操作,读取时将文本以字节流的方式读入,如果要将字节显示为字符,就需要使用字节和字符之间的转换。需要一个直接用于操作文本数据的I/O类——字符流。字符流将字节流进行包装,接受字符串输入,并在底层将字符转换为字节。
Java 的流式输入/输出建立在4个抽象类的基础上:InputStream(字节输入流)、OutputStream(字节输出流)、Reader(字符输入流)和Writer(字符输出流)。
一般在操作文件流时,不管是字节流还是字符流,都可以按照如下的流程进行:
(1)使用File类找到一个要操作的文件路径;
(2)通过File类的对象去实例化字节流或字符流的子类;
(3)进行字节(字符)的读/写操作;
(4)IO流属于资源操作,操作的最后必须关闭。
字节流
字节流包含两个顶层抽象类:InputStream和OutputStream。所有的读操作都继承自一个公共超类java.io.InputStream类。所有的写操作都继承自一个公共超类java.io.OutputStream类。
OutputStream的方法
InputStream方法
字符流
Writer方法
Reader方法
字节流与字符流的转换
爬取网页数据
public class Test1 {
public static void main(String[] args) throws IOException {
//定义变量记录网址
String familyNameNet="https://wen.baidu.com/question/1741226005291675907.html";
String boyNameNet="https://www.mingziwang.cn/baobaoqiming/35091.html";
String girlNameNet="https://www.mingziwang.cn/baobaoqiming/35093.html";
String familyName = webCrawler(familyNameNet);//爬取数据
String boyName = webCrawler(boyNameNet);//爬取数据
String girlName = webCrawler(girlNameNet);//爬取数据
ArrayList<String> boyarr = getData(boyName, "([\\u4E00-\\u9FA5]{2})(、|。)", 1);
}
//根据网址爬取数据
public static String webCrawler(String net) throws IOException {
URL url=new URL(net);//转换成url网址对象
StringBuilder sb=new StringBuilder();
URLConnection conn = url.openConnection();//url对象链接
InputStreamReader isr=new InputStreamReader(conn.getInputStream());//conn读取到url链接中的字节流 转换成字符流
int data;
while ((data=isr.read())!=-1)
{
sb.append((char) data);//将爬取到的数据加入stringBuilder对象中
}
isr.close();
return sb.toString();//返回网页内容
}
//根据正则表达式将爬取到的网址内容进行筛选并且返回
public static ArrayList<String> getData(String net,String regex,int index)
{
ArrayList<String> list=new ArrayList<>();
Pattern pattern=Pattern.compile(regex);
Matcher matcher = pattern.matcher(net);
while (matcher.find()){
list.add(matcher.group(index));
System.out.println(matcher.group(index));
}
return list;
}
}
爬取网页数据跟用正则表达式筛选的构建方法大致如上。正则表达式比较难写,需要依赖于网页内容的格式。
多线程
实现方式
1:自建类去继承Thread类 重写run方法.
实现方式2:自建类实现接口Runnable,重写run方法
实现方式3:自建类实现Callable接口,重写方法call(有返回值,代表多线程运行的结果)。
创建自建类的对象(表示多线程要执行的任务)
创建Future对象,作用管理多线程运行的结果
常见的成员方法
守护线程
若将某个线程设置为守护线程,当其他非守护线程关闭后,守护线程会自动关闭。
锁可以是任意对象 比如Object obj。可以用Thread.class .本类的字节码文件,是唯一的.
同步方法
Lock锁
等待唤醒机制
在Desk.lock.wait()的时候,会释放Desk.lock锁,所以此程序不会死锁。
线程的状态
线程池
当核心线程都排满了,并且排队队列也满了,此时创建临时线程来对排队队列外的线程进行处理,即临时线程4.5处理任务7.8。
任务先提交未必先执行,比如此时任务456在排队,78已经被临时线程处理了。
创建自定义线程池的构造方法中各个参数的意义。用ThreadPoolExecutor
网络编程
B/S架构(浏览器/服务器)
C/S架构(客户端/服务器)
网络编程三要素
UDP
协议发送与接收
TCP
反射
获取class对象的三种方式
利用反射获取构造方法
动态代理
无侵入式的给代码增加额外功能