类型强制转换
// byte、short、char 运算时直接提升为 int
int i = (int)1.5; // double类型数据强制转成int类型,直接去掉小数点。
long up = Long.parseLong(lines[lines.length-3]); // string转为long
Float.parseFloat(lines[0]); // string转float
三元运算符
数据类型 变量名 = 布尔类型表达式?结果1:结果2
1==2 ? 100 : 200
判断语句
if 语句
if(关系表达式){ 语句体; }
if-->else 语句
if(关系表达式) { 语句体1; }else { 语句体2; }
if-->else if-->else语句
if (判断条件1) { 执行语句1; } else if (判断条件2) { 执行语句2; }else if (判断条件n) { 执行语句n; } else { 执行语句n+1; }
switch语句
switch(表达式) { case 常量值1: 语句体1; break; case 常量值2: 语句体2; break; ... default: 语句体n+1; break; }
for循环语句
for(初始化表达式①; 布尔表达式②; 步进表达式④){ 循环体③ }
for(int x = 0; x < 10; x++) { System.out.println("HelloWorld"+x); }
for(元素的数据类型 变量 : Collection集合or数组){ //写操作代码 } // 增强for
while循环语句
while(布尔表达式②){ 循环体③ 步进表达式④ }
while(i<=10){ System.out.println("HelloWorld"); //步进 i++; }
do...while循环语句
do{ 循环体③ 步进表达式④ }while(布尔表达式②);
do {System.out.println("HelloWorld"); x++; }while(x<=10);
跳出循环语句
break // 终止switch或者循环
continue // 结束本次循环,继续下一次的循环
死循环
死循环的是永不结束的循环
嵌套循环
for(初始化表达式①; 循环条件②; 步进表达式⑦) { for(初始化表达式③; 循环条件④; 步进表达式⑥) { 执行语句⑤; } }
for(int i = 0; i < 5; i++){ for(int j = 0; j < 8; j++){ System.out.print("*"); } System.out.println(); }
Stream流
String[] array = {"张无忌", "周芷若", "赵敏", "张强", "张三丰"};
Stream<String> original = Stream.of(array);
original.filter(s ‐> s.startsWith("张")) // 过滤 创建一个新的 stream流 原来的关闭
original.filter(s ‐> s.length() == 3)
original.forEach(System.out::println); // 逐一处理
result = original.map(str‐>Integer.parseInt(str)); // 映射 将流中的元素映射到另一个流中
System.out.println(result.count()); // 统计 元素个数
Stream<String> result = original.limit(2); // 取用前几个
Stream<String> result = original.skip(2); // 跳过前几个
Stream<String> streamA = Stream.of("张无忌");
Stream<String> streamB = Stream.of("张翠山");
Stream<String> result = Stream.concat(streamA, streamB); // 组合:concat 合并两个流为一个
数组:
容器
是将多个数据存储到一起,每个数据称为该容器的元素。
数组概念
数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致。
格式1
数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度]
int[] arr = new int[3];
格式2
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...}
int[] arr = new int[]{1,2,3,4,5};
格式3
数据类型[] 数组名 = {元素1,元素2,元素3...};
int[] arr = {1,2,3,4,5};
数组的访问
数组名[索引]
int[] arr = new int[]{1,2,3,4,5};
arr[0] = 1; // 访问数组
数组遍历
for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); }
数组方法
arr.length // 打印数组长度
面向对象:
类和对象
类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该 类事物
属性:就是该事物的状态信息。
行为:就是该事物能够做什么。
对象:是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为
类的定义格式
public class ClassName { //成员变量 //成员方法 }
定义类:就是定义类的成员,包括成员变量和成员方法。
成员变量:和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外。
成员方法:和以前定义方法几乎是一样的。只不过把static去掉
创建对象
类名 对象名 = new 类名();
使用对象访问类中的成员:
对象名.成员变量;
对象名.成员方法();
成员变量的默认值
整数(byte,short,int,long) 0
浮点数(float,double) 0.0
字符(char) '\u0000'
布尔(boolean) false
数组,类,接口 null
成员变量和局部变量区别
成员变量:类中,方法外
局部变量:方法中或者方法声明上(形式参数)
成员变量:类中
局部变量:方法中
成员变量:有默认值
局部变量:没有默认值。必须先定义,赋值,最后使用
成员变量:堆内存
局部变量:栈内存
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
封装
概述
防止类的代码和数据被其他类随意访问,要访问该类的数据,必须通过指定的方式
private
private是一个权限修饰符,代表最小权限。
可以修饰成员变量和成员方法。
被private修饰后的成员变量和成员方法,只在本类中才能访问。
private的使用格式
private 数据类型 变量名;
private String name;
提供 getXxx 方法 / setXxx 方法,可以访问成员变量
public void setName(String n) { name = n; }
public String getName() { return name; }
this关键字
this代表所在类的当前对象的引用
this使用格式
this.成员变量名;
public void setName(String name) { this.name = name; }
构造方法
修饰符 构造方法名(参数列表){ // 方法体 }
public class Student { private String name; private int age;
// 无参数构造方法
public Student() {}
// 有参数构造方法
public Student(String name,int age) {
this.name = name;
this.age = age; } }
如果你不提供构造方法,系统会给出无参数构造方法。
如果你提供了构造方法,系统将不再提供无参数构造方法。
构造方法是可以重载的,既可以定义参数,也可以不定义参数。
对象被创建的时候,构造方法将会被执行
Scanner
创建对象
数据类型 变量名 = new 数据类型(参数列表);
Scanner sc = new Scanner(System.in);
调用方法
变量名.方法名();
String i = sc.next(); // 接收一个键盘录入的数据
int i = sc.nextInt(); // 接收一个键盘录入的整数
Object类
在对象实例 化的时候,最终找的父类就是Object。
如果一个类没有特别指定父类, 那么默认则继承自Object类
toString方法
返回该对象的字符串表示。
toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。
equals方法
指示其他某个对象是否与此对象“相等”。
调用成员方法equals并指定参数为另一个对象,则可以判断这两个对象是否是相同的
String
特点
字符串不变:字符串的值在创建后不能被更改
因为String对象是不可变的,所以它们可以被共享
"abc" 等效于 char[] data={ 'a' , 'b' , 'c' }
String str = new String(); // 无参构造
String str2 = new String(char chars[] = {'a', 'b', 'c'}); // 通过字符数组构造
String str3 = new String(byte bytes[] = { 97, 98, 99 };); // 通过字节数组构造
常用方法
s1.equals(s2); // 比较字符串的内容是否相同 区分大小写
s1.equalsIgnoreCase(s2); // 比较字符串的内容是否相同,忽略大小写
s.length(); // :获取字符串的长度,其实也就是字符个数
s.concat("**hello itheima"); // 将将指定的字符串连接到该字符串的末尾.
s.charAt(0); // 获取指定索引处的字符
s.indexOf("l"); // 获取str在字符串对象中第一次出现的索引,没有返回‐1
s.substring(0); // 从start开始截取字符串到字符串结尾
s.substring(3, 8); // 从start到end截取字符串。含start,不含end。
s.toCharArray(); // 把字符串转换为字符数组
s.getBytes(); // 把字符串转换为字节数组
String replace = str.replace("it", "IT"); // 替换字母it为大写IT
s.split("|"); // 创建字符串对象
static
概述
可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的
类变量
类变量:使用 static关键字修饰的成员变量。
static 数据类型 变量名; // 定义格式
static int numberID;
静态方法
类方法:使用 static关键字修饰的成员方法,习惯称为静态方法。
修饰符 static 返回值类型 方法名 (参数列表){ // 执行语句 }
public static void showNum() { System.out.println("num:" + numberOfStudent); }
静态方法调用的注意事项
静态方法可以直接访问类变量和静态方法。
静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问类变量或静态方法。
静态方法中,不能使用this关键字。
调用格式
被static修饰的成员可以并且建议通过类名直接访问
类名.类变量名; // 访问类变量
类名.静态方法名(参数); // 调用静态方法
static 修饰的内容特点;
是随着类的加载而加载的,且只加载一次
存储于一块固定的内存区域(静态区),所以,可以直接被类名调用
它优先于对象存在,所以,可以被所有对象共享
静态代码块
静态代码块:定义在成员位置,使用static修饰的代码块{ }。
位置:类中方法外。
执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行。 格式
static { // 执行语句 }
final
概述
final: 不可改变。可以用于修饰类、方法和变量。
类:被修饰的类,不能被继承。
方法:被修饰的方法,不能被重写。
变量:被修饰的变量,不能被重新赋值。
修饰类
final class 类名 { }
修饰方法
修饰符 final 返回值类型 方法名(参数列表){ //方法体 }
修饰变量
final int a; // 声明变量,使用final修饰
继承
概述
继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接 访问父类中的非私有的属性和行为。
好处
提高代码的复用性。
类与类之间产生了关系,是多态的前提。
继承的格式
通过 extends 关键字
class 子类 extends 父类 { ... }
成员变量
子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super 关键字,修饰 父类成员变量,类似于之前学过的 this 。
super.父类成员变量名
super.num; // 访问父类中的num
成员方法
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。
方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。声明不变,重新实现。
子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样
构造方法
构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的
构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构 造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用
super和this
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身
super :代表父类的存储空间标识(可以理解为父亲的引用)。
this :代表当前对象的引用(谁调用就代表谁)
this.成员变量 ‐‐ 本类的
super.成员变量 ‐‐ 父类的
this.成员方法名() ‐‐ 本类的
super.成员方法名() ‐‐ 父类的
继承的特点
Java只支持单继承,不支持多继承
Java支持多层继承(继承体系)。
子类和父类是一种相对的概念。
抽象类
概述
如果一个类包含抽象方法,那么该类必须是抽象类。
定义
抽象方法 : 没有方法体的方法。
抽象类:包含抽象方法的类。
abstract使用格式
使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。
修饰符 abstract 返回值类型 方法名 (参数列表); // 定义格式:
public abstract void run();
抽象类
如果一个类包含抽象方法,那么该类必须是抽象类。
abstract class 类名字 { } // 定义格式:
public abstract class Animal { public abstract void run(); }
抽象的使用
继承抽象类的子类必须重写父类所有的抽象方法
注意事项
抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类
抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类
接口
概述
接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么 接口的内部主要就是封装了方法
接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并 不是类,而是另外一种引用数据类型。
接口的使用,它不能创建对象,但是可以被实现( implements ,类似于被继承)
定义格式
public interface 接口名称 { // 抽象方法 // 默认方法 // 静态方法 // 私有方法 }
含有抽象方法
抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用。
public interface InterFaceName { public abstract void method(); }
含有默认方法和静态方法
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写
静态方法:使用 static 修饰,供接口直接调用
public interface InterFaceName {
public default void method() {
// 执行语句
}
public static void method2() {
// 执行语句
} }
含有私有方法和私有静态方法
私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。
public interface InterFaceName {
private void method() {
// 执行语句
} }
非抽象子类实现接口:
必须重写接口中所有抽象方法。
继承了接口的默认方法,即可以直接调用,也可以重写。
class 类名 implements 接口名 {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【可选】
}
抽象方法的使用
定义接口:
public interface LiveAble {
// 定义抽象方法
public abstract void eat();
public abstract void sleep();
}
定义实现类:
public class Animal implements LiveAble {
@Override
public void eat() {
System.out.println("吃东西"); }
@Override
public void sleep() {
System.out.println("晚上睡");
} }
默认方法的使用
可以继承,可以重写,二选一,但是只能通过实现类的对象来调用
静态方法的使用
静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
私有方法的使用
私有方法:只有默认方法可以调用。
私有静态方法:默认方法和静态方法可以调用。
接口的多实现
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】
// // 重写接口中默认方法【不重名时可选】
}
抽象方法
接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次
默认方法
接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次
静态方法
接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法。
优先级的问题
当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执 行父类的成员方法
接口的多继承
一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继 承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次
interface D extends A,B{
@Override
public default void method() {
System.out.println("DDDDDDDDDDDDDD");
}
}
成员特点
接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰
接口中,没有构造方法,不能创建对象。
接口中,没有静态代码块。
多态
概述
多态: 是指同一行为,具有多个不同表现形式。
多态体现的格式
父类类型 变量名 = new 子类对象;
变量名.方法名();
向上转型
向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的
父类类型 变量名 = new 子类类型(); // 就是多态
Animal a = new Cat();
向下转型
向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的
子类类型 变量名 = (子类类型) 父类变量名;
Cat c =(Cat) a;
权限修饰符
public:公共的
protected:受保护的
default:默认的
private:私有的
不加权限修饰符,其访问能力与default修饰符相同
不同权限的访问能力
public protected default private
同一类中 √ √ √ √
同一包中(子类与无关类) √ √ √
不同包的子类 √ √
不同包中的无关类 √
内部类
概述
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类
成员内部类 :定义在类中方法外的类
定义格式:
class 外部类 { class 内部类{ } }
class Car { //外部类 class Engine { //内部类 } }
访问特点
内部类可以直接访问外部类的成员,包括私有成员
外部类要访问内部类的成员,必须要建立内部类的对象。
创建内部类对象格式
外部类名.内部类名 对象名 = new 外部类型().new 内部类型()
匿名内部类
匿名内部类 :是内部类的简化写法。它的本质是一个 带具体实现的 父类或者父接口的 匿名的 子类对象。
匿名内部类必须继承一个父类或者实现一个父接口。
包装类
装箱与拆箱
装箱:从基本类型转换为对应的包装类对象
Integer i = new Integer(4);//使用构造函数函数
Integer iii = Integer.valueOf(4);//使用包装类中的valueOf方法
拆箱:从包装类对象转换为对应的基本类型。
int num = i.intValue();
基本类型转换为String
基本类型直接与""相连接即可
String转换成对应的基本类型
public static byte parseByte(String s); // 将字符串参数转换为对应的byte基本类型。
public static short parseShort(String s); // 将字符串参数转换为对应的short基本类型。
public static int parseInt(String s); // 将字符串参数转换为对应的int基本类型
public static long parseLong(String s); // 将字符串参数转换为对应的long基本类型
public static float parseFloat(String s); // 将字符串参数转换为对应的float基本类型
public static double parseDouble(String s); // 将字符串参数转换为对应的double基本类型
public static boolean parseBoolean(String s); // 将字符串参数转换为对应的boolean基本类型
int num = Integer.parseInt("100");
函数式接口
概念
有且仅有一个抽象方法的接口。
格式
public interface MyFunctionalInterface { void myMethod(); } // 由于接口当中抽象方法的 public abstract 是可以省略的
@FunctionalInterface注解
编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错
泛型
泛型:可以在类或方法中预支地使用未知的类型。
定义格式:
修饰符 class 类名<代表泛型的变量> { }
ArrayList<Integer> list = new ArrayList<Integer>();
含有泛型的方法
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
public <MVP> void show(MVP mvp) { System.out.println(mvp.getClass()); }
含有泛型的接口
修饰符 interface接口名<代表泛型的变量> { }
泛型通配符
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
类型名称 <? extends 类 > 对象名称 泛型的上限
public static void getElement1(Collection<? extends Number> coll){} // 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
类型名称 <? super 类 > 对象名称 // 泛型的下限
public static void getElement2(Collection<? super Number> coll){} // 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类