public class FloatPrecision { public static void main(String[] args) { double sum = 0.1 + 0.2; System.out.println("The sum is: " + sum); }}/**The sum is: 0.30000000000000004转换为二进制表示时,它们会变成无限循环小数:- 0.1 = 0.0001100110011001100110011...(二进制)- 0.2 = 0.00110011001100110011001100...(二进制)这些无限循环小数不能在有限的二进制位数内精确表示,因此计算机必须对它们进行近似。在不截断的情况下,理论上的计算应该是: 0.1+0.2=0.3然而,由于0.1和0.2在二进制中的表示是近似的,所以实际存储在计算机中的值也是近似的。这意味着当你执行`0.1 + 0.2`的计算时,你实际上是在计算两个近似值的和。*/
1.概述:给类,方法,变量取的名字 2.注意: a.硬性规定(必须遵守) 标识符可以包含"英文字母","数字","$和_" 标识符不能以数字开头 int i1 = 100(正确) int 1i = 100(错误) 标识符不能是关键字 int static = 100(错误) int public = 100(错误)
public class Demo01Arithmetic { public static void main(String[] args) { int i = 10; int j = 3; int add = i+j;//推荐使用 System.out.println(add);//13 System.out.println(i+j);//13 int sub = i-j; System.out.println(sub);//7 int mul = i*j; System.out.println(mul);//30 int div = i/j; System.out.println(div);//3 int mo = i%j; System.out.println(mo);//1 }}
public class Demo02Arithmetic { public static void main(String[] args) { int i = 10; int j = 3; System.out.println(i+j+"");//13 System.out.println(i+j+""+1);//131 System.out.println(i+""+j);//103 System.out.println("i和j相加只和为:"+(i+j)); }}
public class Demo03Arithmetic { public static void main(String[] args) { int i = 10; //i++; ++i; System.out.println("i = " + i); //11 System.out.println("=================="); int j = 100; int result01 = ++j; System.out.println("result01 = " + result01);//101 System.out.println(j);//101 System.out.println("=================="); int k = 10; int result02 = k++; System.out.println("result02 = " + result02); //10 System.out.println(k); //11 System.out.println("=================="); int z = 100; System.out.println(z++); //100 System.out.println(z); //101 System.out.println("=================="); int c = 10; c = c++;//这种写法是无效的,开发不会有这种写法 System.out.println(c);//10 System.out.println(c);//10 /* int temp = c; // 保存当前的 c 值(10) c = c + 1; // c 自增为 11 c = temp; // 将 temp 的值(10)重新赋值给 c */ }}
public class Demo01Compare { public static void main(String[] args) { int i = 10; int j = 20; boolean result01 = i == j; System.out.println("result01 = " + result01);//false System.out.println(i>j);//false System.out.println(i<j);//true System.out.println(i>=j);//false System.out.println(i<=j);//true System.out.println(i!=j);//true }}
public class Demo01Ternary { public static void main(String[] args) { //定义一个变量,表示小明的分数 int score = 60; String result = score>=60?"及格":"不及格"; System.out.println("result = " + result); }}
练习2
有两个老人,年龄分别为70 80 求出两个老人的最高年龄
public class Demo02Ternary { public static void main(String[] args) { int old1 = 70; int old2 = 80; int max = old1>old2?old1:old2; System.out.println("max = " + max); }}
练习3
有三个老人,年龄分别为70 80 60 求出三个老人的最高年龄
public class Demo03Ternary { public static void main(String[] args) { int old1 = 70; int old2 = 80; int old3 = 60; int temp = old1>old2?old1:old2; int max = temp>old3?temp:old3; System.out.println("max = " + max); }}
1.概述:java自带的一个类2.作用:可以在指定的范围内随机一个整数3.位置:java.util4.使用: a.导包:import java.util.Random b.创建对象: Random 变量名 = new Random() c.调用方法,生成随机数: 变量名.nextInt() -> 在int的取值范围内随机一个整数
public class Demo01Random { public static void main(String[] args) { //创建对象 Random rd = new Random(); int data = rd.nextInt(); System.out.println("data = " + data); }}
1.格式: switch(变量){ case 常量值1: 执行语句1; break; case 常量值2: 执行语句2; break; case 常量值3: 执行语句3; break; case 常量值4: 执行语句4; break; ... default: 执行语句n; break; }2.执行流程: 用变量接收的值和下面case后面的常量值匹配,匹配上哪个case就执行哪个case对应的执行语句 如果以上所有case都没有匹配上,就走default对应的执行语句n3.break关键字:代表的是结束switch语句 4.注意:switch能匹配什么类型的数据: byte short int char 枚举类型 String类型
public class Demo03Switch { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int month = sc.nextInt(); switch(month){ case 12: case 1: case 2: System.out.println("冬季"); break; case 3: case 4: case 5: System.out.println("春季"); break; case 6: case 7: case 8: System.out.println("夏季"); break; case 9: case 10: case 11: System.out.println("秋季"); break; default: System.out.println("什么情况,你家有这个月份?"); } }}
public class Demo03IfElse { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int data = sc.nextInt(); if (data%2==0){ System.out.println("偶数"); }else{ System.out.println("奇数"); } }}
public class Demo06IfElse { public static void main(String[] args) { //1.创建Scanner对象,调用nextInt键盘录入一个年份 year Scanner scanner = new Scanner(System.in); int year = scanner.nextInt(); //2.判断(year%4==0 && year%100!=0) || (year%400==0) if ((year%4==0 && year%100!=0) || (year%400==0)){ //3.如果条件成立,就输出闰年2月29天,否则输出平年2月28天 System.out.println("闰年2月29天"); }else{ System.out.println("平年2月28天"); } }}
public class Demo01BreakAndContinue { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { if (i==3){ //结束循环 //break; //结束本次循环,进入下一次循环 continue; } System.out.println("我爱java"+i); } }}
public class Demo01Endless { public static void main(String[] args) { int count = 0; for (int i = 0; i < 10;) { count++; System.out.println("我爱java"+count); } /* while(true){ count++; System.out.println("我爱java"+count); }*/ }}
public class Test { public static void main(String[] args) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(i+"*"+j+"="+(i*j)+"\t"); } System.out.println(""); } }}
public class Demo06Array { public static void main(String[] args) { int[][] arr1 = new int[3][]; arr1[1] = new int[]{1,2,3}; arr1[2] = new int[3]; arr1[2][1] = 100; }}
public class Demo02Method { public static void main(String[] args) { sum(); System.out.println("哈哈哈哈哈"); } public static void sum(){ int a = 10; int b = 20; int sum = a+b; System.out.println("sum = " + sum); }}
public class Demo03Method { public static void main(String[] args) { sum(10,20); } public static void sum(int a,int b){ int sum = a+b; System.out.println("sum = " + sum); }}
public class Demo04Method { public static void main(String[] args) { //打印调用 -> 涛哥不推荐 System.out.println(sum()); //赋值调用-> 极力推荐 int result = sum(); System.out.println("result = " + result); } public static int sum(){ int a = 10; int b = 20; int sum = a+b; return sum; //return a+b; }}
public class Demo05Method { public static void main(String[] args) { int sum = sum(10, 20); System.out.println("sum = " + sum); } public static int sum(int a,int b){ int sum = a+b; return sum; }}
public class Person { //属性-> 成员变量 String name; int age; //行为 -> 成员方法 public void eat(){ System.out.println("人要干饭"); } public void drink(){ System.out.println("人要喝水"); }}
public class Demo01Person { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name); System.out.println(person.age); person.name = "金莲"; person.age = 26; System.out.println(person.name); System.out.println(person.age); person.eat(); person.drink(); }}
1.int i = 10 a.int:是数据类型 b.i:变量名 c.等号右边的10:真正的数据 2.Person p = new Person() a.等号左边的Person:对象的类型,好比是int b.p:对象名 c.等号右边的new Person():真正的数据,是一个Person对象,将这个对象真正创建出来了
1.所谓的匿名对象:其实就是没有等号左边的部分,只有等号右边的部分(对象)2.使用: new 对象().成员3.注意: a.如果我们只想单纯的调用一个方法,让方法执行,我们可以考虑使用匿名对象 b.但是如果涉及到赋值,千万不要用匿名对象
public class Person { String name; public void eat(){ System.out.println("人要吃饭"); }}
public class Demo01Person { public static void main(String[] args) { //原始方式 Person p = new Person(); p.name = "金莲"; System.out.println(p.name); p.eat(); System.out.println("================="); //匿名对象 new Person().eat(); new Person().name = "大郎"; System.out.println(new Person().name);//null }}
public class Person { private String name; private int age; //为name提供get/set方法 public void setName(String xingMing) { name = xingMing; } public String getName() { return name; } //为age提供get/set方法 public void setAge(int nianLing) { if (nianLing < 0 || nianLing > 150) { System.out.println("你脑子是不是秀逗啦!岁数不合理"); } else { age = nianLing; } } public int getAge() { return age; }}
public class Test01 { public static void main(String[] args) { Person person = new Person(); //person.name = "悟空"; //person.age = -18; //System.out.println(person.name); //System.out.println(person.age); person.setName("悟空"); person.setAge(18); String name = person.getName(); int age = person.getAge(); System.out.println(name+"..."+age); }}
public class Person { String name;//成员变量 public void eat(){ int i = 10;//局部变量 System.out.println(i); System.out.println(name);//成员变量不用手动赋值可以直接使用,因为有默认值 } public void drink(){ int j; //System.out.println(j);//局部变量没有默认值,所以需要手动赋值再使用 System.out.println(name); //System.out.println(i);//i是eat方法的局部变量,在drink中使用不了 }}
public class Person { String name; /* 哪个对象调用的this所在的方法,this就代表哪个对象 */ public void speak(String name){ System.out.println(this+"........"); System.out.println(this.name+"您好,我是"+name); }}
public class Test01 { public static void main(String[] args) { Person person = new Person(); System.out.println(person+"========="); person.name = "沉香"; person.speak("刘彦昌"); System.out.println("=========="); Person person2 = new Person(); System.out.println(person2+"+++++"); person2.name = "奥特曼"; person2.speak("奥特曼之父"); }}
1.格式: public 类名(形参){ 为属性赋值 }2.作用: a.new对象 b.为属性赋值3.特点: jvm不会自动提供有参构造,但是将有参构造手写出来,jvm将不再提供无参构造,所以建议有参,无参的构造都手写上去
public class Person { private String name; private int age; //无参构造 public Person(){ System.out.println("我是无参构造"); } //有参构造 public Person(String name,int age){ this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; }}
public class Test01 { public static void main(String[] args) { Person person = new Person(); Person person2 = new Person("涛哥", 18); System.out.println(person2.getName()+"..."+person2.getAge()); }}
public class Person { private String name; private int age; //无参构造 public Person(){ } //有参构造 public Person(String name,int age){ this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; }}
public class Test01 { public static void main(String[] args) { Person person = new Person(); person.setName("金莲"); person.setAge(26); System.out.println(person.getName()+"..."+person.getAge()); Person person2 = new Person("涛哥", 18); System.out.println(person2.getName()+"..."+person2.getAge()); }}
编写符合JavaBean 规范的类,以学生类为例,标准代码如下:
public class Student { private int sid; private String sname; public Student() { } public Student(int sid, String sname) { this.sid = sid; this.sname = sname; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; }}
public class ArraysUtils { /* 构造方法用private修饰 工具类中的成员都是静态的,静态成员都是类名调用,不需要new对象 所以工具类中的构造方法都是用private修饰 如果构造方法被private修饰,那么在别的类中,就不能利用构造方法new对象 */ private ArraysUtils(){ } //定义一个方法,实现获取int数组最大值 public static int getMax(int[] arr){ int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (max<arr[i]){ max = arr[i]; } } return max; }}
public class Test01 { public static void main(String[] args) { int[] arr = {5,3,4,6,7,54,8}; int max = ArraysUtils.getMax(arr); System.out.println("max = " + max); }}
public class Demo01Var { public static void main(String[] args) { sum(1,2,3,4,5); sum1(1,1,2,3,4); } public static void sum(int...arr){ int sum = 0; for (int i = 0; i < arr.length; i++) { sum+=arr[i]; } System.out.println(sum); } public static void sum1(int i,int...arr){ //只能有一个可变参数,和普通参数一起使用时,需放在最后 }}
public class Demo01Param { public static void main(String[] args) { int a = 10; int b = 20; method(a,b); System.out.println(a);//10 System.out.println(b);//20 } public static void method(int a,int b){ a+=10; b+=20; System.out.println(a);//20 System.out.println(b);//40 }}
1.继承只支持单继承,不能多继承 public class A extends B,C{} -> 错误2.继承支持多层继承 public class A extends B{} public class B extends C{}3.一个父类可以有多个子类 public class A extends C{} public class B extends C{}4.构造方法不能继承,也不能重写 私有方法可以继承,但是不能被重写 静态方法可以继承,但是不能被重写
public class Fu { public void method01(){ System.out.println("method01方法"); } private void method02(){ System.out.println("method02方法"); } public static void method03(){ System.out.println("method03方法"); }}
public class Zi extends Fu{ @Override public void method01(){ System.out.println("重写的method01方法"); }/* @Override private void method02(){ System.out.println("method02方法"); }*/}
public class Test01 { public static void main(String[] args) { Zi zi = new Zi(); zi.method03(); Zi.method03(); }}
public class Test01 { public static void main(String[] args) { //创建父类对象 Fu fu = new Fu(); System.out.println(fu.numFu);//父类中的numFu //System.out.println(fu.numZi);//不能直接调用子类特有的成员 System.out.println("================="); //创建子类对象 Zi zi = new Zi(); System.out.println(zi.numZi); System.out.println(zi.numFu);//继承了父类,可以使用父类中非私有成员 }}
public class Fu { int numFu = 100; int num = 10000;}
public class Zi extends Fu{ int numZi = 10; int num = 1000;}
public class Test01 { public static void main(String[] args) { //创建父类对象 Fu fu = new Fu(); System.out.println(fu.numFu);//父类中的numFu //System.out.println(fu.numZi);//不能直接调用子类特有的成员 System.out.println(fu.num);//父类的 System.out.println("================="); //创建子类对象 Zi zi = new Zi(); System.out.println(zi.numZi); System.out.println(zi.numFu);//继承了父类,可以使用父类中非私有成员 System.out.println(zi.num);//子类的 }}
public class Fu { public void methodFu(){ System.out.println("我是父类中的methodFu"); } public void method(){ System.out.println("我是父类中的method方法"); }}
public class Zi extends Fu{ public void methodZi(){ System.out.println("我是子类中的methodZi方法"); } public void method(){ System.out.println("我是子类中的method方法"); }}
public class Test01 { public static void main(String[] args) { Fu fu = new Fu(); fu.methodFu(); // fu.methodZi(); 不能直接调用子类特有的方法 fu.method();//父类中的method方法 System.out.println("====================="); Zi zi = new Zi(); zi.methodZi(); zi.methodFu();//继承父类之后,能调用父类非私有成员 zi.method();//子类中的method方法 System.out.println("==================="); Fu fu1 = new Zi(); fu1.method();//调用的是子类中的method方法 }}
public class Fu { public void methodFu(){ System.out.println("我是父类中的methodFu方法"); } public void method(){ System.out.println("我是父类中的method方法"); }}
public class Zi extends Fu{ public void methodZi(){ System.out.println("我是子类中的methodZi方法"); } @Override public void method(){ System.out.println("我是子类中的method方法"); }
public class Test01 { public static void main(String[] args) { Fu fu = new Fu(); fu.methodFu();//自己的methodFu方法 fu.method();//new的是父类对象,那么调用的就是父类中的method System.out.println("================"); Zi zi = new Zi(); zi.methodZi(); zi.methodFu(); zi.method();//子类中的method方法 }}
1.子类重写父类方法之后,权限必须要保证大于等于父类权限(权限指的是访问权限) public -> protected -> 默认 -> private2.子类方法重写父类方法,方法名和参数列表要一样3.私有方法不能被重写,构造方法不能被重写,静态方法不能被重写4.子类重写父类方法之后,返回值类型应该是父类方法返回值类型的子类类型
public class Fu { public void methodFu(){ System.out.println("我是父类中的methodFu方法"); } public void method(){ System.out.println("我是父类中的method方法"); } void method01(){ } /* public static void method02(){ }*/ public Fu method03(){ return null; }}
public class Zi extends Fu{ public void methodZi(){ System.out.println("我是子类中的methodZi方法"); } @Override public void method(){ System.out.println("我是子类中的method方法"); } @Override public void method01(){ } /* public static void method02(){ }*/ @Override public Zi method03(){ return null; }}
public class OldPhone { public void call(){ System.out.println("打电话"); } public void message(){ System.out.println("发短信"); } public void show(){ System.out.println("显示手机号"); }}
public class NewPhone extends OldPhone{ public void show(){ System.out.println("显示手机号"); System.out.println("显示归属地"); }}
public class Test01 { public static void main(String[] args) { NewPhone newPhone = new NewPhone(); newPhone.call(); newPhone.message(); newPhone.show(); }}
public class Fu { public Fu(){ System.out.println("我是父类中的无参构造"); }}
public class Zi extends Fu{ public Zi(){ //super(); System.out.println("我是子类中的无参构造"); } public Zi(int i){ //super(); System.out.println("我是子类中的有参构造"); }}
public class Test { public static void main(String[] args) { Zi zi = new Zi(); System.out.println("==========="); Zi zi1 = new Zi(10); }}
public class Fu { int num = 10; public Fu(){ System.out.println("我是父类中的无参构造"); } public Fu(int data){ System.out.println("我是父类中的有参构造"); } public void method(){ System.out.println("我是父类中的method方法"); }}
public class Zi extends Fu{ int num = 100; public Zi(){ super();//调用父类中的无参构造 System.out.println("我是子类中的无参构造"); } public Zi(int num){ super(10);//调用父类的有参构造 System.out.println("我是子类中的有参构造"); } public void method(){ super.method();//调用父类的method方法 System.out.println("我是子类中的method方法"); System.out.println(num);//子类自己的 System.out.println(super.num);//调用父类的num }}
public class Test01 { public static void main(String[] args) { Zi zi = new Zi(); System.out.println("============"); Zi zi1 = new Zi(10); System.out.println("============"); Zi zi2 = new Zi(); zi2.method(); }}
public class Person { int num = 10; public Person(){ //this(10); System.out.println("我是Person中的无参构造"); } public Person(int data){ //super();super和this不能同时再构造中出现 this(); System.out.println("我是Person中的有参构造"); } public void method(){ int num = 20; System.out.println(num);//20 System.out.println(this.num);//10 this.method01(); System.out.println("我是Person类中的method方法"); } public void method01(){ System.out.println("我是Person类中的method01方法"); }}
public class Test01 { public static void main(String[] args) { Person person = new Person(); System.out.println("========"); Person person1 = new Person(10); System.out.println("========"); Person person2 = new Person(); person2.method(); }}
public abstract class Animal { public abstract void eat(); public abstract void drink();}
public class Dog extends Animal{ @Override public void eat() { System.out.println("狗啃骨头"); } @Override public void drink() { System.out.println("狗喝水"); }}
public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } @Override public void drink() { System.out.println("猫喝水"); }}
public class Test01 { public static void main(String[] args) { Dog dog = new Dog(); dog.eat(); dog.drink(); System.out.println("==================="); Cat cat = new Cat(); cat.eat(); cat.drink(); }}
public abstract class Employee { private String name; private int age; public Employee() { } public Employee(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void work();}
public class Teacher extends Employee{ public Teacher() { } public Teacher(String name, int age) { super(name, age); } @Override public void work() { System.out.println("涛哥在讲java"); }}
public class Test01 { public static void main(String[] args) { Teacher t1 = new Teacher("涛哥", 18); System.out.println(t1.getName()+"..."+t1.getAge()); }}
1.定义接口: public interface 接口名{}2.实现: public class 实现类类名 implements 接口名{}3.使用: a.实现类实现接口 b.重写接口中的抽象方法 c.创建实现类对象(接口不能直接new对象) d.调用重写的方法
public interface USB { public abstract void open(); public abstract void close();}
public class Mouse implements USB{ @Override public void open() { System.out.println("鼠标打开"); } @Override public void close() { System.out.println("鼠标关闭"); }}
public class Test01 { public static void main(String[] args) { Mouse mouse = new Mouse(); mouse.open(); mouse.close(); }}
public interface USB { //默认方法 public default void methodDef(){ System.out.println("我是默认方法"); } //静态方法 public static void methodSta(){ System.out.println("我是接口中的静态方法"); }}
public class Test01 { public static void main(String[] args) { Mouse mouse = new Mouse(); mouse.methodDef(); System.out.println("============="); USB.methodSta(); }}
1.接口可以多继承 -> 一个接口可以继承多个接口 public interface InterfaceA extends InterfaceB,InterfaceC{}2.接口可以多实现 -> 一个实现类可以实现一个或者多个接口 public class InterfaceImpl implements InterfaceA,InterfaceB{}3.一个子类可以继承一个父类的同时实现一个或者多个接口 public class Zi extends Fu implements InterfaceA,InterfaceB{}4.注意: 继承也好,实现接口也罢,只要是父类中或者接口的抽象方法,子类或者实现类都要重写
当一个类实现多个接口时,如果接口中的抽象方法有重名且参数一样的,只需要重写一次
public interface InterfaceA { public abstract void method();}public interface InterfaceB { public abstract void method();}public class InterfaceImpl implements InterfaceA,InterfaceB{ @Override public void method() { System.out.println("重写的method方法"); }}
当一个类实现多个接口时,如果多个接口中默认方法有重名的,且参数一样的,必须重写一次默认方法
public interface InterfaceA { public abstract void method(); public default void methodDef(){ System.out.println("我是接口A中的默认方法"); }}public interface InterfaceB { public abstract void method(); /* public default void methodDef(){ System.out.println("我是接口B中的默认方法"); }*/ public default void methodDef(int a) { System.out.println("我是接口B中的默认方法"); }}public class InterfaceImpl implements InterfaceA,InterfaceB{ @Override public void method() { System.out.println("重写的method方法"); }/* @Override public void methodDef() { System.out.println("重写后的默认方法"); }*/}public class Test01 { public static void main(String[] args) { InterfaceImpl anInterface = new InterfaceImpl(); anInterface.methodDef(); anInterface.methodDef(10); }}
1.前提: a.必须有子父类继承或者接口实现关系 b.必须有方法的重写(没有重写,多态没有意义),多态主要拓展的是重写方法作用 c.new对象:父类引用指向子类对象 Fu fu = new Zi() -> 理解为大类型接收了一个小类型的数据 ->比如 double b = 102.注意: 多态下不能直接调用子类特有功能
public abstract class Animal { public abstract void eat();}
public class Dog extends Animal{ @Override public void eat() { System.out.println("狗啃骨头"); } //特有方法 public void lookDoor(){ System.out.println("狗会看门"); }}
public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } //特有方法 public void catchMouse(){ System.out.println("猫会捉老鼠"); }}
public class Test01 { public static void main(String[] args) { //原始方式 Dog dog = new Dog(); dog.eat();//重写的 dog.lookDoor();//特有的 Cat cat = new Cat(); cat.eat();//重写的 cat.catchMouse();//特有的 System.out.println("=================="); //多态形式new对象 Animal animal = new Dog();//相当于double b = 10 animal.eat();//重写的 animal接收的是dog对象,所以调用的是dog中的eat// animal.lookDoor(); 多态前提下,不能直接调用子类特有成员 Animal animal1 = new Cat(); animal1.eat();//cat重写的 }}
1.问题描述: 如果使用原始方式new对象(等号左右两边一样),既能调用重写的,还能调用继承的,还能调用自己特有的成员 但是多态方式new对象,只能调用重写的,不能直接调用子类特有的成员,那为啥还要用多态呢?2.多态方式和原始方式new对象的优缺点: 原始方式: a.优点:既能调用重写的,还能调用父类非私有的,还能调用自己特有的 b.缺点:扩展性差 多态方式: a.优点:扩展性强 b.缺点:不能直接调用子类特有功能 Fu fu = new Zi() double b = 10; b = 100L;
public abstract class Animal { public abstract void eat();}
public class Dog extends Animal { @Override public void eat() { System.out.println("狗啃骨头"); } //特有方法 public void lookDoor(){ System.out.println("狗会看门"); }}
public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } //特有方法 public void catchMouse(){ System.out.println("猫会捉老鼠"); }}
public class Test01 { public static void main(String[] args) { Dog dog = new Dog(); dog.eat();//重写的 dog.lookDoor();//特有的 //dog = new Cat(); System.out.println("============="); method(dog); Cat cat = new Cat(); method(cat); /* houzi houzi = new houzi(); method(houzi); bird bird = new bird(); method(bird);*/ } public static void method(Dog dog){ dog.eat(); dog.lookDoor(); } public static void method(Cat cat){ cat.eat(); cat.catchMouse(); } /* public static void method(houzi houzi){ cat.eat(); cat.catchMouse(); }*/}
public class Test02 { public static void main(String[] args) { /* double b = 10; b = 100L; */ Animal animal = new Dog(); animal.eat(); animal = new Cat(); animal.eat(); System.out.println("================="); Dog dog = new Dog(); method(dog); Cat cat = new Cat(); method(cat); } /* 形参传递父类类型,调用此方法父类类型可以接收任意它的子类对象 传递哪个子类对象,就指向哪个子类对象,就调用哪个子类对象重写的方法 */ public static void method(Animal animal){//Animal animal = dog Animal animal = cat animal.eat(); }}
1.向下转型:好比强转,将大类型强制转成小类型2.表现方式: 父类类型 对象名1 = new 子类对象() -> 向上转型 -> double b = 1 子类类型 对象名2 = (子类类型)对象名1 -> 向下转型 -> int i = (int)b3.想要调用子类特有功能,我们就需要向下转型
public abstract class Animal { public abstract void eat();}
public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } //特有方法 public void catchMouse(){ System.out.println("猫会捉老鼠"); }}
public class Dog extends Animal { @Override public void eat() { System.out.println("狗啃骨头"); } //特有方法 public void lookDoor(){ System.out.println("狗会看门"); }}
public class Test01 { public static void main(String[] args) { //多态new对象 向上转型 Animal animal = new Dog(); animal.eat();//dog重写的 //animal.lookDoor();//多态不能调用子类特有功能 //向下转型 Dog dog = (Dog) animal; dog.eat(); dog.lookDoor(); }}
public abstract class Animal { public abstract void eat();}
public class Dog extends Animal { @Override public void eat() { System.out.println("狗啃骨头"); } //特有方法 public void lookDoor(){ System.out.println("狗会看门"); }}
public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } //特有方法 public void catchMouse(){ System.out.println("猫会捉老鼠"); }}
public class Test01 { public static void main(String[] args) { Dog dog = new Dog(); method(dog); System.out.println("==============="); Cat cat = new Cat(); method(cat); } public static void method(Animal animal){//animal = dog animal = cat /* animal.eat(); *//* 这里会出现类型转换异常(ClassCastException) 原因:当调用method,传递Cat对象时,animal代表的就是cat对象 此时我们将代表cat对象的animal强转成了dog 此时等号左右两边类型不一致了,所以出现了类型转换异常 *//* Dog dog = (Dog) animal; dog.lookDoor();*/ if (animal instanceof Dog){ Dog dog = (Dog) animal; dog.eat(); dog.lookDoor(); } if (animal instanceof Cat){ Cat cat = (Cat) animal; cat.eat(); cat.catchMouse(); } }}
public interface USB { public abstract void open(); public abstract void close();}
public class Mouse implements USB{ @Override public void open() { System.out.println("鼠标开启"); } @Override public void close() { System.out.println("鼠标关闭"); } //特有方法 public void click(){ System.out.println("来呀,快点我"); }}
public class KeyBoard implements USB{ @Override public void open() { System.out.println("键盘开启"); } @Override public void close() { System.out.println("键盘关闭"); } //特有功能 public void input(){ System.out.println("来呀,敲我呀!"); }}
public class NoteBook { //开机 public void start(){ System.out.println("开机"); } //使用USB /* USB usb = mouse 多态 USB usb = keyBoard 多态 */ public void useUSB(USB usb){ if (usb instanceof Mouse){ Mouse mouse = (Mouse) usb; mouse.open(); mouse.click(); mouse.close(); }else{ KeyBoard keyBoard = (KeyBoard) usb; keyBoard.open(); keyBoard.input(); keyBoard.close(); } //usb.open(); //usb.close(); } //关机 public void stop(){ System.out.println("关机"); }}
public class Test01 { public static void main(String[] args) { NoteBook noteBook = new NoteBook(); Mouse mouse = new Mouse(); noteBook.start(); noteBook.useUSB(mouse); noteBook.stop(); System.out.println("==========="); KeyBoard keyBoard = new KeyBoard(); noteBook.start(); noteBook.useUSB(keyBoard); noteBook.stop(); }}
1.格式: final 数据类型 对象名 = new 对象();2.特点: 被final修饰的对象,地址值不能改变,但是对象中的属性值可以改变
public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
public class Test02 { public static void main(String[] args) { //Person p1 = new Person("金莲",26); //System.out.println(p1);//地址值 //p1 = new Person("涛哥",18); //System.out.println(p1);//地址值 final Person p1 = new Person("金莲",26); System.out.println(p1);//地址值 //p1 = new Person("涛哥",18); //System.out.println(p1);//地址值 p1.setName("大郎"); p1.setAge(30); System.out.println(p1.getName()+"..."+p1.getAge()); }}
public class Person { public Person(){ System.out.println("我是无参构造方法"); } //构造代码块 { System.out.println("我是构造代码块"); } //静态代码块 static{ System.out.println("我是静态代码块"); }}
public class Test01 { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person(); }}
1.格式:直接在定义内部类的时候加上static关键字 public class A{ static class B{ } }2.注意: a.内部类可以定义属性,方法,构造等 b.静态内部类可以被final或者abstract修饰 被final修饰之后,不能被继承 被abstract修饰之后,不能new c.静态内部类不能调用外部的非静态成员 d.内部类还可以被四种权限修饰符修饰3.调用静态内部类成员: 外部类.内部类 对象名 = new 外部类.内部类()
public class Person { public void eat(){ System.out.println("人要干饭"); } static class Heart{ public void jump(){ System.out.println("心脏哐哐哐跳"); } }}
public class Test01 { public static void main(String[] args) { // 外部类.内部类 对象名 = new 外部类.内部类() Person.Heart heart = new Person.Heart(); heart.jump(); }}
格式: public class A{ class B{ } }调用非静态内部类成员: 外部类.内部类 对象名 = new 外部类().new 内部类()
public class Person { public void eat(){ System.out.println("人要干饭"); } class Heart{ public void jump(){ System.out.println("心脏哐哐哐跳"); } }}
public class Test01 { public static void main(String[] args) { // 外部类.内部类 对象名 = new 外部类().new 内部类() Person.Heart heart = new Person(). new Heart(); heart.jump(); }}
外部类的成员变量和内部类的成员变量以及内部类的局部变量重名时,怎么区分?
public class Student { String name = "金莲"; class Heart{ String name = "大郎"; public void display(String name){ System.out.println(name);//内部类的局部变量 System.out.println(this.name);//内部类的成员变量 System.out.println(Student.this.name);//外部类的成员变量 } }}public class Test02 { public static void main(String[] args) { Student.Heart heart = new Student().new Heart(); heart.display("涛哥"); }}
public interface USB { public abstract void open();}
public class Mouse implements USB{ @Override public void open() { System.out.println("鼠标打开"); }}
public class Test01 { public static void main(String[] args) { Mouse mouse = new Mouse(); method(mouse); System.out.println("================"); USB usb = method01();//USB usb = new Mouse(); usb.open(); } /* 接口作为方法参数,传递实参时,传递的是实现类对象 */ public static void method(USB usb){//USB usb = mouse -> 多态 usb.open(); } /* 接口作为返回值类型返回,实际返回的是实现类对象 */ public static USB method01(){ //Mouse mouse = new Mouse(); //return mouse; return new Mouse(); }}
抽象类作为方法参数和返回值
1.抽象类作为方法参数传递,传递实参时,传递的是其子类对象
2.抽象类作为方法返回值类型返回时,实际返回的是其子类对象
public abstract class Animal { public abstract void eat();}
public class Dog extends Animal{ @Override public void eat() { System.out.println("狗啃骨头"); }}
public class Test02 { public static void main(String[] args) { Dog dog = new Dog(); method01(dog); System.out.println("================="); Animal animal = method02();//Animal animal = new Dog() animal.eat(); } public static void method01(Animal animal){//Animal animal = dog animal.eat(); } public static Animal method02(){ return new Dog(); }}
普通类做方法参数和返回值
普通类作为方法参数传递,传递的是对象
普通类作为方法返回值返回,返回的是对象
public class Person { public void eat(){ System.out.println("人要干饭"); }}
public class Test03 { public static void main(String[] args) { Person person = new Person(); method01(person); System.out.println("=================="); Person person1 = method02();//Person person1 = new Person() person1.eat(); } public static void method01(Person person){ person.eat(); } public static Person method02(){ return new Person(); }}
局部内部类实际操作
public interface USB { void open();}
public class Test01 { public static void main(String[] args) { USB usb = method();//USB usb = new Mouse() usb.open(); } public static USB method(){ //局部内部类 class Mouse implements USB{ @Override public void open() { System.out.println("鼠标打开"); } } return new Mouse(); }}
1.问题描述:我们如果想实现接口,简单使用一次抽象方法,我们就需要创建一个实现类,实现这个接口,重写抽象方法,还要new实现类对象,所以我们在想如果就单纯的想使用一次接口中的方法,我们能不能不这么麻烦呢?可以 a.创建实现类,实现接口 b.重写方法 c.创建实现类对象 d.调用方法2.如果就想单纯的使用一下接口中的方法,我们就没必要经过以上四步了,我们可以四合一3.匿名内部类怎么学:就按照一种格式来学,这一种格式就代表了实现类对象或者子类对象4.格式: new 接口/抽象类(){ 重写方法 }.重写的方法(); ================================= 类名 对象名 = new 接口/抽象类(){ 重写方法 } 对象名.重写的方法();
public interface USB { void open(); void close();}
public class Test01 { public static void main(String[] args) { new USB(){ @Override public void open() { System.out.println("usb打开了"); } @Override public void close() { System.out.println("usb关闭了"); } }.open(); System.out.println("==================="); USB usb = new USB() { @Override public void open() { System.out.println("USB打开了"); } @Override public void close() { System.out.println("USB关闭了"); } }; usb.open(); usb.close(); }}
public class Test02 { public static void main(String[] args) { USB usb = method01(); usb.open(); } public static USB method01(){ return new USB() { @Override public void open() { System.out.println("USB打开了"); } }; }}
public class Demo03Exception { public static void main(String[] args) { String s = "a.tx1t"; method(s); } public static void method(String s){ if (!s.endsWith(".txt")){ //故意创建异常对象,用throw说明此处有异常 throw new NullPointerException(); } System.out.println("我要执行了"); }}
public class Demo10Exception { public static void main(String[] args) { } class A{ public void method()/*throws Exception*/{ } } class B extends A{ @Override public void method()/*throws Exception*/{ } }}
public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; }}
public class Test01 { public static void main(String[] args) { Person p1 = new Person("金莲", 26); System.out.println(p1);//com.example.b_object.Person@4eec7777 System.out.println(p1.toString());//com.example.b_object.Person@4eec7777 System.out.println("=============="); ArrayList<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); System.out.println(list);//[张三, 李四, 王五] System.out.println(list.toString());//[张三, 李四, 王五] }}
public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } /* 问题1:obj直接调用name和age调用不了,因为Object接收了Person类型的对象 属于多态,多态前提下不能直接调用子类特有内容 解决问题1:向下转型 问题2:如果传递的不是Person类型,就会出现类型转换异常 解决问题2:先判断类型,如果是Person类型,再强转成Person 问题3:如果传递null呢?,就不用判断类型了,直接给false 问题4:如果传递自己呢?就不用判断非空了,也不同判断类型了,直接给true */ /* public boolean equals(Object obj){ if (this==obj){ return true; } if (obj==null){ return false; } if (obj instanceof Person){ Person p = (Person) obj; return this.name.equals(p.name)&&this.age==p.age; } return false; }*/ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); }}
public class Test02 { public static void main(String[] args) { Person p1 = new Person("金莲", 26); Person p2 = new Person("金莲", 26); System.out.println(p1==p2);//false System.out.println(p1.equals(p2));//false & true System.out.println("=============="); ArrayList<String> list = new ArrayList<>(); System.out.println(p1.equals(list)); System.out.println("=============="); System.out.println(p1.equals(null)); System.out.println("=============="); System.out.println(p1.equals(p1)); System.out.println("===================="); String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.equals(s2));//true }}
小结:
1.如果直接输出对象名不想输出地址值,重写toString方法
2.如果想比较两个对象的内容,就重写一下equals方法
3.怎么重写:alt+insert -> 选toString 或者equals and hashcode -> 啥也不要管 -> 一路下一步即可
public class Person implements Cloneable{ private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } /* 问题1:obj直接调用name和age调用不了,因为Object接收了Person类型的对象 属于多态,多态前提下不能直接调用子类特有内容 解决问题1:向下转型 问题2:如果传递的不是Person类型,就会出现类型转换异常 解决问题2:先判断类型,如果是Person类型,再强转成Person 问题3:如果传递null呢?,就不用判断类型了,直接给false 问题4:如果传递自己呢?就不用判断非空了,也不同判断类型了,直接给true */ /* public boolean equals(Object obj){ if (this==obj){ return true; } if (obj==null){ return false; } if (obj instanceof Person){ Person p = (Person) obj; return this.name.equals(p.name)&&this.age==p.age; } return false; }*/ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}
public class Test03 { public static void main(String[] args) throws CloneNotSupportedException { Person p2 = new Person("涛哥", 16); Object o = p2.clone(); Person p3 = (Person) o;//克隆了一个新对象 System.out.println(p2==p3);//比较地址值 false System.out.println(p2.equals(p3));//true }}
public class Test01 { public static void main(String[] args) { //创建线程对象 MyThread t1 = new MyThread(); //调用start方法,开启线程,jvm自动调用run方法 t1.start(); for (int i = 0; i < 10; i++) { System.out.println("main线程..........执行了"+i); } }}
public class MyThread extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("MyThread...执行了"+i); } }}
public class MyThread1 extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"执行了......"+i); } }}
public class Test01 { public static void main(String[] args) { MyThread1 t1 = new MyThread1(); t1.setName("金莲"); MyThread1 t2 = new MyThread1(); t2.setName("阿庆"); /* 获取两个线程的优先级 MIN_PRIORITY = 1 最小优先级 1 NORM_PRIORITY = 5 默认优先级 5 MAX_PRIORITY = 10 最大优先级 10 */ //System.out.println(t1.getPriority()); //System.out.println(t2.getPriority()); //设置优先级 t1.setPriority(1); t2.setPriority(10); t1.start(); t2.start(); }}
public class Test01 { public static void main(String[] args) { MyThread1 t1 = new MyThread1(); t1.setName("金莲"); MyThread2 t2 = new MyThread2(); t2.setName("阿庆"); //将t2设置成守护线程 t2.setDaemon(true); t1.start(); t2.start(); }}
public class MyThread1 extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"执行了......"+i); } }}
public class MyThread2 extends Thread{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+"执行了..."+i); } }}
public class Test01 { public static void main(String[] args) { MyThread1 t1 = new MyThread1(); t1.setName("金莲"); MyThread1 t2 = new MyThread1(); t2.setName("阿庆"); t1.start(); t2.start(); }}
public class MyThread1 extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"执行了......"+i); Thread.yield(); } }}
public class MyThread1 extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"执行了......"+i); } }}
public class Test01 { public static void main(String[] args) throws InterruptedException { MyThread1 t1 = new MyThread1(); t1.setName("金莲"); t1.start(); /* 表示把t1插入到当前线程之前,t1要插到main线程之前,所以当前线程就是main线程 */ t1.join(); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"执行了......"+i); } }}
public class Test01 { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); /* Thread(Runnable target) */ Thread t1 = new Thread(myRunnable); //调用Thread中的start方法,开启线程 t1.start(); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"...执行了"+i); } }}
public class MyRunnable implements Runnable{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"...执行了"+i); } }}
public class MyTicket implements Runnable{ //定义100张票 int ticket = 100; @Override public void run() { while(ticket>0){ if (ticket>0){ System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票"); ticket--; } } }}
public class Test01 { public static void main(String[] args) { MyTicket myTicket = new MyTicket(); Thread t1 = new Thread(myTicket, "赵四"); Thread t2 = new Thread(myTicket, "刘能"); Thread t3 = new Thread(myTicket, "广坤"); t1.start(); t2.start(); t3.start(); /** 导致买到了同一张票 赵四买了第100张票 刘能买了第100张票 刘能买了第98张票 刘能买了第97张票 刘能买了第96张票 广坤买了第100张票 广坤买了第94张票 */ }}
public class MyTicket implements Runnable{ //定义100张票 int ticket = 100; //任意new一个对象 Object obj = new Object(); @Override public void run() { while(ticket>0){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (obj){ if (ticket>0){ System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票"); ticket--; } } } }}
public class Test01 { public static void main(String[] args) { MyTicket myTicket = new MyTicket(); Thread t1 = new Thread(myTicket, "赵四"); Thread t2 = new Thread(myTicket, "刘能"); Thread t3 = new Thread(myTicket, "广坤"); t1.start(); t2.start(); t3.start(); }}
public class MyTicket implements Runnable{ //定义100张票 int ticket = 100; @Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } //method01(); method02(); } } /* public synchronized void method01(){ if (ticket>0){ System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票"); ticket--; } }*/ public void method02(){ synchronized(this){ System.out.println(this+".........."); if (ticket>0){ System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票"); ticket--; } } }}
public class MyTicket implements Runnable{ //定义100张票 static int ticket = 100; @Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } //method01(); method02(); } } /*public static synchronized void method01(){ if (ticket>0){ System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票"); ticket--; } }*/ public static void method02(){ synchronized(MyTicket.class){ if (ticket>0){ System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票"); ticket--; } } }}
public class MyTicket implements Runnable { //定义100张票 int ticket = 100; //创建Lock对象 Lock lock = new ReentrantLock(); @Override public void run() { while (true) { try { Thread.sleep(100L); //获取锁 lock.lock(); if (ticket > 0) { System.out.println(Thread.currentThread().getName() + "买了第" + ticket + "张票"); ticket--; } } catch (InterruptedException e) { throw new RuntimeException(e); }finally { //释放锁 lock.unlock(); } } }}
public class Test01 { public static void main(String[] args) { MyTicket myTicket = new MyTicket(); Thread t1 = new Thread(myTicket, "赵四"); Thread t2 = new Thread(myTicket, "刘能"); Thread t3 = new Thread(myTicket, "广坤"); t1.start(); t2.start(); t3.start(); }}
class SharedResource { private final int sharedValue = 42; public int getSharedValue() { return sharedValue; }}// 多个线程只调用 getSharedValue() 方法,没有写操作,因此没有线程安全问题
public class LockA { public static LockA lockA = new LockA();}
public class LockB { public static LockB lockB = new LockB();}
public class DieLock implements Runnable{ private boolean flag; public DieLock(boolean flag) { this.flag = flag; } @Override public void run() { if (flag){ synchronized (LockA.lockA){ System.out.println("if...lockA"); synchronized (LockB.lockB){ System.out.println("if...lockB"); } } }else{ synchronized (LockB.lockB){ System.out.println("else...lockB"); synchronized (LockA.lockA){ System.out.println("else...lockA"); } } } }}
public class Test01 { public static void main(String[] args) { DieLock dieLock1 = new DieLock(true); DieLock dieLock2 = new DieLock(false); new Thread(dieLock1).start(); new Thread(dieLock2).start(); }}
/* count和flag可以定义成包装类 但是要记得给count和flag手动赋值 不然对于本案例来说,容易出现空指针异常 */public class BaoZiPu { //代表包子的count private int count; //代表是否有包子的flag private boolean flag; public BaoZiPu() { } public BaoZiPu(int count, boolean flag) { this.count = count; this.flag = flag; } /* getCount 改造成消费包子方法 直接输出count */ public void getCount() { System.out.println("消费了..............第"+count+"个包子"); } /* setCount 改造成生产包子 count++ */ public void setCount() { count++; System.out.println("生产了...第"+count+"个包子"); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; }}
public class Product implements Runnable{ private BaoZiPu baoZiPu; public Product(BaoZiPu baoZiPu) { this.baoZiPu = baoZiPu; } @Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (baoZiPu){ //1.判断flag是否为true,如果是true,证明有包子,生产线程等待 if (baoZiPu.isFlag()==true){ try { baoZiPu.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为false,证明没有包子,开始生产 baoZiPu.setCount(); //3.改变flag状态,为true,证明生产完了,有包子了 baoZiPu.setFlag(true); //4.唤醒消费线程 baoZiPu.notify(); } } }}
public class Consumer implements Runnable{ private BaoZiPu baoZiPu; public Consumer(BaoZiPu baoZiPu) { this.baoZiPu = baoZiPu; } @Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (baoZiPu){ //1.判断flag是否为false,如果是false,证明没有包子,消费线程等待 if (baoZiPu.isFlag()==false){ try { baoZiPu.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为true,证明有包子,开始消费 baoZiPu.getCount(); //3.改变flag状态,为false,证明消费完了,没 有包子了 baoZiPu.setFlag(false); //4.唤醒生产线程 baoZiPu.notify(); } } }}
public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu = new BaoZiPu(); Product product = new Product(baoZiPu); Consumer consumer = new Consumer(baoZiPu); Thread t1 = new Thread(product); Thread t2 = new Thread(consumer); t1.start(); t2.start(); }}
public class Product implements Runnable{ private BaoZiPu baoZiPu; public Product(BaoZiPu baoZiPu) { this.baoZiPu = baoZiPu; } @Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } baoZiPu.setCount(); } }}
public class Consumer implements Runnable{ private BaoZiPu baoZiPu; public Consumer(BaoZiPu baoZiPu) { this.baoZiPu = baoZiPu; } @Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } baoZiPu.getCount(); } }}
public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu = new BaoZiPu(); Product product = new Product(baoZiPu); Consumer consumer = new Consumer(baoZiPu); Thread t1 = new Thread(product); Thread t2 = new Thread(consumer); t1.start(); t2.start(); }}
public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu = new BaoZiPu(); Product product = new Product(baoZiPu); Consumer consumer = new Consumer(baoZiPu); new Thread(product).start(); new Thread(product).start(); new Thread(product).start(); new Thread(consumer).start(); new Thread(consumer).start(); new Thread(consumer).start(); }}
public class Demo03Iterator { public static void main(String[] args) { //需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马 ArrayList<String> list = new ArrayList<>(); list.add("唐僧"); list.add("孙悟空"); list.add("猪八戒"); list.add("沙僧"); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String element = iterator.next(); if ("猪八戒".equals(element)){ list.add("白龙马"); } } System.out.println(list); }}
String element = iterator.next();private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such /* modCount: 实际操作次数 expectedModCount:预期操作次数 */ int expectedModCount = modCount; @SuppressWarnings("unchecked") public E next() { checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }}
ArrayList() 构造一个初始容量为十的空列表=========================================private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};Object[] elementData; ->ArrayList底层的那个数组public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;} =========================================list.add("a");public boolean add(E e) { modCount++; add(e, elementData, size);// e->要存的元素 elementData->集合数组,长度开始为0,size->0 return true;}private void add(E e->元素, Object[] elementData->集合数组, int s->0) { if (s == elementData.length) elementData = grow(); elementData[s] = e; size = s + 1;}private Object[] grow() { return grow(size + 1);}private Object[] grow(int minCapacity->1) { int oldCapacity = elementData.length;//0 if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, /* minimum growth */ oldCapacity >> 1 /* preferred growth */); return elementData = Arrays.copyOf(elementData, newCapacity); } else { return elementData = new Object[Math.max(DEFAULT_CAPACITY->10, minCapacity->1)]; }}==========================================假设ArrayList中存了第11个元素,会自动扩容-> Arrays.copyOfprivate Object[] grow(int minCapacity) {//11 int oldCapacity = elementData.length;//10 if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { int newCapacity(15) = ArraysSupport.newLength(oldCapacity->10, minCapacity - oldCapacity->1, /* minimum growth */ oldCapacity >> 1 ->5 /* preferred growth */); return elementData = Arrays.copyOf(elementData, newCapacity); } else { return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)]; }} public static int newLength(int oldLength->10, int minGrowth->1, int prefGrowth->5) { // preconditions not checked because of inlining // assert oldLength >= 0 // assert minGrowth > 0 int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // 15 if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) { return prefLength; } else { // put code cold in a separate method return hugeLength(oldLength, minGrowth); }}
ArrayList(int initialCapacity) 构造具有指定初始容量的空列表
ArrayList<String> list = new ArrayList<>(5);==============================================public ArrayList(int initialCapacity->5) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity];//直接创建长度为5的数组 } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); }}
ArrayList<String> list = new ArrayList<String>() -> 现在我们想用都是new但是将来开发不会想使用就new集合,都是调用一个方法,查询出很多数据来,此方法返回一个集合,自动将查询出来的数据放到集合中,我们想在页面上展示数据,遍历集合而且将来调用方法,返回的集合类型,一般都是接口类型List<泛型> list = 对象.查询方法()
1.概述:LinkedList是List接口的实现类2.特点: a.元素有序 b.元素可重复 c.有索引 -> 这里说的有索引仅仅指的是有操作索引的方法,不代表本质上具有索引 d.线程不安全3.数据结构:双向链表 4.方法:有大量直接操作首尾元素的方法 - public void addFirst(E e):将指定元素插入此列表的开头。 - public void addLast(E e):将指定元素添加到此列表的结尾。 - public E getFirst():返回此列表的第一个元素。 - public E getLast():返回此列表的最后一个元素。 - public E removeFirst():移除并返回此列表的第一个元素。 - public E removeLast():移除并返回此列表的最后一个元素。 - public E pop():从此列表所表示的堆栈处弹出一个元素。 - public void push(E e):将元素推入此列表所表示的堆栈。 - public boolean isEmpty():如果列表没有元素,则返回true。
public class Demo05LinkedList { public static void main(String[] args) { LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("吕布"); linkedList.add("刘备"); linkedList.add("关羽"); linkedList.add("张飞"); linkedList.add("貂蝉"); System.out.println(linkedList); linkedList.addFirst("孙尚香"); System.out.println(linkedList); linkedList.addLast("董卓"); System.out.println(linkedList); System.out.println(linkedList.getFirst()); System.out.println(linkedList.getLast()); linkedList.removeFirst(); System.out.println(linkedList); linkedList.removeLast(); System.out.println(linkedList); System.out.println("======================"); Iterator<String> iterator = linkedList.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } System.out.println("======================="); for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } }}
public E pop():从此列表所表示的堆栈处弹出一个元素。public void push(E e):将元素推入此列表所表示的堆栈。
public class Demo06LinkedList { public static void main(String[] args) { LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("吕布"); linkedList.add("刘备"); linkedList.add("关羽"); linkedList.add("张飞"); linkedList.add("貂蝉"); //public E pop():从此列表所表示的堆栈处弹出一个元素。 linkedList.pop(); System.out.println(linkedList); //public void push(E e):将元素推入此列表所表示的堆栈。 linkedList.push("涛哥"); System.out.println(linkedList); }}
LinkedList<String> list = new LinkedList<>();list.add("a");list.add("b");void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++;}
public E get(int index) { checkElementIndex(index); return node(index).item;} Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; }}
index < (size >> 1)采用二分思想,先将index与长度size的一半比较,如果index<size/2,就只从位置0往后遍历到位置index处,而如果index>size/2,就只从位置size往前遍历到位置index处。这样可以减少一部分不必要的遍历
public class Demo01ForEach { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三"); list.add("李四"); list.add("王五"); list.add("赵六"); for (String s : list) { System.out.println(s); } System.out.println("====================="); int[] arr = {1,2,3,4,5}; for (int i : arr) { System.out.println(i); } }}
public class Demo01Collections { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); //static <T> boolean addAll(Collection<? super T> c, T... elements)->批量添加元素 Collections.addAll(list,"张三","李四","王五","赵六","田七","朱八"); System.out.println(list); //static void shuffle(List<?> list) ->将集合中的元素顺序打乱 Collections.shuffle(list); System.out.println(list); //static <T> void sort(List<T> list) ->将集合中的元素按照默认规则排序-> ASCII码表 ArrayList<String> list1 = new ArrayList<>(); list1.add("c.举头望明月"); list1.add("a.床前明月光"); list1.add("d.低头思故乡"); list1.add("b.疑是地上霜"); Collections.sort(list1); System.out.println(list1); }}
1.方法:static <T> void sort(List<T> list, Comparator<? super T> c)->将集合中的元素按照指定规则排序2.Comparator比较器 a.方法: int compare(T o1,T o2) o1-o2 -> 升序 o2-o1 -> 降序
public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; }}
public class Demo02Collections { public static void main(String[] args) { ArrayList<Person> list = new ArrayList<>(); list.add(new Person("柳岩",18)); list.add(new Person("涛哥",16)); list.add(new Person("金莲",20)); Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge()-o2.getAge(); } }); System.out.println(list); }}
1.接口:Comparable接口2.方法: int compareTo(T o) -> this-o (升序) o-this(降序)
public class Student implements Comparable<Student>{ private String name; private Integer score; public Student() { } public Student(String name, Integer score) { this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", score=" + score + '}'; } @Override public int compareTo(Student o) { return this.getScore()-o.getScore(); }}
public class Demo03Collections { public static void main(String[] args) { ArrayList<Student> list = new ArrayList<>(); list.add(new Student("涛哥",100)); list.add(new Student("柳岩",150)); list.add(new Student("三上",80)); Collections.sort(list); System.out.println(list); }}
public class Demo04Collections { public static void main(String[] args) { List<String> list = Arrays.asList("张三", "李四", "王五"); System.out.println(list); }}
public class Demo01Genericity { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("1"); list.add(1); list.add("abc"); list.add(2.5); list.add(true); //获取元素中为String类型的字符串长度 for (Object o : list) { String s = (String) o; System.out.println(s.length());//ClassCastException } }}
public class ListUtils { //定义一个静态方法addAll,添加多个集合的元素 public static <E> void addAll(ArrayList<E> list,E...e){ for (E element : e) { list.add(element); } }}
public class Demo03Genericity { public static void main(String[] args) { ArrayList<String> list1 = new ArrayList<>(); ListUtils.addAll(list1,"a","b","c"); System.out.println(list1); System.out.println("================"); ArrayList<Integer> list2 = new ArrayList<>(); ListUtils.addAll(list2,1,2,3,4,5); System.out.println(list2); }}
public interface MyList <E>{ public boolean add(E e);}
public class MyArrayList1<E> implements MyList<E>{ //定义一个数组,充当ArrayList底层的数组,长度直接规定为10 Object[] obj = new Object[10]; //定义size,代表集合元素个数 int size; /** * 定义一个add方法,参数类型需要和泛型类型保持一致 * * 数据类型为E 变量名随便取 */ public boolean add(E e){ obj[size] = e; size++; return true; } /** * 定义一个get方法,根据索引获取元素 */ public E get(int index){ return (E) obj[index]; } @Override public String toString() { return Arrays.toString(obj); }}
public class Demo04Genericity { public static void main(String[] args) { MyArrayList1<String> list1 = new MyArrayList1<>(); list1.add("张三"); list1.add("李四"); System.out.println(list1.get(0)); }}
public interface MyIterator <E>{ E next();}public class MyScanner implements MyIterator<String>{ @Override public String next() { return "涛哥和金莲的故事"; }}
public class Demo05Genericity { public static void main(String[] args) { MyScanner myScanner = new MyScanner(); String result = myScanner.next(); System.out.println("result = " + result); }}
static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;}8 4 2 1规则->无论指定了多少容量,最终经过tableSizeFor这个方法计算之后,都会遵循8421规则去初始化列表容量为了存取高效,尽量较少碰撞
static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next;}
public class Demo02Vector { public static void main(String[] args) { Vector<String> vector = new Vector<>(); vector.add("张三"); vector.add("李四"); for (String s : vector) { System.out.println(s); } }}
Vector底层源码分析
Vector() 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零 Vector(int initialCapacity, int capacityIncrement)使用指定的初始容量和容量增量构造一个空的向量
1.概述:字节输入流 InputStream ,是一个抽象类 子类:FileInputStream2.作用:读数据,将数据从硬盘上读到内存中来3.构造: FileInputStream(File file) FileInputStream(String path) 4.方法: int read() 一次读一个字节,返回的是读取的字节 int read(byte[] b) 一次读取一个字节数组,返回的是读取的字节个数 int read(byte[] b, int off, int len) 一次读取一个字节数组一部分,返回的是读取的字节个数 void close() 关闭资源
Exception in thread "main" java.io.IOException: Stream Closed at java.base/java.io.FileInputStream.read0(Native Method) at java.base/java.io.FileInputStream.read(FileInputStream.java:228) at com.atguigu.c_input.Demo01FileInputStream.method01(Demo01FileInputStream.java:38) at com.atguigu.c_input.Demo01FileInputStream.main(Demo01FileInputStream.java:7)
public class Demo01InputStreamReader { public static void main(String[] args)throws Exception { InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\Idea\\io\\1.txt"),"gbk"); int data = isr.read(); System.out.println((char)data); isr.close(); }}
public class Demo02OutputStreamWriter { public static void main(String[] args)throws Exception { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\Idea\\io\\1.txt"),"gbk"); osw.write("你好"); osw.close(); }}
public class Demo01PrintStream { public static void main(String[] args)throws Exception{ PrintStream ps = new PrintStream("module22\\printstream.txt"); ps.println("涛哥是一个大帅哥"); ps.println("涛哥是一个小鲜肉"); ps.println("涛哥和金莲不为人知的故事"); ps.close(); }}
public class Demo01Properties { public static void main(String[] args) { Properties properties = new Properties(); properties.setProperty("username","root"); properties.setProperty("password","1234"); Set<String> set = properties.stringPropertyNames(); for (String key : set) { System.out.println(properties.getProperty(key)); } }}
public class Demo02Properties { public static void main(String[] args)throws Exception { Properties properties = new Properties(); FileInputStream fis = new FileInputStream("module22\\jdbc.properties"); properties.load(fis); Set<String> set = properties.stringPropertyNames(); for (String key : set) { System.out.println(key+"..."+properties.getProperty(key)); } }}
public class Receive { public static void main(String[] args) throws Exception{ //1.创建DatagramSocket对象,指定服务端的端口号 DatagramSocket socket = new DatagramSocket(6666); //2.接收数据包 byte[] bytes = new byte[1024];//用于保存接收过来的数据 DatagramPacket dp = new DatagramPacket(bytes, bytes.length); socket.receive(dp); //3.解析数据包 byte[] data = dp.getData();//接收的数据 int len = dp.getLength();//从数据包中获取多少个数据 InetAddress address = dp.getAddress();//获取发送端的主机 int port = dp.getPort();//发送端的端口号 System.out.println(new String(data,0,len)); System.out.println(address+"..."+port); //4.释放资源 socket.close(); }}
public class Client { public static void main(String[] args)throws Exception { //1.创建Socket对象,指明服务端的ip以及端口号 Socket socket = new Socket("127.0.0.1", 6666); //2.调用socket中的getOutputStream,往服务端发送请求 OutputStream os = socket.getOutputStream(); os.write("我想下载一个小电影".getBytes()); //3.调用socket中的getInputStream,读取服务端响应回来的数据 InputStream is = socket.getInputStream(); byte[] bytes = new byte[1024]; int len = is.read(bytes); System.out.println(new String(bytes,0,len)); //4.关流 is.close(); os.close(); socket.close(); }}
public class Server { public static void main(String[] args)throws Exception { //1.创建ServerSocket对象,设置端口号 ServerSocket ss = new ServerSocket(6666); //2.调用ServerSocket中的accept方法,等待客户端连接,返回Socket对象 Socket socket = ss.accept(); //3.调用socket中的getInputStream,用于读取客户端发送过来的数据 InputStream is = socket.getInputStream(); byte[] bytes = new byte[1024]; int len = is.read(bytes); System.out.println(new String(bytes,0,len)); //4.调用socket中的getOutputStream,用于给客户端响应数据 OutputStream os = socket.getOutputStream(); os.write("给你一个小电影".getBytes()); //5.关闭资源 os.close(); is.close(); socket.close(); ss.close(); }}
public class Person { @Deprecated public void eat(){ System.out.println("人要吃饭"); }}
@SuppressWarnings("all")public class Test01 { public static void main(String[] args) { Person person = new Person(); person.eat(); System.out.println("================"); ArrayList list = new ArrayList(); list.add(1); }}
public class Test01 { public static void main(String[] args) { //1.获取BookShelf的class对象 Class<BookShelf> bookShelfClass = BookShelf.class; //2.判断bookShelf上有没有Book注解 boolean b = bookShelfClass.isAnnotationPresent(Book.class); //3.判断,如果b为true,就获取 if (b){ Book book = bookShelfClass.getAnnotation(Book.class); System.out.println(book.bookName()); System.out.println(Arrays.toString(book.author())); System.out.println(book.price()); System.out.println(book.count()); } }}
public class Demo01Junit { @Test public void add(){ System.out.println("我是@Test执行的add方法"); } @Test public void delete(){ System.out.println("我是@Test执行的delete方法"); }}
public enum State { //State WEIFUKUAN = new State() //State WEIFUKUAN = new State("未付款") WEIFUKUAN("未付款"), //State YIFUKUAN = new State() //State YIFUKUAN = new State("已付款") YIFUKUAN("已付款"), //State WEIFAHUO = new State() //State WEIFAHUO = new State("未发货") WEIFAHUO("未发货"), //State YIFAHUO = new State() //State YIFAHUO = new State("已发货") YIFAHUO("已发货"); private String name; private State() { } State(String name) { this.name = name; } public String getName() { return name; }}
public class Test01 { public static void main(String[] args) { State weifahuo = State.WEIFAHUO; System.out.println(weifahuo);//默认调用toString State yifukuan = State.YIFUKUAN; System.out.println(yifukuan.getName()); }}