文章目录
java语言程序设计期末复习
1.概叙
- java的特点:不存在独立于类的函数,一次编译(javac)处处运行(java)。
- JDK:JRE+相关开发工具(如javac),程序员使用的软件
- JRE:JVM+其他基础设施,没有它就不可能再Windows上运行Java
2.java应用程序基础
- public的类名称必须和.java文件名称一模一样,因此,一个java源文件中只能有一个公有类。
- java 程序的基本单位是类
- Java标识符开头
$_[a-z]
+
后的数据类型与左边的对象的数据类型保持一致
3.语法基础
1.foreach
这仅仅是for语句的一种扩充写法。
2. 引用数据类型
-
当声明一个引用数据类型时,并没有创建一个对象,此变量为null
-
而原始数据类型在声明时,会立刻给它分配空间
- String向其他的转换
int x=Integer.parseInt(str);
- 其他向String的转换
X.toString();#调用方法
X+"";#自动转换
String.valueOf(X);#静态方法
- 其他之间的转换
Double y=1.0;
Integer x=y.intValue();
4.方法
- 静态方法
静态方法不需要创建实例,就可以直接使用。可以一定程度上模仿C语言中的函数。
- 方法重载
两个方法的名字一样,但是形式参数不一样。
- 处理大整数
BigInteger x=Biginteger.valueOf(1);
- 随机数生成
Random random = new Random();
- 可变参数
public static double max(double ... values){//只能在参数列表的最后
}
- 递归
5.类和对象
-
this关键字
- 没啥大用,
this.value
和value
大部分情况等价 - 同一个类里的函数可以互相调用
f()
等价this.f()
。但是static的方法只可以调用静态方法和静态成员。
- 没啥大用,
-
构造方法constructor
-
==
对原始数据类型可以比较是否相等,但对于引用类型变量,实在比较引用地址。 -
包
import 包名.类型名;//导入特定的类型(类或接口)
import 包名*;//导入指定包的全部类型
- 所有用户自己开发的package,都不能用java和javax打头
- 包名要放在源文件的开头。
- 以点好分隔的包名,对应着相应文件夹的结构
- 组件化开发(CBD):将老系统中可以重用的代码抽出,单独构建为“组件”,开发新系统时直接用这些组件,这就是CBD的基本思想。
- jdk的各个组件,就是以jar包的形式提供给开发者的。
- jar文件是一个压缩文件,可用zip等解压。
- jar包中包容一个清单文件,包容重要信息,比如指定哪个是主类main class
- 双击部分jar包可以执行:指定主类,并且jar包包容所有所需的组件
- 如何跨项目重用代码:
- 封装为一个单独的jar包,在新项目添加到build path中。
6.字符串
- String对象的内容是只读的:对String做操作,实际上是返回一个全新的字符串。
- 字符串的比较:
==
比较字符串变量是否引用同一对象。.equals
比较内容s1.compareTo(s2)
字典法比较.regionMatches()
比较两字符串中某一部分是否相等。
- 字串查找:
.startWith("Hel")
是否以某字串开头.endWith("rld")
是否以某字串结尾.indexOf("Hello")
查找index,找不到返回-1
- 字符串常用功能
subSring
提取子串concat
和+
一样String.valueOf()
把其他数据类型转换成字符串toUpperCase()/toLowerCase
getChars()
trim()
去除头尾空格
- StringBuffer类
StringBuffer buf = new StringBuffer("Head");
buf.insert(0,"tail");
buf.toString();
buf.deleteCharAt(10);
buf.delete(2,6);
7.正则表达式
1.正则表达式常识
[]
候选字符集,指示字符串中单个位置。^
例外字符集合] - ^ [
包围在[]
中时需要转义。{min(,max)}
指定重复次数()
可以把若干字符当成一个整体处理。|
多选一,左边的选项拥有更高的优先级。^ $
指定字符串的起始、结束字符。Match the beginning and end of the string.?=
断言。(?=seashore)sea
先看字符串是否有seashore出现,为真时,回到开头再匹配后面的内容。sea(?=shore)
先匹配,再看后面是不是跟着shore,不回到开头。注意?=
后出现的字符不会出现在最终匹配的字符串中。?!
定义为false的条件。\w
相当于[0-9a-zA-Z_]
\w
相当于[^0-9a-zA-Z_]
2.java中的正则表达式
-
String类支持正则
如:要求用户输入6位数字
userInput.matches("^\\d{6}$");
-
java.util.regex包
Pattern expression = Pattern.compile("\\d{5}");
String str = "HelloWorld12334";
Matchar matcher = expression.matcher(str);
while(matcher.find()){
System.out.println(matcher.group());
}
8 .数组
- 数组特点
- 一经创建,尺寸保持不变
- 元素具有相同的数据类型
- 如果基本类型是int,初始化默认为0
- 如果数组元素是引用类型,使用前先创建相应对象。
- 数组创建方法
String[] str = new String[100];
其中String[]
进行declare,new
进行allocate。
- 数组的初始化
int[] n = {10,20,30,40,50};
- 遍历初始化
- 访问数组
- 如果使用循环语句,要注意非法的数组下标。如果越界会抛出
ArrayIndexOutOfBoundsException
异常 - foreach语句
for(String i: str)
。要注意迭代变量必须在()中定义,集合变量可以是任何一个实现了Iterable
接口的集合类。
- 数组的参数传递
- 传递引用,也即传递地址。
9.类与接口
1.类class
- 构造方法
先运行父类的构造方法,再运行子类的构造方法。
- 不允许继承的类
final class 类名{}
- 子类与父类的关系
- extends:子类可以继承父类的属性方法(没有重名的那些)。
- override:子类定义了和父类**完全一样(包括参数)**的方法,重写了该方法。有如下要点:
- 覆盖方法的允许访问范围不小于原方法
- 抛出的异常不能多于原方法
- final方法不可以被覆盖
- static方法不可以被覆盖
- overloads:子类方法名称和父类中的一样,但参数不一样,重载了该方法。
2.抽象类abstract class
- 抽象类不可以
new
,必须派生一个子类,并实现其中全部抽象方法(如果不完全则仍为abstract)。 - 抽象类内部可以包含非抽象方法和成员变量。
- 使用抽象类:不能创建对象,用它来引用子类对象。
抽象类 抽象类变量 = new 派生子类();
3.接口(类)interface
- 接口的应用:
- 类的行为特征,可以理解为面向符合该接口设定类的一组需求。
- sort的应用示例:
Java的Array类有sort静态方法,可以对对象数组进行排序。但对象所属的类必须实现Comparable接口。
可以看一看这个接口
public interface Comparable<T>{
int compareTo(T other);
}
具体的使用
class Student implements Comparable<Student>{
...
public int compareTo(Student other){
return Double.compare(age,other.age);
}
...
}
-
接口的扩充:可以通过继承接口来扩充已有接口。
-
使用接口:实现接口的类必须实现所有接口定义的方法,才可以
new
。接口类型 接口类型变量 = new 实现接口的具体类型();
4.接口和抽象类的区别
- 抽象类是一个不完全的类。
- 接口只是表明类应该具有哪些外部特征。
5.内部类
- 直接包容于另一个类(或一方法)内部的类。
- 内部类的好处
- 当以面对对象的方式封装某些信息为一个类,而这些信息仅在一个地方被另一个类(或方法)使用,没有必要创建一个独立的,公开的类,也不利于信息隐藏。在这种情况下,可以建立内部类。
- 对于匿名内部类,实际上展示了“把代码本身当作数据”的思想。
10.多态
- java重写需要注意的规则
- 子类方法与父类方法的参数列表和返回类型应完全一致。
- 被子类重写的方法不能拥有比父类方法更加严格的访问权限。比如父类中private方法就无法被重写。
- 覆盖方法抛出的异常不能多于原方法。
- final,static声明的方法不能被覆盖。
- 多态的好处
在修改程序或扩充系统时,所需的修改的地方较少,对其他部分代码影响较小。在大规模程序设计中减少代码冗余,利于后续功能的开发和完善。
11.异常处理
- 目的:一句实际情况提供不同错误的的应对策略和手段,事程序更加稳定。
- 用途:提供准确的错误消息,解释失败的原因。同时具备一定的恢复能力,尽可能保证数据完整性不被破坏,并让程序能够继续运行。
try{
//可能发生运行错误的代码
}catch(异常对象){
//处理异常的代码
}finally{
//不管如何,这里一定被执行
}
printStackTrace
打印方法调用堆栈,每个Throwable
类对象都有一个。getMessage
方法,它返回一个字符串,这个字符串是在Exception
构造函数中传入的,通常让这一字串包含特定异常的相关信息。
12.泛型
-
集合使用泛型:限制集合接受的对象类型,并且消除了类型转换的需要。
-
泛型的优势
- 减少类的数目,促进代码复用
- 剖离数据结构和算法
- 减少编码错误,在编译时就检查类型。
-
定义的时候,用
T
代替即可,在创建实例的时候需要指定类型
13.lambda表达式与方法引用
1.lambda表达式——接口实现的一种方式(函数式接口)
- 标准格式:
(形式参数)->{代码块}
1.形式参数:如果有多个参数,用逗号隔开
2.代码块:具体实现的内容,类似方法体。
3.作用:类似于实现了 重写 和 创建实例 两个步骤。整体直接当作一个被创建的对象用。
- 使用前提
- 有一个接口
- 接口中有且只有一个抽象方法
- 省略模式
- 参数类型可以省略
- 如果参数只有一个,小括号可以省略
- 如果代码块语句只有一条,可以省略大括号,分号和return
- lambda表达式和匿名内部类的区别
- 例子
//匿名内部类,可以实现更多内容,但写起来也相对复杂
new Thread(new Runnable(){
@override
public void run(){
System.out.println("Hello");
}
}).start()
//lambda表达式
new Thread(()->{
System.out.println("Hello");
}).start()
2.方法引用
- 引用类静态方法
类名::静态方法
Integer::parseInt;
useConvert(s->Interger.parseInt);
useConvert(Integer::parseInt);
private static void useConvert(Converter c){
int number=c.convert("666");
}
- 引用对象实例
对象::成员方法
3.排序与接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O93T12By-1638941678029)(C:\Users\19416\AppData\Roaming\Typora\typora-user-images\image-20211206102453638.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-diRsmcd4-1638941678031)(C:\Users\19416\AppData\Roaming\Typora\typora-user-images\image-20211206102714515.png)]
14.Stream流
1.基础概念
- 不是数据结构,没有内部存储
- 不支持索引访问
- 仅出现中间操作时不执行
- 当出现终止操作时,才会执行
- 流对象只能使用一次,使用过后必须重建。
2.常用操作
- 中间操作
filter
过滤distinct
去重sorted
排序limit
skip
截取map
flatMap
转换peek
其他
- 终止操作
forEach
循环min\max\count\average
计算anyMatch\allMatch\noneMatch\findFirst\findAny
匹配reduce
规约toArray\collect
收集器collect需要配合Collector使用。
3.Stream创建
.Stream
方法创建:几乎所有的Collection对象都实现了Collection接口定义的Stream方法
List ls = new ArrayList<String>();
Stream<String> st=ls.stream();
- Stream接口定义的
of
方法创建
String[] names={"1","2","3"};
Stream<String> stream = Stream.of(names);
-
Stream.Builder<T>
接口 -
基于数组构建
IntStream intStream = Arrays.stream(elements);
- 特殊构建
IntStream stream = IntStream.range(0,100);
Stream<String>stream = Stream.empty();
- 元素工厂
Supplier<Integer> intFactory = ()->(int)(Math.random()*100);
Stream<Integer> stream = Stream.generate(intFactory).limit(10)
//generate构建无穷流,需要用limit。
- 迭代法构建流
//起始值为1
int seed = 1;
//使用递推公式a[n]=a[n-1]+2
UnaryOperator<Integer> intFactory = n->n+2;
Stream<Integer> stream = Stream.iterate(seed,intFactory).limit(10);
4.Optional
级联操作,如果中间遇到NULL,会打断流处理管线。为了解决这个问题,引入了Optional类
15.一些拓展
1.实现Iterable接口
public class Stack<T> implements Iterable<T> {
//实现iterator接口
private static Object[] elements;
private static int N = 0;
public boolean isEmpty() {return N == 0;}
public int size() {return N;}
//重写iterator方法,该方法无参数,返回Iterator<T>
@Override
public Iterator<T> iterator() {
return new ReversedArrayIterator<>();
}
//需要实现内部类,实现Iterator接口,并重写以下三个方法。
private static class ReversedArrayIterator<T> implements Iterator<T> {
private int current = N;
@Override
public boolean hasNext() {
return current != 0;
}
@Override
public T next() {
T result = (T) elements[--current];
return result;
}
}
}
Override
public Iterator iterator() {
return new ReversedArrayIterator<>();
}
//需要实现内部类,实现Iterator接口,并重写以下三个方法。
private static class ReversedArrayIterator implements Iterator {
private int current = N;
@Override
public boolean hasNext() {
return current != 0;
}
@Override
public T next() {
T result = (T) elements[--current];
return result;
}
}
}