float f = 3.4
可以理解为我想将一个double类型的值赋值给float类型,是基本类型转换中的大转小,需要强转;float f = (float)3.4
或者我们在什么 3.4 的时候就规范这个3.4的类型 float f = 3.4F
s1 = (short)(s1 + 1)
不是,String是引用类型,底层维护的是char类型的数组
& 是 位运算符;可以操作boolean类型,也可以操作数值类型;
&& 是逻辑运算符,表示逻辑与,只能操作boolean类型;
当运算符两边的表达式都为 true 时,结果才为 true,反之则为 false;而其中&&比较特别,我们又称短路与,当&&左边的表达式为 false 时,则不再执行&&右侧的表达式,结果也为 false,我们称之为短路,用一句话概括&&的规则:见 false 则 false;
|与||也同理,||也会出现短路功能,我们可以将短路或的规则一句话概括为:见 true 则 true
public class Sort {
public static void main(String[] args) {
int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
bubbleSort(arr);
//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
System.out.println(Arrays.toString(arr));
}
/**
* 冒泡排序
* @param arr 想要排序的数组
*/
public static void bubbleSort(int[] arr){
//控制比较轮数
for (int i = 0; i < arr.length -1; i++) {
//每轮比较多少次
for (int j = 0; j < arr.length -i -1; j++) {
if (arr[j] > arr[j + 1]) {
// temp 为一个临时变量,为了存储交换时的临时值
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
//递归:方法自己调用自己
//求 1~n 的和
public class Demo {
public static void main(String[] args) {
int sum= b1(100);
System.out.println(sum);
}
private static int b1(int i) {
if(i==1){
return 1;
}
return i+b1(i-1);
}
}
// 斐波那契数列,1,1,2,3,5,8,13...这样一个数列就是斐波那契数列,求第n项的值。
public static int f1(int n) {
if(n < 1) {
return 0;
}else if(n == 1 || n == 2) {
return 1;
}
return f1(n-1) + f1(n-2);
}
面向对象是以对象为核心来思考,解决问题的一种方式,它是 Java 核心的一种思想;
世间的万事万物我们都可以理解成一个对象,所以才有我们万物皆对象的说法。
面向对象三大特征:封装,继承,多态
面向对象的优点:易复用、易维护、易扩展,降低了系统代码的耦合度。
注意:构造方法不能重写,声明为 final 的方法不能被重写,声明为 static 的方法不能被重写,但是可以被再次声明;
//构造方法可以重载
public class Aoo {
String name;
Aoo(){}//无参构造方法
Aoo(String name){//含参构造方法
this.name = name;
System.out.println("超类");
}
}
//构造方法不可以重写
public class Aoo {
String name;
Aoo(){}//无参构造方法
Aoo(String name){//含参构造方法
this.name = name;
System.out.println("超类");
}
}
public class Boo extends Aoo{
int age;
Boo(){}
Boo(String name,int age){
super(name);//子类的构造方法中会调用父类的构造方法,但是不能重写
this.age = age;
System.out.println("派生类");
}
}
Java 在构造实例时的顺序是这样的:
访问控制修饰符有哪些?有什么区别?
访问范围 | private | default(默认的) | protected | public |
---|---|---|---|---|
本类中 | 可访问 | 可访问 | 可访问 | 可访问 |
同包中的其它类 | 不可访问 | 可访问 | 可访问 | 可访问 |
不同包中的子类 | 不可访问 | 不可访问 | 可访问 | 可访问 |
不同包中的非子类 | 不可访问 | 不可访问 | 不可访问 | 可访问 |
final 是最终的意思,可以修饰变量,方法,类
static 是静态的意思,常用于修饰变量和方法,当然也可以修饰代码块和内部类。
静态的特点:
注意事项:
不能,定义抽象类就是为了让其他类继承的,如果定义为 final 该类就不能被继承了,这样彼此就会产生矛盾,所以 final 不能修饰抽象类
静态代码块>构造代码块>构造方法>局部代码块
// 静态代码块>构造代码块>构造方法>局部代码块
public class Test{
public Test(){
System.out.println("三");
}
public void aa(){
System.out.println("一");
}
{
System.out.println("九");
}
public class TestChild{
public TestChild(){
System.out.println("五");
}
{
System.out.println("七");
}
public void bb(){
System.out.println("二");
}
}
public static void main(String[]args){
new Test().new TestChild().bb();//八,九,三,七,五,二
}
static{
System.out.println("八");
}
}
变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存中的一小块区域。
成员变量:类里方法外的变量,我们称为成员变量
局部变量:方法中的变量,我们称为局部变量
区别:
值传递(pass by value)是指在调用函数时将实际参数的值复制一份传递到函数中,这样在函数中如果对参数的副本进行修改,将不会影响到原来的实际参数值。
引用传递(pass by reference)是指在调用函数时将实际参数的引用地址(引用的对象在堆中的内存地址)直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。
错误理解二:Java是引用传递。
错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。
java中无论是基本类型还是引用类型,都是值传递:
Lambda表达式可参考:Lambda表达式详解
(参数列表)->{
方法体
}
这里引入了一个新的符号:->
,我们称之为箭头符号
由上述语法可以看出,Lambda表达式由箭头符号分为了两部分:
注意事项:Lambda表达式只能用于接口中只有一个抽象方法的情境中
当我们想使得我们的代码更简洁更灵活,我们使用 Lambda 表达式;
只有满足只有一个抽象方法的抽象类或者接口我们才能使用 Lambda 表达式
Lambda表达式只能用于接口中只有一个抽象方法的情境中,一般我们称这种接口为函数式接口
// == equals -> 比较
int a = 5;
int b = 7;
System.out.println(a == b);
// == 比较基本类型的时候,比较的是 值是否相等
// == 比较引用类型的时候,比较的是 地址值是否相等(内存中地址不一样)
//equals 不能比较基本类型,只能比较引用类型
//equals 是 Object 的方法
// => public boolean equals(Object obj) {return (this == obj);}
// -> 相当于 == -> 比较的就是 地址值
//如果我们重写了 equlas 方法,我们比较的就是值的相等
Student s1 = new Student("张三",15);
Student s2 = new Student("张三",15);
System.out.println(s1);//地址值 com.cy.entity.Student@16e8e07
System.out.println(s2);//地址值 com.cy.entity.Student@16e8e08
System.out.println(s1 == s2);//地址值不相等,所以结果为 false
System.out.println(s1.equals(s2));//不重写 equals 结果为 false,重写 equlas 结果为 true
charAt()
返回指定索引处的字符indexOf/lastIndexOf()
返回指定字符的索引startsWith/endsWith()
以什么开头/以什么结尾subString()
截取字符串matches()
此字符串是否匹配给定的正则表达式。split()
分割字符串,返回一个分割后的字符串数组toLowerCase/toUpeerCase()
将字符串转成小写字母/将字符串转成大写字符trim()
去除字符串两端空白replaceAll()
字符串替换length()
返回字符串长度valueOf()
将其他类型转换成字符串类型isEmpty()
判断字符串是否为空getBytes()
返回字符串的 byte 类型数组contains()
字符串中是否包含指定字符compareTo()
按字典顺序比较两个字符串不能,因为 String 类是由 final 修饰的类,故不能被继承
创建了一个或者两个 String 类型对象
创建了一个或者两个 String 类型对象
“ab”+“c” 在编译时 自动 转变成"abc"
//使用 StringBuilder 或者 StringBuffer 的 reverse()方法
String s = "123456789";
StringBuilder sb = new StringBuilder(s);
sb.reverse();
s = sb.toString();
System.out.println(s);
5 + ""
String.valueOf(5)
Integer.toString(5)
Integer.parseInt("10")
Integer.valueOf("8").inValue()
hashCode()
的作用是获取哈希码,也称为散列码;这个哈希码的作用是确定该对象在哈希表中的索引位置。这种散列表的存储结构是键值对的方式(key-value),可以根据这个键(key)快速检索出对应的值(value),以为着可以快速找到所需要的对象。
equals
的作用默认是比较内存中的地址是否相等,重写了 equals
方法后,比较的就是内容是否相等
Java IO流 共涉及40多个类,这些类看上去很杂乱,但是都是从上述的四个抽象类基类派生出来的
Java 对象序列化必须实现 Serializable 接口,使得对象能通过网络传输或者文件储存等方式传输。
如果不想将某个字段序列化,则在属性上添加 transient 关键字 修饰。
本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态。