1.Scanner用法
Scanner sc = new Scanner(System.in); //创建键盘录入 System.out.println("请输入一个整数"); //将键盘录入的数据存储到x中 int x = sc.nextInt(); System.out.println(x);
练习:输入两个值,并将最大值输出
Scanner sc = new Scanner(System.in); System.out.println("请输入第一个整数"); int x = sc.nextInt(); System.out.print("请输入第二个整数"); int y = sc.nextInt(); int temp = (x>y) ? x:y; System.out.println(temp);
2.进制
1 byte = 8bit
1 k = 1024b(m、g、t以此类推)
二进制:0和1组成, 以0b开头
八进制:有0-7组成, 以0开头
十六进制:有0-9,a-f组成, 以0x开头
原码
二进制定点表示法,最高位位符号位,“0”表示正,“1”表示负,其余为数值的大小
00000111 (+7)
10000111 (-7)
11111000 (-7反码)
11111001 (-7补码)
反码:正数的反码与其原码相同,负数的反码是对其原码诸位取反,符号位除外
补码:正数的补码与其原码相同,负数的补码是对其反码的末位加1
3.数据类型
基本数据类型
整数型:
byte 1个字节 -128-127
short 2个字节
int 4个字节
long 8个字节
浮点型:
float 4个字节
double 8个字节
字符型:
char 2个字节
布尔型:
boolean 理论上1/8字节,java没有明确定义大小
变量与常量区别:
byte b1 = 3;
byte b2 = 4;
//1.数值默认都是int byte和byte(或short,char)进行运算时都会提升为int,两个int相加结果为int类型
//2.b1和b2是两个变量,变量存储的值是变化的,在编译的时候无法判断里面具体的值,相加会超过byte取值范围
byte b3 = b1+b2; //编译出错
//java编译器有常量优化机制,编译时知道值,判断3+4没超过byte值
byte b4 = 3+4; //正确
引用数据类型
3.流程控制
顺序结构
选择结构
if
int x = 10;
switch(表达式){
case 值1:
语句体1;
break;
....
default;
语句体n;
break;
}
for(){
}
while(){
}
do{
循环体语句;
控制条件语句;
}while(判断条件语句);
三者的不同:
do...while:循环至少执行一次循环体
for循环:变量会及早的从内存中释放
while循环:变量不会释放
4.控制跳转语句标号
a:for(int i=1;i<= 10;i++){ //a就是标号,只要是合法的标识符即可 System.out.println("i="+i); b:for(int j=1;j<=10;j++){ System.out.println("j="+j); break a; //结束a循环,直接break就只结束b循环 } }
break用于switch和循环(结束整个循环)
continue用于循环(结束本次循环,进行下次循环)
return (结束方法)
5.方法
格式:修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数2...){
方法体语句;
return 返回值;
}
方法重载:方法名相同,参数列表不同,与返回值类型无关
重载的分类:
1.参数个数不同
2.参数类型不同
3.参数顺序不同
public static void main(String[] args) { double sum1 = add(10,37); int sum2 = add(12,34,56); double sum3 = add(12.4,45.3); System.out.println(sum1); System.out.println(sum2); System.out.println(sum3); } public static double add(int a ,int b){ return a+b; } public static int add(int a,int b,int c){ return a+b+c; } public static double add(double a,double b){ return a+b; }
6.数组
数据类型[ ] 数组名 = new 数据类型[数组的长度] ;
默认初始化值:
整数类型:byte、 short 、int 、long 默认是0
float、double 默认是0.0
布尔型:boolean 默认是false
字符:char 默认‘u0000’ (char在内存占两个字节,16个二进制,
每个0代表是16进制的0,16进制1位代表4个二进制位,‘u0000’总共16个二进制)
静态初始化格式:数据类型[ ] 数组名 = new 数据类型[ ]{ 元素1,元素2....}
数据类型[ ] 数据名 = {元素1,元素2...}
public static void main(String[] args) { int[] arr = {11,33,55,22,66}; int max = getMax(arr); System.out.println(max); reverseArraly(arr); print(arr); } //获取数组最大值 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 static void reverseArraly(int[] arr){ for(int i=0;i<arr.length/2;i++){ int temp = arr[i]; arr[i] = arr[arr.length-1-i]; arr[arr.length-1-i] = temp; } } //遍历数组 public static void print(int[] arr){ for(int i=0;i<arr.length;i++){ System.out.print(arr[i]); } }
7.内存分配
栈:存储局部变量
堆:存储new出来的数组或对象
方法区
本地方法区:和系统有关
寄存器:给cpu使用
. 一个数组的内存图
8.面向对象
面向对象特征:
封装
继承
多态
9.成员变量和局部变量
成员变量:堆内存、随着对象创建而存在,随着对象消失而消失、有默认初始化值
局部变量:栈内存、随着方法调用而存在,随着方法的调用完毕而消失、没有默认初始化值,必须定义
10.封装
原则:把属性隐藏,提供公共方法对其访问
private :被修饰的成员只能在本类中使用
this :表示当前类的对象引用(当前类的一个对象)
11.构造方法
方法名与类名相同,没有返回值(包括void)-----给对象数据进行初始化
注意:没有给出构造方法,系统将自动提供一个无参构造方法
给出了构造方法,系统将不再提供默认的无参构造方法,如果我们还想使用无参构造方法,就必须自己给出
构造方法重载:
给成员变量赋值两种方法:setXXX() 构造方法
public class StudentMethod { private String name; private int age; public StudentMethod(){ System.out.println("这是无参构造方法"); } public StudentMethod(String name){ System.out.println("这是个带一个String类型的构造方法"); this.name = name; } public StudentMethod(String name, int age){ System.out.println("这是个带多个参数的构造方法"); this.name = name; this.age = age; } public void show(){ System.out.println(name+"----"+age); } } public class StudentMethodTest { public static void main(String[] argus){ StudentMethod sm = new StudentMethod(); sm.show(); //结果: 这是无参构造方法 null----0 StudentMethod sm1 = new StudentMethod("张三"); sm1.show(); //结果: 这是个带一个String类型的构造方法 张三----0 StudentMethod sm2 = new StudentMethod("李四",12); sm2.show(); //结果:这是个带多个参数的构造方法 李四----12 } }
12.static
多个对象相同的成员变量(被所有对象共享)
可以通过类名调用,本身也可以通过对象调用
注意事项:
1. 在静态方法中是没有this关键字的(静态是随着类的加载而加载,
this是随着对象的创建而存在,静态比对象先存在)
2. 静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法
非静态方法:
成员变量:可以是静态变量,也可以是非静态变量
成员方法:可以是静态的成员方法,也可以是非静态的成员方法
13. 继承
注意事项:
a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
b:子类不能继承父类的构造方法,可以通过super关键字去访问父类构造方法
c:不要为了部分功能而去继承
继承具有就近原则,子类有就不用父类的
this和super的区别:
this:当前对象的引用
super:当前对象父类的引用
成员变量:
this:调用本类的成员变量,也可以调用父类的成员变量
super:调用父类的成员变量
public class Father { int num1 = 10; int num2 = 30; private String name; private int age; public Father(){ System.out.println("Father 空参构造"); } public Father(String name,int age){ this.name = name; this.age = age; System.out.println("Father 有参构造"); } 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 Son extends Father { int num2 = 20; public void print(){ System.out.println(this.num1); //10 this既可以调用本类的,也可以调用父类的(本类没有的情况下) System.out.println(this.num2); //20 就近原则,子类有就不用父类的 System.out.println(super.num2); //30 super调用父类 } public Son(){ //此处隐藏 super() 将父类的无参构造方法注释 将报错 System.out.println("son 空参构造"); } public Son(String name,int age){ //此处隐藏 super() 将父类的无参构造方法注释 将报错 super(name,age); //调用父类有参构造方法 System.out.println("Son 有参构造"); } } public static void main(String[] args) { Son s = new Son(); s.print(); Son s1 = new Son(); //输出 :Father空参构造 son空参构造 System.out.println("-------"); Son s2 = new Son("张三",33); //Father空参构造 Son有参构造 System.out.println(s2.getName()+"...."+s2.getAge()); //张三....33 }
重写:当子类需要父类的功能,而功能主体子类有自己特有内容,可以重写父类方法
注意事项:
a. 父类中私有方法不能被重写
b.子类重写父类方法是,访问权限不能更低
c.父类静态方法,子类也必须通过静态方法重写
final:
修饰类:类不能被继承
修饰变量:变量变成常量,只能被赋值一次
修饰方法:方法不能被重写
14.多态
事物存在的多种形态
多态前提:要有继承关系、要有方法重写、要有父类引用指向子类对象
1.多态中成员访问特点之成员变量
2.多态中的成员访问特点之成员方法
3.多态中的成员访问特点之静态成员方法
public class Father { int num=10; public void print(){ System.out.println("father"); } public static void method(){ System.out.println("father static method"); } } public class Son extends Father{ int num = 20; public void print(){ System.out.println("son"); } public static void method(){ System.out.println("son static method"); } } public class Test1 { public static void main(String[] args) { //多态中成员访问特点之成员变量 Father f = new Son(); //父类引用指向子类对象 System.out.println(f.num); //结果:10 输出的是父类的成员变量 (编译看左边,运行看左边) Son s = new Son(); System.out.println(s.num); //结果:20 调自己成员变量 (编译看左边,运行看左边) //多态中的成员访问特点之成员方法 Father f1 = new Son(); f1.print(); //结果:son (编译看左边,运行看右边) //多态中的成员访问特点之静态成员方法 Father f2 = new Son(); f2.method(); //结果:father static method(相当于是Father.method 编译看左边,运行看左边) } }
4.多态中向上转型和向下转型
多态
instanseof :判断前边的引用是否是后边的数据类型
抽象类(abstract):
抽象类和抽象方法必须用abstract关键字修饰:
abstract class 类名{ }
public abstract void eat();
抽象不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
抽象类不能被实例化
抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法
抽象类成员特点:
a:成员变量:既可以是变量,也可以是常量(abstract不可以修饰成员变量)
b:构造方法:有
用于子类访问父类的初始化
c:成员方法:既可以是抽象的,也可以是非抽象的
一个抽象类没有抽象方法,是可以定义为抽象类(意义:定义为抽象不让该类被实例化)
abstract和static不能共存:abstract修饰的方法没有方法体,被static修饰的可以用类名.调用,但是类名.调用没有意义的
abstract和final不能共存:被abstract修饰的方法强制子类重写,被final修饰的不让子类重写
abstract和private不能共存:同理final
15.接口
对外提供规则的都是接口
interface 接口名{}
类实现接口implements 表示:class 类名 implements 接口名{ }
接口不能实例化
接口的子类:可以是抽象类,但意义不大,可以是具体类,要重写接口中所有抽象方法
public interface Inter { public abstract void print(); //接口中的方法都是抽象的 } public class Demo implements Inter{ @Override public void print() { // TODO Auto-generated method stub } } public class DemoTest { public static void main(String[] args) { //Inter i = new Inter(); //接口不能被实例化,因为调用抽象方法没有意义 Inter i = new Demo(); //父类引用指向子类对象 i.print(); } }
成员变量:只能是常量,并且是静态的并公共的
默认修饰符:public static final
构造方法:没有
成员方法:只能是抽象方法
默认修饰符:public abstract
public interface Inter { int num =10; //默认下面的 //public static final int num = 10; //一般写法 public void print(); } public class Demo implements Inter{ @Override public void print() { //num = 20; //错误,接口定义的成员变量是常量 System.out.println(num); } } public class DemoTest { public static void main(String[] args) { Demo d = new Demo(); d.print(); //输出10 System.out.println(Inter.num); } }
设计理念区别:
抽象类:抽象类中定义的是该继承体系的共性功能
接口: 接口中定义的是该继承体系的扩展功能
//测试类 public class Test { /** * 动物类:姓名,年龄,吃饭,睡觉 * 猫和狗 * 动物培训接口:跳高 */ public static void main(String[] args) { Cat cat = new Cat("加菲",8); cat.eat(); //猫吃鱼 cat.sleep(); //猫睡觉 JumpCat jc = new JumpCat(); jc.eat(); //猫吃鱼 jc.sleep(); //猫睡觉 jc.jump(); //猫跳高 } } //动物类 public abstract class Animal { private String name; private int age; //空参构造 public Animal(){ } //有参构造 public Animal(String name,int age){ this.name = name; this.age = age; } public abstract void eat(); //吃饭 public abstract void sleep();//睡觉 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 interface Jump { public void jump(); } //猫类 public class Cat extends Animal{ //空参构造 public Cat(){ } //有参构造 public Cat(String name,int age){ super(name,age); } @Override public void eat() { System.out.println("猫吃鱼"); } @Override public void sleep() { System.out.println("猫睡觉"); } } //跳高猫类 public class JumpCat extends Cat implements Jump{ @Override public void jump() { System.out.println("猫跳高"); } }
16.四种权限修饰符
本类 同一个包下(子类和无子类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
17.String、StringBuffer、StringBuild
String
字符串面值“abc”看成是一个字符串对象
字符串是一个常量,一旦被赋值,不能被改变
不可变得字符序列
StringBuffer
线程安全的可变字符序列,效率低
StringBuild
线程不安全的可变字符序列,效率高
String类虽然是引用数据类型,但是当作参数传递时和基本类型是一样的(不改变其值)
StringBuffer 作为参数传递,改变值
/** * 数组高级冒泡排序: * 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
* 第一次:arr[0]与arr[1],arr[1]与arr[2],arr[2]与arr[3],arr[3]与arr[4]比较4次
* 第二次:arr[0]与arr[1],arr[1]与arr[2],arr[2]与arr[3]比较3次
* 第三次:arr[0]与arr[1],arr[1]与arr[2]比较2次
* 第四次:arr[0]与arr[1]比较1次
*/ public class StringDemo { public static void main(String[] args){ int[] arr ={24,69,80,57,13}; maopao(arr); for(int i=0;i<arr.length;i++){ System.out.print(arr[i]+" "); } } public static void maopao(int[] arr){ for(int i=0;i<arr.length -1;i++){ for(int j=0;j<arr.length-1-i ;j++){ // -i为了提高效率 if(arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } }
/** * 选择排序: * 用一个索引位置上的元素,依次与其他索引位置上的元素比较,小在前面大的在后面 * 第一次:arr[0]分别与arr[1-4]比较,比较4次 * 第二次:arr[1]分别与arr[2-4]比较,比较3次 * 第三次:arr[2]分别与arr[3-4]比较,比较2次 * 第四次:arr[3]与arr[4]比较,比较1次 */ public static void main(String[] args) { int[] arr = {24,69,80,57,13}; xuanze(arr); for(int i=0;i<arr.length;i++){ System.out.print(arr[i]+" "); } } public static void xuanze(int[] arr){ for(int i=0;i<arr.length-1;i++){ for(int j=1+i;j<arr.length;j++){ if(arr[i] > arr[j]){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } }
/** * 二分查找;(前提元素有序) * */ public static void main(String[] args) { int[] arr = {11,22,33,44,55,66}; System.out.println(getIndex(arr,44)); } public static int getIndex(int[] arr ,int value){ int min =0; int max = arr.length-1; int mid = (min + max)/2; while(arr[mid] != value){ //当中间值不等于要找的值,就开始循环查找 if(arr[mid] < value){//当中间值小于要找的值 min = mid +1; //最小的索引改变 }else if(arr[mid] > value){//当中间值大于要找的值 max = mid -1; //最大的索引改变 } mid =(min + max)/2; //无论最大最小改变,中间索引都会随之改变 if(min > max){ return -1; } } return mid; }
18.Arrays类
public static void main(String[] args) { int[] arr ={33,22,11,44,66,55}; System.out.println(Arrays.toString(arr));//数组转字符串 Arrays.sort(arr); //排序数组 System.out.println(Arrays.toString(arr)); int[] arr2 = {11,22,33,44,55,66}; System.out.println(Arrays.binarySearch(arr2, 44)); //查找元素位置(二分查找法) }
17.集合
//collection集合 一些方法 Collection c = new ArrayList(); //父类引用子类对象 c.add("ssss"); c.add(true); //自动装箱new Boolean(true) c.add(100); c.add(new Student()); System.out.println(c); //[ssss, true, 100, collection.Student@42d73fb7] c.remove("ssss"); System.out.println(c);//[true, 100, collection.Student@6cd737e3] boolean b =c.contains(100); System.out.println(b); //true 是否包含 System.out.println(c.size()); //获取元素个数 c.clear(); System.out.println(c);//[] System.out.println(c.isEmpty()); //true 是否为空 //collection集合转数组 Collection c1 = new ArrayList(); //父类引用子类对象 c1.add("2"); c1.add("1"); Object[] arr = c1.toArray(); for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } //collection集合带All的方法 Collection c2 = new ArrayList(); //父类引用子类对象 c2.add("aa"); c2.add("bb"); Collection c3= new ArrayList(); //父类引用子类对象 c3.add("aa"); c3.add("cc"); c3.add("dd"); c2.addAll(c3); System.out.println(c2);//[aa, bb, aa, cc, dd] c2.removeAll(c3); System.out.println(c2);//[bb] //删除的是交集 System.out.println(c2.containsAll(c3)); //false判断是否包含 c2.retainAll(c3); System.out.println(c2); //取交集 //迭代 Collection c4= new ArrayList(); //父类引用子类对象 c4.add("aa"); c4.add("cc"); c4.add("dd"); Iterator it = c4.iterator(); //获取迭代器 /*boolean b1 = it.hasNext(); //判断集合是否有元素 Object obj = it.next();*/ while(it.hasNext()){ System.out.println(it.next()); }
18.集合框架(数据结构之数组和链表)
数组:查询和修改快
增删慢
链表:查询和修改慢
增删快
List三个子类特点:
ArrayList:底层数据结构是数组,查询快,增删慢
线程不安全,效率高
Vector(向量):底层数据结构是数组,查询快,增删慢
线程安全,效率低
LinkedList:底层结构是链表,查询慢,增删快
线程不安全,效率高
/** * 数组转集合 */ public static void main(String[] args) { String[] arr = {"a","b","c"}; List<String> list = Arrays.asList(arr); //list.add("d"); 不能增加 System.out.print(list); }
/** * 集合转数组 */ public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); String[] arr = list.toArray(new String[0]); //当集合转换数组时,数组的长度如果是小于等于集合的size //转换后的数组长度等于size,如果大于集合size,分配的数组的长度就是指定的长度 for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } }
19.set
HashSet:无索引、不可以重复、存取不一致
LinkedHashSet:可以保证怎么存怎么取,其他属性同HashSet
TreeSet:可以排序(自然排序),其他同HashSet
20.Map
HashMap和Hashtable
共同点:底层都是哈希算法,都是双列集合
不同点:1.HashMap是线程不安全的,效率高
Hashtable是线程安全的,效率低
2.HashMap可以存储nul键和null值
Hashtable不能存储nul键和null值
21.File
/** * File(String pathname):根据一个路径得到File对象 * File(String parent,String child):根据一个目录和一个子文件/目录得到File对象 * File(File parent,String child):根据一个父File对象和一个子文件/目录得到File对象 */ public static void main(String[] args) { File file = new File("C:\Notepad++\localization\chineseSimplified.xml"); System.out.println(file.exists()); String parent = "C:\Notepad++\localization"; String child = "chineseSimplified.xml"; File file1 = new File(parent,child); System.out.println(file1.exists()); File parentFile = new File("C:\Notepad++\localization"); String child1 = "chineseSimplified.xml"; File file2 = new File(parentFile,child1); System.out.println(file2.exists()); }
/** * 创建功能 * Public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了 * public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了 * public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来 * 案列演示: * File类的创建功能 * 注意事项:如果创建文件或文件夹忘写盘路径,那么默认在项目路径下 */ public static void main(String[] args) throws IOException { File file = new File("xxx.txt"); //默认创建在项目下 file.createNewFile(); File file2 = new File("aaa"); System.out.println(file2.mkdir()); File file3 = new File("ccc\ddd"); System.out.println(file3.mkdirs()); //创建多级目录 }
/** * 重命名注意事项: * 如果路径名相同,就是改名,不同就是改名并剪切 * 删除注意事项: * java删除不走回收站 * 要删除一个文件夹,注意该文件夹不能包含文件或者文件夹 */ public static void main(String[] args) { File file1 = new File("xxx.txt"); File file2 = new File("ooo.txt"); file1.renameTo(file2); //把文件重命名为指定的文件路径 File file3= new File("zzz"); file3.delete(); //删除文件 }
public static void main(String[] args) { File file1 = new File("ccc"); System.out.println(file1.isDirectory()); //判断是都是一个文件夹 File file2 = new File("ooo.txt"); System.out.println(file2.isFile()); //判断是否是文件 File file3 = new File("eee"); System.out.println(file3.exists()); //判断是否存在 File file4 = new File("ooo.txt"); file4.setReadable(false); System.out.println(file4.canRead()); //判断是否可读 System.out.println(file4.canWrite()); //判断是否可写(window系统默认所有文件都是可读的) System.out.println(file4.isHidden()); //判断是否隐藏 }
public static void main(String[] args) { File file1 = new File("ooo.txt"); System.out.println(file1.getAbsolutePath()); //D:myworkspacedemoooo.txt 获取绝对路径 File file2 = new File("ooo.txt"); File file3 = new File("D:\myworkspace\demo\ooo.txt"); System.out.println(file2.getPath()); //ooo.txt 获取构造方法传入的路径 System.out.println(file3.getPath()); //D:myworkspacedemoooo.txt 获取构造方法传入的路径 System.out.println(file2.getName()); //ooo.txt 获取文件或者文件夹的名称 System.out.println(file2.length()); //获取长度,字节数 System.out.println(file2.lastModified()); //获取最后一次的修改时间(毫秒数) }
public static void main(String[] args) { File dir = new File("D:\Notepad++"); String[] arr = dir.list(); //仅为了获取文件名 for (String string : arr) { System.out.println(string); } File[] subFiles = dir.listFiles(); //获取文件对象 for (File file : subFiles) { System.out.println(file); } }
22.IO流
1.字节流
public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象 int x = fis.read(); //从硬盘上读取一个字节 System.out.println(x); fis.close(); //关流释放资源 }
/** * FileOutputStream在创建对象时如果没有这个文件会创建出来,如果有这个文件会将文件清空 */ public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("yyy.txt"); //创建字节输出流对象, fos.write(98); fos.close(); FileOutputStream fos1 = new FileOutputStream("yyy.txt",true); //如果想续写就在第二个参数传一个true fos1.write(99); fos1.close(); }
/** * 一个一个字节读取和写 */ public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("C:\Users\wisdytech\Pictures\Screenshots\屏幕截图(1).png"); //创建输入流对象 FileOutputStream fos = new FileOutputStream("copy.png"); //创建输出流对象 int b; while((b=fis.read()) != -1){ //不断读取每一个字节 fos.write(b); //将每个字节写出 } fis.close(); fos.close(); }
/** * 不推荐使用,因为可能会导致内存溢出 */ public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("C:\Users\wisdytech\Pictures\Screenshots\屏幕截图(1).png"); //创建输入流对象 FileOutputStream fos = new FileOutputStream("copy1.png"); //创建输出流对象 byte[] arr = new byte[fis.available()]; //创建与文件一样大小的字节数组 fis.read(arr); //将文件上的字节读取到内存中 fos.write(arr); //将字节数组中的字节数据写到文件中 fis.close(); fos.close(); }
/** * 定义小数组(拷贝) * @throws IOException */ public static void main(String[] args) throws IOException { //demo1(); FileInputStream fis = new FileInputStream("yyy.txt"); FileOutputStream fos = new FileOutputStream("zzz.txt"); byte[] arr = new byte[2]; int len; while((len = fis.read(arr)) != -1){ fos.write(arr,0,len); } fis.close(); fos.close(); } public static void demo1() throws IOException{ FileInputStream fis = new FileInputStream("yyy.txt"); byte[] arr = new byte[2]; int a = fis.read(arr); //将文件上的字节读取到字节数组中 System.out.println(a); // 2 for(byte b:arr){ System.out.println(b); //97 98 } int c = fis.read(arr); System.out.println(c); // 1 for(byte b:arr){ System.out.println(b); // 99 98 } fis.close(); }
/** * BufferedInputStream和BufferedOutputStream进行copy */ public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("yyy.txt"); //创建输入流对象 FileOutputStream fos = new FileOutputStream("zzz.txt"); //创建输出流对象 BufferedInputStream bis = new BufferedInputStream(fis); //创建缓冲区对象,对输入流进行包装,使其变得更强大 BufferedOutputStream bos = new BufferedOutputStream(fos); int b; while((b = bis.read()) != -1){ bos.write(b); } bis.close(); bos.close(); }
close和flush区别
close()方法:具备刷新功能,在关闭流之前,就会先刷新一次缓冲区,将缓冲区的字节全部刷新到文件上,
在关闭,刷完之后就不能再写了
flush()方法:具备刷新功能,刷完之后还可以继续写
/** * 字节流读取中文: * 字节流在读取中文时可能读到半个字节,导致乱码 * 字节流写出中文的问题: * 字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组 * 写出回车换行write(" ".getBytes()) * @throws IOException */ public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("xxx.txt"); fos.write("我读书少,你不要骗我".getBytes()); fos.write(" ".getBytes()); fos.close(); } public static void demo1() throws IOException{ FileInputStream fis = new FileInputStream("xxx.txt"); byte[] arr = new byte[3]; int len; while((len = fis.read(arr)) != -1){ System.out.println(new String(arr,0,len)); } fis.close(); }
2.字符流
/** * 读 */ public static void main(String[] args) throws IOException { //demo1(); FileReader fr = new FileReader("zzz.txt"); int x; while((x = fr.read()) != -1 ){ char c =(char)x; System.out.print(c); } fr.close(); } public static void demo1() throws IOException{ FileReader fr = new FileReader("zzz.txt"); int x = fr.read(); char c =(char)x; System.out.println(c); fr.close(); }
/** * 写 */ public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("aaa.txt"); fw.write("好好学习,天天向上"); fw.write(97); fw.close(); }
/** * 带缓冲区的字符流(BufferedReader和BufferedWriter) */ public static void main(String[] args) throws IOException { //demo1(); //demo2(); BufferedReader br = new BufferedReader(new FileReader("xxx.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("ccc.txt")); int c; while((c = br.read()) != -1){ bw.write(c); } br.close(); bw.close(); } /** * 字符流不可以拷贝非纯文本的文件 */ public static void demo1() throws IOException{ FileReader fr = new FileReader("xxx.txt"); FileWriter fw = new FileWriter("ccc.txt"); int x; while((x = fr.read()) != -1){ fw.write(x); } fr.close(); fw.close(); } /** * 自定义字符数组拷贝 */ public static void demo2() throws IOException{ FileReader fr = new FileReader("xxx.txt"); FileWriter fw = new FileWriter("ddd.txt"); char[] arr = new char[1024*8]; int len; while((len = fr.read(arr)) != -1){ //将文件上的数据读取到字符数组中 fw.write(arr,0,len); //将字符数组中的数据写到文件上 } fw.close(); }
/** * 带缓冲区的流中的特殊方法 * readLine() 整行读取(效率更高) * newLine() * * newLine()与 区别 * newLine()是跨平台的方法 * 只支持window系统 * @throws IOException */ public static void main(String[] args) throws IOException { //demo(); BufferedReader br = new BufferedReader(new FileReader("xxx.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("ccc.txt")); String line; while((line = br.readLine()) != null){ bw.write(line); //bw.newLine(); //写出回车换行符 bw.write(" "); } bw.close(); } public static void demo() throws IOException{ BufferedReader br = new BufferedReader(new FileReader("xxx.txt")); String line; while((line = br.readLine()) != null){ System.out.println(line); } br.close(); }
/** * 将一个文本档上的文本反转 * @throws IOException */ public static void main(String[] args) throws IOException { //1。创建输入输出流 BufferedReader br = new BufferedReader(new FileReader("xxx.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); //2.创建集合对象 List<String> list = new ArrayList<>(); //3.将读取的数据存储在集合中 String line; while((line = br.readLine()) != null){ list.add(line); } //4.倒着遍历集合将数据写到文件上 for(int i=list.size()-1;i>=0;i--){ bw.write(list.get(i)); bw.newLine(); } bw.close(); br.close(); }
/** * 增加行号读取 * */ public static void main(String[] args) throws IOException { LineNumberReader lnr = new LineNumberReader(new FileReader("xxx.txt")); String line; lnr.setLineNumber(100); while((line = lnr.readLine()) != null){ System.out.println(lnr.getLineNumber() + ":" + line); } lnr.close(); }
public class Wrap { /** * 装饰设计模式 * 耦合性不强,被装饰的类的变化与装饰类的变化无关 */ public static void main(String[] args) { HeiMaStudent hms = new HeiMaStudent(new Student()); hms.code(); } } interface Coder{ public void code(); } class Student implements Coder{ @Override public void code() { System.out.println("javase"); System.out.println("javaweb"); } } class HeiMaStudent implements Coder{ //1.获取被装饰类的引用 private Student s; //获取学生引用 //2.在构造方法中传入被装饰类的对象 public HeiMaStudent(Student s){ this.s =s; } //3.对原有的功能进行升级 @Override public void code() { s.code(); System.out.println("ssh"); System.out.println("数据库"); System.out.println("大数据"); System.out.println("..."); } }
/** * 高效使用指定编码表读写 */ public static void main(String[] args) throws IOException { //demo1(); //demo2(); BufferedReader br = //更高效的读 new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8")); BufferedWriter bw = //更高效的写 new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk")); int c; while((c = br.read()) != -1){ bw.write(c); } bw.close(); } /** * 用默认编码表读写。出现乱码 */ public static void demo1() throws IOException{ //用默认编码表读写。出现乱码 FileReader fr = new FileReader("utf-8.txt"); FileWriter fw = new FileWriter("gbk.txt"); int c; while((c = fr.read()) != -1){ fw.write(c); } fw.close(); } /** * 用指定编码表读写 */ public static void demo2() throws IOException{ //指定码表读字符 InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8"); //指定码表写字符 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk"); int c; while((c = isr.read()) != -1){ osw.write(c); } osw.close(); }
转换流图解
/** * 获取文本上每个字符出现的次数,将结果写在time。txt上 * @throws IOException */ public static void main(String[] args) throws IOException { //1.创建带缓冲的输入流对象 BufferedReader br = new BufferedReader(new FileReader("xxx.txt")); //2.创建双列集合对象TreeMap TreeMap<Character, Integer> tm = new TreeMap<>(); //3.将读到的字符串存储到双列集合中,存储时要判断,如果不包含这个键,将键和1存储,如果包含这个键,将该键和值加1存储 int ch; while((ch = br.read()) != -1){ char c = (char)ch; //向下强转 /*if(! tm.containsKey(c)){ tm.put(c, 1); }else{ tm.put(c, tm.get(c) + 1); }*/ tm.put(c, ! tm.containsKey(c) ? 1:tm.get(c) + 1); } //4.关闭输入流 br.close(); //5.创建输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt")); //6.遍历集合将集合中的内容写到time.txt中 for(Character key :tm.keySet()){ switch (key) { case ' ': bw.write("\t" + "=" + tm.get(key)); break; case ' ': bw.write("\n" + "=" + tm.get(key)); break; case ' ': bw.write("\r" + "=" + tm.get(key)); break; default: bw.write(key + "=" + tm.get(key)); break; } bw.newLine(); } //7.关闭输出流 bw.close(); }
/** * 试用版软件,试用10次,次数到了购买正版 */ public static void main(String[] args) throws IOException { //1.创建带缓冲的输入流对象,要使用readLine方法,保证数据的原样性 BufferedReader br = new BufferedReader(new FileReader("config.txt")); //2.将读到的字符串转为int数 String line = br.readLine(); int times = Integer.valueOf(line); //3.对int数进行判断,如果大于0,将其--写回去,如果不大于0,就提示请购买正版 if(times > 0){ //4.在if判断中将--的结构打印,并将结果通过输出流写到文件上 System.out.println("您还有"+times--+"次机会"); FileWriter fw = new FileWriter("config.txt"); fw.write(times+""); fw.close(); }else{ System.out.println("您的试用次数已到"); } br.close(); }
递归:
/** * 递归:方法自己调用自己 * 实现5的阶乘 */ public static void main(String[] args) { int sum = fun(5); System.out.println(sum); } public static int fun(int num){ if(num == 1){ return 1; }else { return num*fun(num-1); } }
/** * 从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名 * 分析: * 从键盘接收一个文件夹路径 * 1.如果录入的是不存在,给与提示 * 2.如果录入的是文件路径,给与提示 * 3.如果是文件夹路径,直接返回 * 打印出该文件夹下所有的.java文件名 * 1.获取到该文件夹路径下的所有文件和文件夹,存储在File数组中 * 2.遍历数组,对每一个文件或文件夹做判断 * 3.如果是文件,并且后缀是。java就打印 * 4.如果是文件夹,就递归调用 * */ public static void main(String[] args) { File fir = getDir(); getJavaFile(fir); } /** * 键盘录入获取文件夹 */ public static File getDir(){ Scanner sc = new Scanner(System.in); System.out.println("请输入路径"); while(true){ String line = sc.nextLine(); File fir = new File(line); if(! fir.exists()){ System.out.println("输入的路径不存在"); }else if(fir.isFile()){ System.out.println("输入路径不是文件夹路径"); }else{ return fir; } } } /** * 获取所有.java文件 */ public static void getJavaFile(File fir){ //1.获取到该文件夹路径下的所有文件和文件夹,存储在File数组中 File[] fileArr = fir.listFiles(); //2.遍历数组,对每一个文件或文件夹做判断 for(File subFil:fileArr){ //3.如果是文件,并且后缀是。java就打印 if(subFil.isFile() && subFil.getName().endsWith(".java")){ System.out.println(subFil); //4.如果是文件夹,就递归调用 }else if(subFil.isDirectory()){ getJavaFile(subFil); } } }
线程
public class Thread_Demo { /** * Thread */ public static void main(String[] args) { MyThread mt = new MyThread(); //4.创建Thread类的子类对象 mt.start(); //开启线程 for(int i=0;i<1000;i++){ System.out.println("bbbbbbbbb"); } } } class MyThread extends Thread{ //1.继承Thread方法 public void run(){ //2.重写run方法 for(int i=0;i<1000;i++){ //3.将要执行的代码写在run方法中 System.out.println("aaaaaaaaa"); } } }
public class Thread_demo2 { /** * @param args */ public static void main(String[] args) { MyRunnable mr = new MyRunnable(); Thread t = new Thread(mr); t.start(); for(int i=0;i<1000;i++){ System.out.println("bbbbbbbbb"); } } } class MyRunnable implements Runnable{ //1.定义一个类实现Runnable @Override public void run() { //2.重写run方法 for(int i=0;i<1000;i++){ //3.将要执行的代码写在run方法中 System.out.println("aaaaaaaaa"); } } }
public class Synchronized_Demo1 { /** * 同步代码块 * 当多线程并发,有多段代码同时执行时,我们希望某一段代码执行过程中cpu不要切换到其他流程工作,这时就需要同步 * 如果两段代码是同步的,那么同一时间只能执行一段,在一段代码没执行结束之前,不会执行另一段代码 */ public static void main(String[] args) { final Printer p = new Printer(); /** * 匿名内部类创建线程 */ new Thread(){ public void run(){ while(true){ p.print1(); } } }.start(); new Thread(){ public void run(){ while(true){ p.print2(); } } }.start(); } } class Printer{ Demo d =new Demo(); public void print1(){ synchronized(d) { //同步代码块,锁机制,锁对象可以是任意的 System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); } } public void print2(){ synchronized(d) { System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print(" "); } } } class Demo{ }
public class Synchronized_Demo2 { /** * 同步方法 */ public static void main(String[] args) { final Printer2 p = new Printer2(); /** * 匿名内部类创建线程 */ new Thread(){ public void run(){ while(true){ p.print1(); } } }.start(); new Thread(){ public void run(){ while(true){ p.print2(); } } }.start(); } } class Printer2{ Demo1 d =new Demo1(); //非静态同步方法的锁对象是this //静态同步方法的锁对象是该类的字节码类.class public synchronized void print1(){ System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); } public void print2(){ synchronized(this) { System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print(" "); } } } class Demo1{ }
public class Test1 { /** * 多线程并发处理同一数据时,就有可能出现线程安全问题 * 使用同步技术可以解决这种问题 * 铁路售票,一共100张,通过4个窗口卖完 */ public static void main(String[] args) { new Ticket().start(); new Ticket().start(); new Ticket().start(); new Ticket().start(); } } class Ticket extends Thread{ private static int ticket = 100; //new Ticket()是四个不同的对象,当成员变量为静态的4个对象会共享 public void run(){ while(true){ synchronized (Ticket.class) { if(ticket == 0){ break; } System.out.println(getName()+"这是第"+ ticket-- +"号票" ); } } } }
public class Test2 { /** * 铁路售票,一共100张,通过4个窗口卖完用Runnable接口 */ public static void main(String[] args) { MyTicket mt = new MyTicket(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); } } class MyTicket implements Runnable{ private int ticket = 100; @Override public void run() { while(true){ synchronized (Ticket.class) { if(ticket == 0){ break; } System.out.println(Thread.currentThread().getName()+"这是第"+ ticket-- +"号票" ); } } } }
public class DeadLock { /** * 死锁(synchronized嵌套synchronized) */ private static String s1="筷子左"; private static String s2="筷子右"; public static void main(String[] args) { new Thread(){ public void run(){ while(true){ synchronized (s1) { System.out.println(getName()+"获取"+ s1 +"等待" +s2); synchronized(s2){ System.out.println(getName()+"拿到"+ s2 +"开吃"); } } } } }.start(); new Thread(){ public void run(){ while(true){ synchronized (s2) { System.out.println(getName()+"获取"+ s2 +"等待" +s1); synchronized(s1){ System.out.println(getName()+"拿到"+ s1 +"开吃"); } } } } }.start(); } }
单例设计模式
public class Singleton_Demo { /** * 单例设计模式(保证类在内存中只有一个对象) */ public static void main(String[] args) { //Singleton s1 = new Singleton(); 不能创建 //成员变量被私有不能通过类名.调用 /*Singleton s1 = Singleton.s; Singleton s2 = Singleton.s; System.out.println(s1=s2); //true */ /*Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1==s2);*/ Singleton s1 = Singleton.s; Singleton s2 = Singleton.s; System.out.println(s1==s2); } } /** * 饿汉式(直接创建对象) */ /*class Singleton{ //1.私有构造方法,其他类不能访问该构造方法 private Singleton(){} //2.创建本类对象 private static Singleton s = new Singleton(); //3.对外提供公共的访问方法 public static Singleton getInstance(){ //获取实例 return s; } }*/ /** * 懒汉式(开发时不用) 单例的延迟加载模式 */ /*class Singleton{ //1.私有构造方法,其他类不能访问该构造方法 private Singleton(){} //2.创建本类对象 private static Singleton s; //3.对外提供公共的访问方法 public static Singleton getInstance(){ //获取实例 if(s == null){ //多线程访问时会创建多个对象 s = new Singleton(); } return s; } }*/ /* *饿汉式和懒汉式区别 * 1.饿汉式是空间换时间,懒汉式是时间换空间 * 2.在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象 */ /** * 第三种 */ class Singleton{ //1.私有构造方法,其他类不能访问该构造方法 private Singleton(){} //2.创建本类对象 public static final Singleton s = new Singleton(); }
计时器
public class Timer_Demo { /** * 计时器 * @throws Exception */ public static void main(String[] args) throws Exception { Timer t = new Timer(); //在指定时间安排指定任务 //第一个参数是安排的任务,第二个参数是执行的时间,第三个参数是过多长时间在重复执行 t.schedule(new MyTimerTask(), new Date(188, 6, 1, 14, 20, 30),3000); while(true){ Thread.sleep(1000); System.out.println(new Date()); } } } class MyTimerTask extends TimerTask{ @Override public void run() { System.out.println("起床背英语单词"); } }
线程间的通信
public class Notify_demo { /** * 线程间通信 * 等待唤醒机制 */ public static void main(String[] args) { final Printer2 p = new Printer2(); new Thread() { public void run(){ while(true){ try { p.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run(){ while(true){ try { p.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } //等待唤醒机制 //实现将黑马程序员、传智播客间隔输出 class Printer2{ private int flag =1; public void print1() throws InterruptedException{ synchronized(this) { if(flag != 1){ this.wait(); } System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print(" "); flag =2; this.notify(); //随机唤醒单个等待的线程 } } public void print2() throws InterruptedException{ synchronized(this) { if(flag != 2){ this.wait(); //当前线程等待 } System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print(" "); flag =1; this.notify(); } } }
public class NotifyAll_Demo { /** * 三个或三个以后线程通信 */ public static void main(String[] args) { final Printer3 p = new Printer3(); new Thread() { public void run(){ while(true){ try { p.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run(){ while(true){ try { p.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run(){ while(true){ try { p.print3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } /** * 再同步代码块中,用哪个对象锁,就用哪个对象调用wait方法 * sleep方法和wait方法区别: * sleep方法必须传入参数,参数就是时间,时间到了自动醒来 * wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待 * sleep方法在同步函数或同步代码中,不释放锁 * wait方法在同步函数或同步代码中,释放锁 * */ class Printer3{ private int flag =1; public void print1() throws InterruptedException{ synchronized(this) { while(flag != 1){ this.wait(); } System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print(" "); flag =2; this.notifyAll(); //随机唤醒单个等待的线程 } } public void print2() throws InterruptedException{ synchronized(this) { while(flag != 2){ this.wait(); //当前线程等待 } System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print(" "); flag =3; this.notifyAll(); } } public void print3() throws InterruptedException{ synchronized(this) { while(flag != 3){ this.wait(); //当前线程等待 } System.out.print("i"); System.out.print("t"); System.out.print("h"); System.out.print("e"); System.out.print("i"); System.out.print("m"); System.out.print("e"); System.out.print(" "); flag =1; this.notifyAll(); } } }
public class ReentrantLock_demo { /** * @param args */ public static void main(String[] args) { final Printer4 p = new Printer4(); new Thread() { public void run(){ while(true){ try { p.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run(){ while(true){ try { p.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run(){ while(true){ try { p.print3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer4{ private ReentrantLock r = new ReentrantLock(); private Condition c1 = r.newCondition(); private Condition c2 = r.newCondition(); private Condition c3 = r.newCondition(); private int flag =1; public void print1() throws InterruptedException{ r.lock(); //获取锁 if(flag != 1){ c1.await(); } System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print(" "); flag =2; c2.signal(); r.unlock(); //释放锁 } public void print2() throws InterruptedException{ r.lock(); //获取锁 if(flag != 2){ c2.await(); //当前线程等待 } System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print(" "); flag =3; c3.signal(); r.unlock(); //释放锁 } public void print3() throws InterruptedException{ r.lock(); //获取锁 if(flag != 3){ c3.await(); //当前线程等待 } System.out.print("i"); System.out.print("t"); System.out.print("h"); System.out.print("e"); System.out.print("i"); System.out.print("m"); System.out.print("e"); System.out.print(" "); flag =1; c1.signal(); r.unlock(); //释放锁 } }
public class ThreadGroup_demo { public static void main(String[] args) { //demo(); ThreadGroup tg = new ThreadGroup("我是一个新的线程组"); //创建新的线程组 MyRunnable mr = new MyRunnable(); //创建Runnable子类对象 Thread t1 = new Thread(tg, mr, "张三"); //将线程t1放在组中 Thread t2 = new Thread(tg, mr, "李四"); //将线程t2放在组中 System.out.println(t1.getThreadGroup().getName()); //获取组名 System.out.println(t2.getThreadGroup().getName()); } public static void demo(){ MyRunnable mr = new MyRunnable(); Thread t1 = new Thread(mr, "张三"); Thread t2 = new Thread(mr, "李四"); ThreadGroup tg1 = t1.getThreadGroup(); ThreadGroup tg2 = t2.getThreadGroup(); System.out.println(tg1.getName()); //main 默认是主线程 System.out.println(tg2.getName()); } } class MyRunnable implements Runnable{ @Override public void run() { for(int i=0;i<1000;i++){ System.out.println(Thread.currentThread().getName()); } } }
简单工厂模式
/** * Cat类 */ public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } } ------------------------------------------------------ /** * Dog类 */ public class Dog extends Animal { @Override public void eat() { System.out.println("狗吃肉"); } } ------------------------------------------------------ /** * Animal类 */ public abstract class Animal { public abstract void eat(); } ------------------------------------------------------ /** * 工厂类 */ public class AnimalFactory { /*public static Dog createDog(){ return new Dog(); } public static Cat createCat(){ return new Cat(); }*/ //发现方法会定义很多,复用性太差 //改进 public static Animal createAnima(String name){ if("dog".equals(name)){ return new Dog(); }else if ("cat".equals(name)){ return new Cat(); }else{ return null; } } } ------------------------------------------------------ public class Test { /** * 简单工厂模式(定义一个具体的工厂类负责创建一些类的实例) * 优点:客户端不需要负责对象的创建,从而明确了各个类的职责 * 缺点:这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者其他对象的创建方式不同, * 就需要不断的修改工厂类,不利于后期的维护 */ public static void main(String[] args) { //Dog d = AnimalFactory.createDog(); Dog d = (Dog) AnimalFactory.createAnima("dog"); d.eat(); Cat c = (Cat) AnimalFactory.createAnima("cat"); c.eat(); } }
工厂方法模式
public abstract class Animal { public abstract void eat(); } ------------------------------------- public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } } -------------------------------------------- public class Dog extends Animal { @Override public void eat() { System.out.println("狗吃肉"); } } ------------------------------------------------ public interface Factory { public Animal createAnimal(); } ------------------------------------------------- public class CatFactory implements Factory { @Override public Animal createAnimal() { return new Cat(); } } ----------------------------------------------------- public class DogFactory implements Factory { @Override public Animal createAnimal() { return new Dog(); } } --------------------------------------------------------------- public class Test { /** * 工厂方法模式(抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承工厂的具体类实现) * 优点:客户端不需要负责对象的创建,从而明确各个类的职责,只需要增加一个具体类和具体的工厂类即可 * 不影响已有的代码,后期维护容易,增加了系统的扩展性 * 缺点:需要额外的编写代码。增加了工作量 */ public static void main(String[] args) { DogFactory df = new DogFactory(); Dog d = (Dog) df.createAnimal(); d.eat(); CatFactory cf = new CatFactory(); Cat c = (Cat) cf.createAnimal(); c.eat(); } }
GUI(图形用户接口)
适配器设计模式:
适配器:在使用监听器的时候,需要定义一个类事件监听器接口
通常接口中会有多个方法,而程序中不一定所有都用到
但又必须重写,这很繁琐,适配器简化了这些操作,
我们定义监听器时只要继承适配器,然后重写需要的方法即可
适配器原理:就是一个类,实现了监听器接口,所有抽象方法都重写了
但方法都是空的,
适配器类需要定义为抽象的,因为创建该类对象,调用空方法是没有意义的
目的就是为了简化程序员的操作,定义监听器时继承适配器,只重写需要的方法即可
public class Demo1_Adapter { /** * 适配器设计模式 */ public static void main(String[] args) { luzhishen lzs = new luzhishen(); lzs.xiwu(); } } interface heshang{ public void dazuo(); public void nianjing(); public void zhuangzhong(); public void xiwu(); } //声明称抽象的原因是:不想让其他类创建本类对象,因为创建也没有意义,方法都是空的 abstract class tiangangxing implements heshang{ @Override public void dazuo() { } @Override public void nianjing() { } @Override public void zhuangzhong() { } @Override public void xiwu() { } } class luzhishen extends tiangangxing{ public void xiwu(){ System.out.println("拳打镇关西"); System.out.println("倒拔垂杨柳"); } }
网络编程
upd传输
/** * 发送 */ public static void main(String[] args) throws Exception { String str = "what are you doing"; DatagramSocket socket = new DatagramSocket(); //随机端口号 DatagramPacket packet = new DatagramPacket(str.getBytes(), str.getBytes().length,InetAddress.getByName("127.0.0.1"),6666); socket.send(packet); socket.close(); } -------------------------------------------------------------- /** * 接收 */ public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(6666); DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); socket.receive(packet); byte[] arr = packet.getData(); //获取数据 int len = packet.getLength(); //获取有效的字节个数 String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); System.out.println(ip +"----"+port+"----"+new String(arr, 0, len)); socket.close(); }
TCP
/** * 客户端 * 创建Socket连接服务器(指定ip地址,端口号)通过ip地址找对应的服务器 * 调用Socket的getInputStream和getOutputStream方法获取和服务端相连的IO流 * 输入流可以读取服务器输出流写出的数据 * 输出流可以写出数据到服务端的输入流 */ public static void main(String[] args) throws UnknownHostException, IOException { Socket socket = new Socket("127.0.0.1", 12345); InputStream is = socket.getInputStream(); //获取客户端输入流 OutputStream os = socket.getOutputStream(); //获取客户端输出流 byte[] arr =new byte[1024]; int len = is.read(arr); //读取服务器发过来的数据 System.out.println(new String(arr,0,len)); //将数据转换成字符串并打印 os.write("学习挖掘机哪家强".getBytes()); //客户端向服务器写数据 socket.close(); }
/** * 服务端 * 创建ServerSocket(需指定端口号) * ServerSocket的accept方法接受一个客户端请求,得到一个Socket * 调用Socket的getInputStream和getOutputStream方法获取和客户端相连的IO流 * 输入流可以读取客户端输出流写出的数据 * 输出流可以写出数据到客户端的输入流 */ public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(12345); Socket socket = server.accept(); InputStream is = socket.getInputStream(); //获取客户端输入流 OutputStream os = socket.getOutputStream(); //获取客户端输出流 os.write("百度一下你就知道".getBytes()); //服务器向客户端写出数据 byte[] arr =new byte[1024]; int len = is.read(arr); //读取客户端发过来的数据 System.out.println(new String(arr,0,len)); //将数据转换成字符串并打印 socket.close(); }
/** * 客户端(优化版) * 创建Socket连接服务器(指定ip地址,端口号)通过ip地址找对应的服务器 * 调用Socket的getInputStream和getOutputStream方法获取和服务端相连的IO流 * 输入流可以读取服务器输出流写出的数据 * 输出流可以写出数据到服务端的输入流 */ public static void main(String[] args) throws UnknownHostException, IOException { Socket socket = new Socket("127.0.0.1", 12345); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //将字节流包装成字符流 PrintStream ps = new PrintStream(socket.getOutputStream()); //printStream中有写出换行的方法 System.out.println(br.readLine()); ps.println("我想报名"); System.out.println(br.readLine()); ps.println("大哭"); socket.close(); }
/** * 服务端(优化版) * 创建ServerSocket(需指定端口号) * ServerSocket的accept方法接受一个客户端请求,得到一个Socket * 调用Socket的getInputStream和getOutputStream方法获取和客户端相连的IO流 * 输入流可以读取客户端输出流写出的数据 * 输出流可以写出数据到客户端的输入流 */ public static void main(String[] args) throws IOException { //demo1(); ServerSocket server = new ServerSocket(12345); while(true){ final Socket socket = server.accept(); new Thread(){ public void run(){ try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //将字节流包装成字符流 PrintStream ps; ps = new PrintStream(socket.getOutputStream()); //printStream中有写出换行的方法 ps.println("欢迎咨询黑马程序员"); System.out.println(br.readLine()); ps.println("不好意思"); System.out.println(br.readLine()); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); } } /** * 非线程 */ public static void demo1() throws IOException{ ServerSocket server = new ServerSocket(12345); Socket socket = server.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //将字节流包装成字符流 PrintStream ps = new PrintStream(socket.getOutputStream()); //printStream中有写出换行的方法 ps.println("欢迎咨询黑马程序员"); System.out.println(br.readLine()); ps.println("不好意思"); System.out.println(br.readLine()); socket.close(); }
/** * 客户端向服务端写字符串(键盘录入),服务端(多线程)将字符串反转并写回,客户端再次读取到是反转后字符串 * @throws IOException * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException, IOException { Scanner sc = new Scanner(System.in); Socket socket = new Socket("127.0.0.1", 12345); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream ps = new PrintStream(socket.getOutputStream()); ps.println(sc.nextLine()); System.out.println(br.readLine()); socket.close(); } ------------------------------------------------- /** * 服务端 */ public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(12345); while(true){ final Socket socket = server.accept(); new Thread(){ public void run(){ try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream ps = new PrintStream(socket.getOutputStream()); String line = br.readLine(); line = new StringBuilder(line).reverse().toString(); ps.println(line); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } }
/** *客户端向服务端上传文件 */ public static void main(String[] args) throws UnknownHostException, IOException { //1.提示输入要上传的文件路径,验证路径是否存在以及是否是文件夹 File file = getFile(); //2.发送文件名到服务器 Socket socket= new Socket("127.0.0.1", 12564); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream ps = new PrintStream(socket.getOutputStream()); ps.println(file.getName()); //6.接收结果,如果存在给予提示,程序直接退出 String result =br.readLine(); //读取存在或者不存在的结果 if("存在".equals(result)){ System.out.println("您上传的文件已经存在,请不要重复上传"); socket.close(); return; } //7.如果不存在,定义FileInputStream读取文件,写出到网络 FileInputStream fis = new FileInputStream(file); byte[] arr = new byte[8192]; int len; while((len= fis.read(arr)) != -1){ ps.write(arr,0,len); } fis.close(); socket.close(); } private static File getFile(){ Scanner sc =new Scanner(System.in); //创建键盘录入对象 System.out.println("请输入文件路径"); while(true){ String line = sc.nextLine(); File file = new File(line); if(! file.exists()){ System.out.println("您录入的文件路径不存在,请重新录入"); }else if(file.isDirectory()){ System.out.println("您录入的是文件夹路径,请输入一个文件路径"); }else { return file; } } } ------------------------------------------------ /** * 服务端 */ public static void main(String[] args) throws IOException { //3.创建多线程服务器 ServerSocket server = new ServerSocket(12564); //4.读取文件名 while(true){ final Socket socket = server.accept(); //接收请求 new Thread(){ public void run(){ try { InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); PrintStream ps = new PrintStream(socket.getOutputStream()); String fileName = br.readLine(); //判断文件是否存在,将结果返回客户端 File dir = new File("update"); dir.mkdir(); //创建文件夹 File file = new File(dir, fileName); //分装成file对象 if(file.exists()){ ps.println("存在"); //如果服务器已经存在这个文件将存在写给客户端 socket.close(); //关闭socket return; }else{ ps.println("不存在"); } //8.定义FileOutPrintStream 从网络读取数据,存储到本地 FileOutputStream fos = new FileOutputStream(file); byte[] arr = new byte[8192]; int len; while((len = is.read(arr)) != -1){ fos.write(arr,0,len); } fos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } }