jdk(java development kit),即Java开发工具集。java
jre(java runtime enviroment),即Java运行环境编程
jvm(java virtual machine),Java虚拟机。目前主要使用的式hotsopt。小程序
Green项目设计模式
应用环境:像电视盒这样的消费类电子产品数组
要求:安全
发明者:James Gosling服务器
历程:网络
▪ 1991年,Sun公司的Green项目,Oak
▪ 1995年,推出Java测试版
▪ 1996年,JDK1.0
▪ 1997年,JDK1.1
▪ 1998年,JDK1.2,大大改进了早期版本的缺陷,是一个革命性的版本,改名为Java2
▪ 1999 Java被分红J2SE、J2EE 和J2ME,JSP/Servlet技术诞生
▪ 2004年,J2SE 5.0 (1.5.0) Tiger老虎.为了表示这个版本的重要性,J2SE1.5改名为J2SE5.0。
▪ 2006年,J2SE 6.0 (1.6.0) Mustang野马.此时,Java的各类版本被改名,取消其中的数字"2":J2EE改名为Java EE, J2SE改名为
Java SE,J2ME改名为Java ME
▪ 2009年4月20日甲骨文收购Sun公司,交易价格达74亿美圆
▪ 2011年,JavaSE7.0
▪ 2014年 ,JavaSE8.0
▪ 2017年,JavaSE9.0
▪ 2018年3月,JavaSE10.0
▪ 2018年9月,JavaSE11.0
▪ 2019年3月,JavaSE12.0数据结构
public class Test{ public static void main(String[] args){ System.out.println("hello, world"); } }
用来给类、变量、方法、对象等起的名称。由于在Java中一切皆对象,故不存在函数这一说,只有方法。多线程
首字母能够是字母、下划线、美圆符号,可是不能是数字
// 合法 int a; int _a; int A; int $a; // 不合法 int 1a;
其余部分只能是字母、下划线、数字、美圆符号
// 合法 int a1_$; // 不合法 int a-1;
Java严格区分大小写
int a; int A; // a和A不是同一个变量
Java命名变量的时候建议采用驼峰标识以及变量要见名知意
// 建议 String name; int age; boolean isAlive; // 不建议 String s; int a; boolean b;
给系统使用的关键字,好比:int,float,void, class,for,while,break等等,在定义变量的时候不能定义成:int float;
。
算术运算符包括:+,-,*,/,%。
int a = 10; int b = 3; a + b; // 13 a - b; // 7 a * b; // 30 a / b; // 做商, 3 a % b; // 取余, 1
比较运算符包括:==,!=,>,>=,<, <=。
int a = 10; int b = 3; a == b; // false a != b; // true a > b ; // true a >= b; // true a < b ; // false a <= b; // false
赋值运算符:int a = 10;
,将10赋值给变量a。
逻辑运算符包括:&&,||,!。
int a = 10; int b = 1; int c = 2; // && 两边同时为true结果返回true,不然返回false (a > b) && (a > c); // true,a>b为true,a>c为true (a > b) && (a < c); // false, 由于,a>b为true,a<c为fasle // || 两边只要有一边为true,结果返回true (a > b) || (a > c); // true,a>b为true,a>c为true (a > b) || (a < c); // true,a>b为true,a<c为false (a < b) || (a > c); // true,a<b为false,a>c为true (a < b) || (a < c); // false,a<b为fasle,a<c为false // !,对取得的布尔值取反操做,!true->false, !false->true !(a>c); // fasle,a>c为true // &&,|| 的短路操做 (a > b) && ((c = b) ==b); // true,c=1,由于a>b为true,继续比较右边,执行右边 (a < b) && ((c=b)==b); // false,c=2,由于a<b为false,直接返回false,不比较后面代码,也不执行后面代码 (a > b) || ((c=b)==b); // true,c=2,由于a>b为true,直接返回结果,不执行后面操做 (a < b) || ((c=b)==b); // true,c=1,由于a<b为false,继续比较右边,执行右边代码,右边结果为true
形如:xxx?x:y。若xxx语句的返回值为true,则返回x,不然返回y。
int a = 10>20?1:2; // a=2,由于10>20为false
位运算符主要包括:&,|,^。
// & 将两个数转换为二进制进行比较,相同的位上都是1,则该位比较后的值为1 // | 将两个数转换为二进制进行比较,相同的位上若是存在1,则该位比较后的值为1 // ^ 将两个数转换为二进制进行比较,相同的位上若是存在1,且不一样时为1,则该位比较后的值为1 5转换成二进制:0101 3转换成二进制:0011 0101 & 0011 = 0001 转换成10进制:1 0101 | 0011 = 0111 转换成10进制:7 0101 ^ 0011 = 0110 转换成10进制:6
byte b; short s; int i; long l; float f; double d; char c; boolean b; String string;
占1位。
String
数组
定义方式
int[] numbers = new int[10]
;int[] numbers = new int[10]{1,2,3,4,5,6,7,8,9,0};
int[] numbers = {1,2,3,4,5,6,7,8,9,0};
使用
获取
int[] numbers = {1,2,3}; System.out.println(numbers[1]);
修改
int[] numbers = {1,2,3}; numbers[1] = 10;
注意:
对象
类的实例化
class Person{ } Person person = new Person(); // person即为对象
接口
某种行为/功能的抽象,若要使用则要实现接口中的全部方法,接口相似于一种约束、规范
interface MyInterface{ void method(); }
等等
从上到下依次按顺序执行
if
if(条件){ 执行语句 } // 但条件的返回结果为true时执行执行语句,不然不执行 // 应用 int a = 10; if(a < 20){ a = 30; } // 由于 a<20为true,执行语句,a=30
if...else
if(条件){ 执行语句 }else{ 执行语句2 } // 若条件的返回结果为true,则执行语句,不然执行语句2 // 应用 int a = 10; if(a>10){ a = 8; }else{ a = 20; } // 由于a>10为false,所以执行a=20
if...else if...else
if(条件1){ 执行语句1 }else if(条件2){ 执行语句2 }else{ 执行语句3 } // 若知足条件1,则执行语句1,不然若知足条件2,则执行语句2,不然执行语句3 // 应用 int a = 10; if(a > 10){ a = 8; }else if(a > 5){ a = 4 }else{ a = 100; } //a = 4,由于a>10为false,a>5为false,执行a=4
switch
switch(变量){ case value1: 执行语句1 break; case value2: 执行语句2 break; default: 执行语句3 break; } // 变量的值若是等于某一个case后面的值则执行相应的语句,而后跳出语句,不然就执行default里的语句,而后退出 // 这里变量以及case的值只能为:整数、字符、字符串 // 应用 int a = 10; switch(a){ case 10: System.out.println("10"); break; case 20: System.out.println("20"); break; default: System.out.println("no"); break; } // 打印10
do...while
do{ 执行语句 }while(条件); // 循环执行语句,直到不知足条件,至少作一次 int a = 0; do{ System.out.print(i); i++; }while(i<20);
while
while(条件){ 执行语句 } // 但知足条件时循环执行语句,直到不知足条件 int a = 0; while(a < 10){ System.out.println(a); a++; }
for
for(初始化变量;知足的条件;更新变量){ 执行语句 } // 对于初始化变量,每次执行语句后更新变量,直到不知足条件 for(int a;a<10;a++){ System.out.println(a); }
加强for循环
对于一个集合、数组或者map,若其中的元素的类型都一致,则可使用使用forech(加强for循环来遍历)
for(类型 变量:集合){ 执行语句 } // 应用 int[] numbers = {1,2,3,4,5}; for(int number:numbers){ System.out.println(number); }
break
跳出当前循环
for(int i=0;i<10;i++){ if(i==5){ break; } System.out.println(i); } //打印0-4后,更新变量,i=5,此时跳出for循环
continue
跳过本次循环
for(int i=0;i<10;i++){ if(i % 2 !=0){ continue; } System.out.println(i); } // 打印0-9全部的偶数
return
返回结果值
public int addOne(int number){ return number + 1; } System.out.println(addOne(10)); // 返回11
结束程序
for(int i=0;i<10;i++){ if(i ==5){ return; } } // 当i==5时,结束程序
典型的是C语言。经过分析出解决问题所须要的步骤,而后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就能够了。以把大象放入冰箱为例,咱们首先定义一个拿到大象的函数,而后定义一个开冰箱的函数,而后定义一个放大象的函数,而后定义一个关冰箱的函数,最后一次调用就能够实现功能了。
在考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现。
典型的C++、C#、Java等编程语言。经过将现实世界中的物体抽象成一个具体的类,经过调用类的相关方法来完成一系列行为。仍是以把大象放入冰箱为例,咱们先定义一我的的类,有拿大象、放大象、开冰箱、关冰箱的方法(也就是人能够作这些事情),再定义一个大象类,再定义一个冰箱类,而后建立相应的对象调用相关的方法便可。
在考虑问题时,以对象为单位,考虑它的属性及方法。
定义(规范,约束)与实现(名实分离的原则)的分离。
接口的自己反映了系统设计人员对系统的抽象理解。
经过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP能够对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度下降,提升程序的可重用性,同时提升了开发的效率。
典型的是Python、JavaScript语言。
函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),并且λ演算的函数能够接受函数看成输入(参数)和输出(返回值)。主要思想是把运算过程尽可能写成一系列嵌套的函数调用。
在现实生活中,人(Person)表示一种生物,很抽象,具体的人:张三,就是一个对象,一个具体的人,一个独立的个体。
// 定义一个类 class Person{ } // 实例化一个对象(建立一个对象) Person zhangsan = new Person();
经过new关键字实现。
一个类的构造方法,用于对一个对象的初始化,好比说咱们在买电脑的时候都会选择电脑的:cpu、内存、硬盘、显示屏等等,这些至关于初始化。
class Computer{ private String cpu; private String arm; private String disk; private String screen; public Computer(String _cpu, String _arm, String _disk, String _screen){ cpu = _cpu; arm = _arm; disk = _disk; screen = _screen; } } // 利用构造器建立对象 Computer myComputer = new Computer("Intel", "英伟达","sanxing", "英伟达");
默认状况下建议写一个无参构造器。
指代当前对象。能够在构造方法中使用,用来区分参数和成员变量,在普通方法中使用表示调用当前的属性或者当前类的方法,能够省略。
class Computer{ private String cpu; private String arm; private String disk; private String screen; public Computer(String cpu, String arm, String disk, String screen){ this.cpu = cpu; this.arm = arm; this.disk = disk; this.screen = screen; } } // 利用构造器建立对象 Computer myComputer = new Computer("Intel", "英伟达","sanxing", "英伟达");
表示静态的,更准确的说是表示类的什么什么,被static修饰的方法、函数、类(内部类)在类加载的时候就建立了,而没有被修饰的则是属于对象,只有当建立对象的时候才建立,由于,static修饰的属性、方法、类的建立是先于普通属性、方法的,所以:静态方法中不能存在普通的属性、方法、对象。
被static修饰的属性、方法,类能够直接调用。
class Person{ static boolean isPerson = true; static void sleep(){ } } // 调用 System.out.println(Person.isPerson); System.out.println(Person.sleep());
表示最终的,不可更改,有三种形式
打包:区分同名的文件,分布在不一样的目录。
将不一样的功能代码整合在一块儿。
导包:方便引用其余包的类
规定方法、类、属性的访问范围。
分类:
在同一个类中,能够定义多个同名方法,可是,这些方法必须知足如下三个条件之一:
参数类型不同
参数个数不同
参数顺序不同
class Demo{ public void method(){ } public void method(String str){ } public void method(String str,int number){ } public void method(int number,String name){ } }
在代码中能够将某个代码块变成方法,抽象出某些工具类
public class Test2 { private String string; private int number; public String getString() { return string; } public void setString(String string) { this.string = string; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } }
解释说明
重写
super
public class Test2 extends Test4{ @Override public void method() { super.method1(); System.out.println("Test2->method"); } } class Test4{ public void method(){ System.out.println("Test4->method"); } public void method1(){ System.out.println("Test4->method1"); } }
public class Test2{ public static void main(String[] args) { personSpeak(new Boy()); // 传入子类自动转换成父类 personSpeak(new Girl()); personSpeak((Person) new Object()); // 父类到子类强制转换,Object类是全部类的父类 } static void personSpeak(Person person){ person.speak(); } } abstract class Person{ abstract void speak(); } class Boy extends Person{ @Override void speak() { // 重写父类方法 System.out.println("男孩说话"); } } class Girl extends Person{ @Override void speak() { System.out.println("女孩说话"); } }
public class Test2{ public static void main(String[] args) { new Singer().singSong(new Boy()); } } interface Sing{ final boolean isSing = true; void singSong(Person person); } class Singer extends Person implements Sing{ @Override public void singSong(Person person) { this.speak(); } @Override void speak() { } }
// 案例:人都要睡觉;人要说话,可是不一样国家的人说的话不同,中国人说中文,美国人说美语 abstract class Person{ public void sleep(){ System.out.println("是我的都睡觉"); } abstract void speak(); } class Chinese extends Person{ @Override void speak() { System.out.println("中国人说做文"); } } class American extends Person{ @Override void speak() { System.out.println("美国人说美语"); } }
public class Demo1 { public static void main(String[] args) { // 静态内部类 StaticInnerClass staticInnerClass = new Demo1.StaticInnerClass(); // 成员内部类 InnerClass innerClass = new Demo1().new InnerClass(); // 方法内部类,生命周期指在方法内 Object o = method(); // 匿名内部类 MyInterface myInterface = new MyInterface() {}; } static class StaticInnerClass{ } class InnerClass{ } public static Object method(){ class MethodInnerClass{ } return new MethodInnerClass(); } } interface MyInterface{ }
表示程序在运行过程当中出现的非正常状况,编写代码的过程当中尽量少的减小异常出现的状况
try...catch
try{ 可能出现异常的语句 }catch(可能出现的异常){ 捕捉异常后执行的语句 } // try{ int x = 1 /0; }catch(ArithmeticException e){ e.printStack(); }
try...catch...finally
try{ 可能发生异常的代码 }catch(发生的异常){ 捕捉异常后执行的语句 }finally{ 无论是否发生异常都要执行的语句 } // try{ int x = 1 /0; }catch(ArithmeticException e){ e.printStack(); }finally{ System.out.println("finally") }
注意
当发生异常时,在try代码块中异常语句后面的语句不会再执行
try、catch、finally以及try...catch...finally以外的代码是互相独立的,在try中定义的变量在其余的部分没法访问,改变了仅做用于try部分,其余catch、finally状况相似,可是外部定义的变量在try、catch、finally中可使用
在进行异常捕获的时候,return语句的不一样位置会形成结果的不一样
首先讨论try...catch...finally后面有代码的状况
//此时注意一个关键的点:checked异常,即return语句后面不能再跟语句 // 例如 return; System.out.println("after return");// 这条语句ide直接报错,至关于多余的 // 故return的语句只能有一下几种状况 //1 try{ System.out.println("1"); System.out.println(1 / 0); return; }catch (Exception e){ System.out.println("2"); // return; }finally { System.out.println("3"); // return; } System.out.println("4"); } // 此时return语句永远都不会被执行,也就不会报错。 //2 try{ System.out.println("1"); // System.out.println(1 / 0); return; }catch (Exception e){ System.out.println("2"); // return; }finally { System.out.println("3"); // return; } System.out.println("4"); //此时,当程序执行到return语句时,并不会当即执行,而是先挂起,等执行完finally中的语句以后再执行return语句结束程序,故try、catch、finally以外的其余代码不会再执行 //其余的catch、finally中都不能再存在return语句了
try...catch...finally后面没有代码的状况
//第一种状况 try{ System.out.println("1"); System.out.println(1 / 0); return; }catch (Exception e){ System.out.println("2"); // return; }finally { System.out.println("3"); // return; } // 此时return语句永远不会执行 // 第二种状况,此时return语句有没有都没有关系 try{ System.out.println("1"); // System.out.println(1 / 0); return; }catch (Exception e){ System.out.println("2"); // return; }finally { System.out.println("3"); // return; } //第三种状况 try{ System.out.println("1"); System.out.println(1 / 0); // return; }catch (Exception e){ System.out.println("2"); return; }finally { System.out.println("3"); // return; } //此时,仍是跟前面同样的,return先挂起,执行完finally中的代码后再结束程序 //第三种状况 public class Demo { public static void main(String[] args) { System.out.println(method()); } public static int method(){ try{ System.out.println("1"); System.out.println(1 / 0); // return; }catch (Exception e){ System.out.println("2"); return 1; }finally { System.out.println("3"); // return 2; } // System.out.println("4"); return 0; } } // 此时会执行最近的return语句
综上:
将异常状况抛出给调用者
注意,若是整个程序的运行过程当中都没有异常的处理的话,最终异常会抛给jvm,不太友好,通常都要对异常进行处理
import java.io.FileInputStream; import java.io.FileNotFoundException; public class Demo1 { public static void main(String[] args) throws FileNotFoundException { FileInputStream fileInputStream = new FileInputStream("test.txt"); } }
java中提供了很是多的异常类,可是在某些项目中须要本身定义独特的异常处理方式,此时须要自定义异常
public class MyException extends Exception{ public MyException(){ System.out.println("自定义异常"); } } public class Demo1 { public static void main(String[] args) throws MyException { throw new MyException(); } }
另外,还能够自定义异常信息
public class Demo1 { public static void main(String[] args) throws Exception { throw new Exception("test"); } }
基本数据类型都由对应的包装类
自动拆箱和自动装箱
举例
public class Demo { public static void main(String[] args) { // 此时自动调用:Integer.valueOf(),若数字大于-128且小于127,直接返回值,不然新建一个对象 Integer integer1 = 1000; Integer integer2 = 1000; int i1 = 1000; int i2 = 1000; System.out.println(integer1 == integer2); // 由于两个变量不是同一个对象所以结果为false System.out.println(integer1.equals(integer2));// true System.out.println(i1 == i2); // true System.out.println(i1 == integer2); // true } }
不可变字符串:String
可变字符串:
举例
public class Demo1 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer("hello,world"); // 增 stringBuffer.insert(0, "@"); stringBuffer.append("#"); // 删 stringBuffer.delete(0,1); // 改 stringBuffer.setCharAt(0, '$'); stringBuffer.replace(0,1,"x"); // 查 stringBuffer.indexOf("a"); stringBuffer.substring(0,1); System.out.println(stringBuffer); } }
日期经常使用类
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class Demo2 { public static void main(String[] args) { DateFormat dateFormat = new SimpleDateFormat("YY-MM-dd HH-mm-ss"); // 建立格式化日期类 System.out.println(dateFormat.format(new Date())); } }
返回格林威治时间
import java.util.Calendar; import java.util.GregorianCalendar; public class Demo3 { public static void main(String[] args) { Calendar calendar = new GregorianCalendar(); System.out.println(calendar.getTime()); System.out.println(calendar.getTimeZone()); System.out.println(calendar.getFirstDayOfWeek()); System.out.println(calendar.getWeekYear()); } }
数学经常使用类
public class Demo4 { public static void main(String[] args) { System.out.println(Math.max(10,20)); System.out.println(Math.abs(-1)); System.out.println(Math.ceil(1.1)); System.out.println(Math.PI); System.out.println(Math.E); } }
import java.util.Random; public class Demo5 { public static void main(String[] args) { System.out.println(new Random().nextInt(10)); System.out.println(new Random().nextDouble()); } }
枚举类也是一个类,能够定义属性和方法,甚至能够写构造方法,填写具体的枚举类对象的时候,能够带参数,可是要跟构造方法进行匹配
public class Demo6 { public static void main(String[] args) { System.out.println(Gender.FEMALE); } } public enum Gender { MALE,FEMALE; }
每一个枚举的子枚举均可以看做是枚举的子类,能够定义相关方法以及相应的set/get方法来获取子枚举携带的一些信息
public enum WEEK_DAY { MONDAY(0), TUESDAY(1), WEDNESDAY(2), THURSDAY(3), FRIDAY(4), SATURDAY(5), SUNDAY(6); private int value; public void method(int i){ System.out.println(i); } public int getValue(){ return this.value; } WEEK_DAY(int i) { this.value = i; } } public class Demo6 { public static void main(String[] args) { System.out.println(WEEK_DAY.FRIDAY.getValue()); } }
一个用来储存数据的容器
形如:int[],String[]
的数据结构
特色:
具备的基本操做:
不惟一,有序
ArrayList实现了长度可变的数组,在内存中分配连续的空间
LinkedList采用链表存储方式
LinkedList特有方法
采用Hashtable哈希表存储结构
优势:添加速度快,查询速度快,删除速度快
缺点:无序
LinkedHashSet
关键代码
HashSet hs=new HashSet();//建立HashSet对象 hs.add(new Person("张三",20)); hs.add(new Person("李四",22)); hs.add(new Person("王五",23)); hs.add(new Person("李四",22));
@Override public int hashCode() { System.out.println(this.name+".....hashCode"); return 60; }
hashCode都相同,不符合实际状况,继续升级
修改hashCode方法
@Override public int hashCode() { System.out.println(this.name+".....hashCode"); return this.name.hashCode()+age; }
总结:
全部能够“排序”的类都实现了java.lang.Comparable 接口 compareTo(Object obj) 方法。
该方法:
返回 0 表示 this == obj 返回正数 表示 this > obj 返回负数 表示 this < obj
实现了Comparable 接口的类经过实现 comparaTo 方法从而肯定该类对象的排序方式。
public class StrLenComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { if (o1.length()>o2.length()) { return 1; } if (o1.length()<o2.length()) { return -1; } return o1.compareTo(o2);//长度相同, 按字母 } } public static void sortDemo(){ List<String> list=new ArrayList<String>(); ..添加元素 sop(list); Collections.sort(list);//按字母排序 sop(list); //按照字符串长度排序 Collections.sort(list,new StrLenComparator()); sop(list); }
全部实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。
Iterator对象称做迭代器,用以方便的实现对容器内元素的遍历操做。
Iterator接口定义了以下方法:
boolean hasNext(); //判断是否有元素没有被遍历 Object next(); //返回游标当前位置的元素并将游标移动到下一个位置 void remove(); //删除游标左面的元素,在执行完next以后该 //操做只能执行一次
全部的集合类均未提供相应的遍历方法,而是把遍历交给迭代器完成。迭代器为集合而生,与门实现集合遍历
Iterator是迭代器设计模式的具体实现
Iterator方法:
可使用Iterator遍历的本质 :实现Iterable接口
在迭代过程当中,准备添加或者删除元素
ArrayList al=new ArrayList(); al.add("java1");//添加元素 al.add("java2"); al.add("java3"); //遍历 Iterator it=al.iterator(); while(it.hasNext()){ Object obj=it.next(); if (obj.equals("java2")) { al.add("java9"); } sop("obj="+obj); }
在迭代时,不可能经过集合对象的方法(al.add(?))操做集合中的元素,会发生并发修改异常。 因此,在迭代时只能经过迭代器的方法操做元素,可是Iterator的方法是有限的,只能进行判断(hasNext),取出(next),删除(remove)的操做,若是想要在迭代的过程当中进行向集合中添加,修改元素等就须要使用 ListIterator接口中的方法
ListIterator li=al.listIterator(); while(li.hasNext()){ Object obj=li.next(); if ("java2".equals(obj)) { li.add("java9994"); li.set("java002"); } }
接口存储一组键值对象,提供key到value的映射
Collections和Collection不一样,前者是集合的操做类,后者是集合接口
Collections提供的静态方法 :
数组不是面向对象的,存在明显的缺陷,集合弥补了数组的一些缺点,比数组更灵活更实用,可大大提升软件的开发效率,并且不一样的集合框架类可适用不一样场合。具体以下:
实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在不少状况下能够互用
二者的主要区别以下 :
流是指一连串流动的字符,是以先进先出方式发送信息的通道 。
XXX->程序-->输入流
程序->XXX-->输出流
输入输出流是相对于计算机内存来讲的,而不是相对于源和目标
字节流是 8 位通用字节流,字符流是 16 位 Unicode 字符流
功能不一样
节点流:能够直接从数据源或目的地读写数据
处理流(包装流):不直接链接到数据源或目的地,是其余流进行封装。目的主要是简化操做和提升性能
节点流和处理流的关系
节点流处于io操做的第一线,全部操做必须经过他们进行
处理流能够对其余流进行处理(提升效率或操做灵活性)
用FileInputStream和FileOutputStream读写文本文件
使用FileInputStream 读文本文件
引入相关的类
构造文件输入流FileInputStream对象
读取文本文件的数据
关闭文件流对象
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class Demo { public static void main(String[] args) { FileInputStream fileInputStream; byte[] bytes = new byte[1024]; try { fileInputStream= new FileInputStream("test.txt"); fileInputStream.read(bytes); System.out.println(new String(bytes)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } fileInputStream.close(); } }
使用FileOutputStream 写文本文件
引入相关的类
构造文件数据 流输出对象
将数据写入文 本文件
关闭文件流对象
import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; public class Demo2 { public static void main(String[] args) throws IOException { FileOutputStream fileOutputStream = new FileOutputStream("test.txt"); String string = "aaaaa"; fileOutputStream.write(string.getBytes(StandardCharsets.UTF_8)); fileOutputStream.close(); } }
用BufferedReader和BufferedWriter读写文本文件
使用 BufferedReader 读文本文件
import java.io.*; public class Demo3 { public static void main(String[] args) throws IOException { FileReader fileReader = new FileReader("test.txt"); BufferedReader bufferedReader = new BufferedReader(fileReader); String result = ""; while ((result = bufferedReader.readLine())!=null){ System.out.println(result); } bufferedReader.close(); fileReader.close(); } }
使用 BufferedWriter 写文件
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class Demo4 { public static void main(String[] args) throws IOException { FileWriter fileWriter = new FileWriter("test.txt"); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); String string = "aaaaaaaa\naaaaaa\taaaa\nsdsdsds"; bufferedWriter.write(string); bufferedWriter.close(); fileWriter.close(); } }
使用DataInputStream和DataOutputStream读写二进制文件以及基本数据类型数据的读写
写入数据
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt")); dos.writeInt(234); dos.writeBoolean(false); dos.writeDouble(9943.00); dos.writeUTF("中国"); dos.close();
读取数据
DataInputStream dis=new DataInputStream(new FileInputStream("data.txt")); int num=dis.readInt(); boolean isFind=dis.readBoolean(); double price=dis.readDouble(); String str=dis.readUTF(); System.out.println(num+"\t"+isFind+"\t"+price+"\t"+str);
使用ObjectInputStream和ObjectOutputStream读写对象(序列化与反序列化)
注意:传输的对象须要实现Serializable接口
序列化
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt")); oos.writeObject(new Person("张三",19)); oos.close();
反序列化
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt")); Person p=(Person)ois.readObject(); System.out.println(p);
注意:
在Java中负责线程的这个功能的是Java.lang.Thread 这个类
能够经过建立 Thread 的实例来建立新的线程
每一个线程都是经过某个特定Thread对象所对应的方法run( )来完成其操做的,方法run( )称为线程体
经过调用Thead类的start()方法来启动一个线程
具体实现:
public class ThreadDemo01 extends Thread { //重写父为的run方法 @Override public void run() { for(int i=0;i<10;i++){ System.out.println("第"+i+"次threadrun........"); } } public static void main(String[] args) { //建立对象,就建立好一个线程 ThreadDemo01 d=new ThreadDemo01(); //d.run();//启动线程使用start方法 d.start(); for(int i=0;i<5;i++){ System.out.println("main-->"+i); } } }
线程的执行
操做步骤
public class RunableDemo implements Runnable { @Override public void run() { for(int i=0;i<10;i++){ System.out.println("第"+i+"次threadrun........"); } } public static void main(String[] args) { //建立对象,就建立好一个线程 RunableDemo rd=new RunableDemo(); Thread t=new Thread(rd); t.start(); for(int i=0;i<5;i++){ System.out.println("main-->"+i); } } }
有三种方法能够暂停Thread执行:
public class TicketImplements implements Runnable { private int tick=5; public void run() { while(true){ if (tick>0) { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖票:"+tick--); } } } public static void main(String[] args) { TicketImplements ti=new TicketImplements(); new Thread(ti).start(); new Thread(ti).start(); new Thread(ti).start(); new Thread(ti).start(); }
多线程的运行出现了安全问题
使用同步解决多线程的安全性问题
同步代码块
public void run() { while(true){ synchronized (this) {//一般将当前对象做为同步对象 if (tick>0) { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖 票:"+tick--); } } } }
同步的前提
将须要同步的代码放到方法中
public void run() { while(true){ sale(); } } public synchronized void sale(){ //一般将当前对象做为同步对象 if (tick>0) { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖票:"+tick--); } }
同步监视器
同步监视器的执行过程
Java提供了3个方法解决线程之间的通讯问题
一组相互链接的计算机
OSI参考模式:开放系统互连参考模型(Open System Interconnect)
TCP/IP参考模型:传输控制/网际协议 Transfer Controln Protocol/Internet Protocol
得到百度主机名:
InetAddress ia2=InetAddress.getByName("www.baidu.com"); System.out.println("其它主机名称:"+ia2.getHostAddress());
进行网络通讯时, Socket须要借助数据流来完成数据的传递工做
客户端
Socket socket=new Socket("localhost",8800);
OutputStream os=socket.getOutputStream();
String info="用户名: Tom;用户密码: 123456"; os.write(info.getBytes()); socket.shutdownOutput();
关闭全部的数据流和Socket
os.close(); socket.close();
服务端
创建链接,处理发送到指定端口的数据
ServerSocket server=new ServerSocket(8800);
获取客户端对象
Socket socket=server.accept();
数据流中读写信息
InputStream is=socket.getInputStream(); byte[] buf=new byte[1024]; int len=is.read(buf); syso(new String(buf,0,len)) socket.shutdownInput();
关闭全部的数据流和Socket
is.close(); socket.close(); server.close()
序列化对象
User user=new User();//User是用户类 user.setLoginName("Tom"); user.setPwd("123456"); oos.writeObject(user);
通讯双发不须要创建链接 ,通讯双方彻底平等
import java.io.IOException; import java.net.*; public class Client { public static void main(String[] args) throws IOException, InterruptedException { DatagramSocket datagramSocket = new DatagramSocket(new InetSocketAddress(InetAddress.getByName("localhost"),8888)); datagramSocket.connect(InetAddress.getByName("localhost"), 9999); ReadThread readThread = new ReadThread(datagramSocket); WriteThread writeThread = new WriteThread(datagramSocket); readThread.start(); writeThread.start(); } } public class Client2 { public static void main(String[] args) throws IOException, InterruptedException { DatagramSocket datagramSocket = new DatagramSocket(new InetSocketAddress(InetAddress.getByName("localhost"),9999)); datagramSocket.connect(InetAddress.getByName("localhost"), 8888); ReadThread readThread = new ReadThread(datagramSocket); WriteThread writeThread = new WriteThread(datagramSocket); readThread.start(); writeThread.start(); } } import java.nio.charset.StandardCharsets; public class ReadThread extends Thread{ private DatagramSocket datagramSocket; private byte[] bytes = new byte[1024]; private byte[] bytes1; DatagramPacket datagramPacket = new DatagramPacket(this.bytes, 0,1024); public ReadThread(DatagramSocket datagramSocket){ this.datagramSocket = datagramSocket; } @Override public void run() { super.run(); while (true){ try { this.datagramSocket.receive(this.datagramPacket); this.bytes1 = new String(this.bytes, 0, this.bytes.length).getBytes(StandardCharsets.UTF_8); System.out.println(new String(this.bytes1, 0, this.bytes1.length)); Thread.sleep(2); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } } import java.util.Scanner; public class WriteThread extends Thread{ private DatagramSocket datagramSocket; private String message = ""; private byte[] bytes = new byte[1024]; private Scanner scanner = new Scanner(System.in); public WriteThread(DatagramSocket datagramSocket){ this.datagramSocket = datagramSocket; } @Override public void run() { super.run(); while (true){ synchronized (WriteThread.class){ System.out.print("输入:"); this.message = this.scanner.nextLine(); } DatagramPacket datagramPacket = null; try { datagramPacket = new DatagramPacket(message.getBytes(StandardCharsets.UTF_8),0, message.length(), new InetSocketAddress(InetAddress.getByName("localhost"),datagramSocket.getPort())); } catch (UnknownHostException e) { e.printStackTrace(); } try { datagramSocket.send(datagramPacket); } catch (IOException e) { e.printStackTrace(); }finally { try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
Lambda表达式是 Java8 中最重要的新功能之一。使用 Lambda 表达式能够替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。 Lambda表达式同时还提高了对集合、框架的迭代、遍历、过滤数据的操做
任何有函数式接口的地方
只有一个抽象方法(Object类中的方法除外) 的接口是函数式接口
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,若是抽象方法的实现刚好可使用调用另一个方法来实现,就有可能可使用方法引用