java基础笔记
第一章 入门须知
1.1 程序开发步骤
- 编写
- 编译:将我们编写的java源文件翻译成jvm认识的class文件,此过程编译器会检查我们所写的程序是否有语法错误
- 运行
1.2 标识符
- 定义:自己定义的内容,如类名,方法名,变量名
- 命名规则:
- 可以包含:**字母,数字,$(美元符号),_(下划线)**
- 不能以数字开头
1.3 数据类型转换
- 自动转换:自动向更适应的类型转换(自动将类型提升)
- 强制转换:随你,但要看能不能转换成功
- 加减运算默认是在int类型下的,所以short类型也会发生自动转换
- short s = 1; s = s + 1;//编译失败
public static void main(String[] args){ byte b1=1; byte b2=2; //对于常数,编译器是知道的,所以会自动得出结果3,从而确定没有越界而顺利赋值 byte b3=1 + 2; //对于变量,编译器不知道值是多少,会进行自动转换,从而报错,出现异常 byte b4=b1 + b2; System.out.println(b3); System.out.println(b4); }
1.4 运算符
- && 短路与:左边是false,右边就不再运算
- || 短路或:左边是true,右边就不再运算
- ! 取反
1.5 方法
- 方法必须定义在一个类中的方法外
- 方法不能定义在方法里
1.6 选择语句
- switch语句中表达式的数据类型可以为
- byte,short,int,char,enum(枚举),JDK7后可以接收字符串
1.7 方法重载
- 同一个类中,方法名相同,参数不同即可(与修饰符和返回值无关)
- 参数不同:个数不同/数据类型不同/顺序不同
- 重载方法调用:jvm通过方法的参数列表,调用不同的方法
1.8 数组
- 定义
int[] arr=new int[4]; int[] arr=new int[]{1,2,3,4}; int[] arr={1,2,3,4};
1.9 java虚拟机的内存分配
- 寄存器:给CPU使用
- 本地方法栈:jvm在使用操作系统功能的时候使用,与我们开发无关
- 方法区:存储可以运行的class文件
- 堆内存:存储对象或者数组,new出来的都存储在堆内存
- 方法栈:方法运行时使用的内存
第二章 面向对象
2.1 定义类
- 成员变量
- 成员方法(把static去掉)
2.2 static关键字
- 作用
- 修饰类变量
- 修饰类方法(静态方法)
- 特点
- 随着类加载而加载,且只加载一次
- 存储于固定的内存区域(方法区中的静态区)
2.3 静态代码块
- 特点
- 在类方法之外
- 随着类的加载而执行一次先于main方法和构造方法的执行
- 作用
- 给类变量进行初始化赋值
2.4 继承
- 特点
- 子类可以直接访问父类中的 非私有 的属性和行为(相当于也是子类的成员变量)
- 若成员变量重名,默认方法的是子类成员变量,若想访问父类的,使用关键字 super
- 成员方法重名-重写
- 要求 返回值类型,方法名,参数列表都相同
- 继承后的特点-构造方法
- 继承执行的过程
- 加载父类的静态变量(是那种一上来就赋了初始值)
- 加载父类的静态代码块
- 加载子类的静态变量
- 加载子类的静态代码块
- 加载父类的成员变量
- 加载父类的构造函数
- 加载子类的成员变量
- 加载子类的构造函数
2.5 抽象类
- 特点
- 抽象类不能实例化
- 抽象类可以由构造方法,供子类创建对象时,初始化父类成员使用
- 抽象类可以不包含抽象方法,
- 抽象类中可以由方法,属性(私不私有都行)
2.6 接口
特点:封装了方法
- 抽象方法
默认方法(JDK8)(public default void fly(){}):可以被继承,可以被重写
- 静态方法(JDK8):只能由接口调用
- 私有方法(JDK9)::只能由默认方法调用
- 私有静态方法(JDK9):只能由默认方法和静态方法调用
- public static final 声明的变量(相当于常量,必须赋值)
- 接口中没有构造方法
- 接口中没有 静态代码块
接口中没有成员变量
2.7 多态
- 向上转型(这是个默认过程)
- 向下转型(需要用户标记强制转换)
- instanceof关键字
变量名 instanceof 数据类型 如果变量属于该数据类型,返回true。 如果变量不属于该数据类型,返回false。 Animal a=new Cat; if(a instanceof Cat){}
2.8 final关键字
- 修饰类:不能被继承
- 修饰方法:不能被重写
- 修饰变量:不能重写赋值
2.9 权限修饰符
- public:权限最高
- protected:同一个包内,不同包的子类可以访问
- default:同一个包内可以访问(不同包的子类不可以访问)
- private:同一类可以访问
2.10 内部类
访问特点
- 内部类可以直接访问外部类的成员,包括私有成员
- 外部类要访问内部类必须要建立内部类对象
外部类名.内部类名 对象名 = new 外部类型().new 内部类型(); 内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名 和$符号 。 比如,Person$Heart.class
2.11 匿名内部类
- 定义:本质是一个带具体实现的父类或父接口的匿名子类对象
- 格式
new 父类名或者接口名(){ // 方法重写 @Override public void method() { // 执行语句 } };
- 使用方法
FlyAble f = new FlyAble(){ public void fly() { System.out.println("我飞了~~~"); } }; //调用 fly方法,执行重写后的方法 f.fly();
2.12 装箱与拆箱
- Java 5后这个过程是自动完成
2.13 泛型(重点)
- 特点:编译时期的语法约束规则,(不满足泛型所规定的约束,编译就都不能通过,高级开发工具会有红色提示)
- 定义格式
- 在创建对象的时候确定泛型
修饰符 class 类名<代表泛型的变量> { } class ArrayList<E>{ public boolean add(E e){ } public E get(int index){ } .... }
ArrayList<String> list = new ArrayList<String>(); //此时 class ArrayList<String>{ public boolean add(String e){ } public String get(int index){ } ... }
- 含有泛型的方法
- 调用方法时,确定泛型的关联
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ } public class MyGenericMethod { public <MVP> void show(MVP mvp) { System.out.println(mvp.getClass()); } } public class GenericMethodDemo { public static void main(String[] args) { // 创建对象 MyGenericMethod mm = new MyGenericMethod(); // 演示看方法提示 mm.show("aaa"); mm.show(123); mm.show(12.45); } }
- 含有泛型的接口
- 定义类时确定泛型的类型
- 始终无法确定泛型的类型,则在创建对象时确定泛型类型
修饰符 interface接口名<代表泛型的变量> { } public interface MyGenericInterface<E>{ public abstract void add(E e); public abstract E getE(); } public class MyImp1 implements MyGenericInterface<String> { @Override public void add(String e) { // 省略... } @Override public String getE() { return null; } } //还是无法确定泛型 public class MyImp2<E> implements MyGenericInterface<E> { @Override public void add(E e) { // 省略... } @Override public E getE() { return null; } } /* * 使用时确定泛型 */ public class GenericInterface { public static void main(String[] args) { MyImp2<String> my = new MyImp2<String>(); my.add("aa"); } }
泛型通配符
泛型的上限:
- 格式:
类型名称 <? extends 类 > 对象名称
- 意义:
只能接收该类型及其子类
泛型的下限:
- 格式:
类型名称 <? super 类 > 对象名称
- 意义:
只能接收该类型及其父类型
2.14 增强for
- 格式
for(元素的数据类型 变量 : Collection集合or数组){ //写操作代码 } //使用增强for遍历 for(String s :coll){//接收变量s代表 代表被遍历到的集合元素 System.out.println(s); }
3.15 可变参数
- 格式
修饰符 返回值类型 方法名(参数类型... 形参名){ } 等价于 修饰符 返回值类型 方法名(参数类型[] 形参名){ }
第三章 API
3.1 String类
- 特点
- 字符串的值被创建后不能修改
- 因为不能修改,所以String对象可以共享
- 方法
public boolean equals (Object anObject) public boolean equalsIgnoreCase (String anotherString) public char[] toCharArray () public byte[] getBytes () public String replace (CharSequence target, CharSequence replacement) public String[] split(String regex) //按照给定的正则规则分割成字符串数组
3.2 Arrays类(工具类)
- 方法
public static String toString(int[] a) public static void sort(int[] a) //默认升序排序
3.3 Math类(工具类)
- 方法
public static double abs(double a) //求绝对值 public static double ceil(double a) public static double floor(double a) public static long round(double a)
3.1 ArrayList
- 父类
- List
- 实例化
List<String> list = new ArrayList<>();
- 成员方法
public boolean add(E e) public E remove(int index) public E get(int index) public int size()
3.4 Object类
- 所有类默认继承该类
- 方法
public String toString() //经常被重写 public boolean equals(Object obj) //默认是地址比较,而我们经常把他改成值比较,然后再配合hasCode()方法完成判断对象是否相同
3.5 Objects类(工具类)
- 静态方法
//判断两个对象是否相等 public static boolean equals(Object a, Object b){ return (a == b) || (a != null && a.equals(b)); }
3.6 Date类
构造函数和方法
public Date() public Date(long date) public long getTime() System.out.println(new Date()); // Tue Jan 16 14:37:35 CST 2018
3.7 DateFormat类(抽象类)
- 作用:将Date对象和String对象之间来回转化
- 格式化(将Date对象转化为指定格式的String对象)
- 解系:按照指定格式,从String对象转换为Date对象
- 实现类:SimpleDateFormat
- 实现类构造方法和方法
- 标识字母:
- y:年
- M:月
- d:日
- H:时
- m:分
- s:秒
public SimpleDateFormat(String pattern) //构造方法,参数为日期格式 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public String format(Date date) public Date parse(String source) DateFormat df = new SimpleDateFormat("yyyy年MM月dd日"); String str = "2018年12月11日"; Date date = df.parse(str);
3.8 Calendar类(抽象类)
静态方法
public static Calendar getInstance() Calendar cal = Calendar.getInstance();
常用方法
public int get(int field) public void set(int field, int value) public abstract void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。 public Date getTime()
field选项
YEAR:年 MONTH:月(从0开始,可以+1使用) DAY_OF_MONTH:月中的天(几号) HOUR:时(12小时制) HOUR_OF_DAY:时(24小时制) MINUTE:分 SECOND:秒 DAY_OF_WEEK:周中的天(周几,周日为1,可以-1使用) Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, 2020); cal.add(Calendar.DAY_OF_MONTH, 2); // 加2天 cal.add(Calendar.YEAR, -3); // 减3年
3.9 System类
- 静态方法
public static long currentTimeMillis() public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length): public static void main(String[] args) { int[] src = new int[]{1,2,3,4,5}; int[] dest = new int[]{6,7,8,9,10}; System.arraycopy( src, 0, dest, 0, 3); /*代码运行后:两个数组中的元素发生了变化 src数组元素[1,2,3,4,5] dest数组元素[1,2,3,9,10] */ }
3.10 StringBuilder类
- 特点
- 默认16个字符空间,超过自动扩展
- 非线程安全,但速度快
- 构造方法和常用方法
public StringBuilder()//空容器 public StringBuilder(String str) //指定初值的容器 public StringBuilder append(任意类型)//都看成表面上的字符串 public String toString()
3.11 包装类的parseXxx静态方法
int num = Integer.parseInt("100"); short num = Short.parseShort("10"); Byte b = Byte.parseByte("a"); Long num = Long.parseLong("10"); Float num = Float.parseFloat("10.7"); Double num = Double.parseDouble("10.3"); Boolean num = Boolean.parseBoolean("10");
第四章 集合
4.1 集合分类
- Collection(接口)
- List(接口):有序,允许重复元素
- ArrayList:基于数组结构,最常用,查询方便
- LinkedList:基于链表结构(双向链表),增删方便
- Vector
- Set(接口):无序,不允许重复元素
- HashSet:基于哈希表实现(哈希表基于数组,链表,红黑树实现),自定义元素需要重写对象中的hashCode和equals方法,确保集合中对象唯一(被排序的类型需要实现Comparable接口)
- LinkedHashSet:实现了存放元素顺序的要求,但还是要求元素不能重复
- TreeSet
- List(接口):有序,允许重复元素
- Map(接口):每次存储一对儿元素(这一对元素为一个整体即 键——值),键值唯一
- TreeMap
- HashMap:存储的自定义键的类型需要重写hashCode方法和equals方法
- TableMap:链表加哈希表,保证了存储先后顺序,保证了键的唯一,
4.2 Connection接口
- 方法
public boolean add(E e) public void clear() public boolean remove(E e) public boolean contains(E e) public boolean isEmpty() public int size() public Object[] toArray() public Iterator<E> iterator() //返回的是迭代器接口的实现类
4.3 Iterator迭代器(接口)
- 方法
- public E next():返回迭代的下一个元素。 - public boolean hasNext():如果仍有元素可以迭代,则返回 true。
4.4 List接口
- 方法
public void add(int index, E element) public E get(int index) public E remove(int index) public E set(int index, E element)
4.5 LinkedList类(可以作为堆栈)
- 方法
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
4.6 Collections(工具类)
- 静态方法
public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。 public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。 public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。 public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排 序。
4.7 Comparator比较器(接口)
- 抽象方法
public int compare(T o1, T o2) Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.charAt(0) ‐ o1.charAt(0); } }); 两个对象比较的结果有三种:大于,等于,小于。 如果要按照升序排序, 则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)(即o1大于o2为真) 如果要按照 降序排序 则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)(即o2大于o1为真)
4.8 Map接口
- 方法
public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。 public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的 值。 public V get(Object key) 根据指定的键,在Map集合中获取对应的值。 public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。 public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
- Entry键值对对象
- 方法
public K getKey() :获取Entry对象中的键。 public V getValue() :获取Entry对象中的值 Set<Entry<String,String>> entrySet = map.entrySet(); // 遍历得到每一个entry对象 for (Entry<String, String> entry : entrySet) { // 解析 String key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"的CP是:"+value); }
4.9 JDK9关于集合的新特性
- 为List,Set,Map增加了静态工厂方法,可以创建集合的不可变实例
Set<String> str1=Set.of("a","b","c"); //str1.add("c");这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合 System.out.println(str1); Map<String,Integer> str2=Map.of("a",1,"b",2); System.out.println(str2); List<String> str3=List.of("a","b"); System.out.println(str3); //生成的集合是不可修改的
1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法,比如 HashSet,ArrayList等待; 2:返回的集合是不可变的;
4.10 Properties类
- 特点
- 继承于Hashtable,属于Map的子类
- 构造方法与方法
public Properties() :创建一个空的属性列表。 public Object setProperty(String key, String value) : 保存一对属性。 public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。 public Set<String> stringPropertyNames() :所有键的名称的集合。 public void load(InputStream inStream) : 从字节输入流中读取键值对。
第五章 异常
5.1 异常体系
- Throwable:异常的根类
- Error:无法通过处理的错误,如内存溢出,如系统崩溃
- Exception:可以处理的异常,(这是我们常说的异常)
- 编译时期异常:编译时期就会检查,如果不处理则编译失败(checked异常)
- 运行时期异常:编译器不会报错,但运行时会出错(runtime异常),我们自己根据情况选择是否要去处理(如IO异常我们需要处理,去释放资源,不然会导致系统奔溃)
5.2 Throwable类
- 方法
public void printStackTrace() :打印异常的详细信息 public String getMessage() :获取发生异常的原因 public String toString() :获取异常的类型和异常描述信息(不用)。
5.3 异常的处理
- 抛出异常throw
- 声明异常throws
- 捕获异常try...catch
- finally代码块
5.5 异常主义事项
- 多个异常如何使用捕获
- 多个异常分别处理
- 多个异常一次捕获,多次处理
- 多个异常一次捕获,一次处理
- 运行时异常被抛出可以不处理。即不捕获也不声明抛出。 (如除以0)
- 如果finally有return语句,永远返回finally中的结果,避免该情况。
- 子类不能抛出比父类抛出范围更大的异常
- 父类方法没有抛出异常,则子类也不能抛出异常,如果有异常,则只能捕获
第六章 多线程与Lambda表达式
6.1 多线程编程
- 概念
- 高内聚低耦合的情况下线程操作资源类
- 不同的线程操作着同一个资源类对象
6.2 创建线程类
- 通过继承Thread类创建多线程(但真正企业中不会这么用)
- 重写Thread的run方法
- 创建Thread的子类实例,即线程对象
- 调用start()方法启动线程
public class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() {...} } public class Demo01 { public static void main(String[] args) { MyThread mt = new MyThread("新的线程!"); mt.start(); } }
- 实现Runnable接口创建多线程(重点,企业中做法)
- 定义Runnable接口的实现类(进阶:通过匿名内部类创建多线程)
- 作为参数传入Thread对象中
- Thread的对象调用start方法
- 即通过实现Runnable接口创建多线程的好处
- 匿名内部类可以访问外部类中的成员,所以为多个线程共享资源打下来很好的基础。不是匿名内部类则可以通过set方法或构造方法将资源变量(是引用型变量)传入。
- 增加健壮性,实现了解耦
- 线程池中只能存放实现Runnable或Callable类线程,不能直接放继承Thread的类
public static void main(String[] args) { //共享资源 final Ticket ticket = new Ticket(); new Thread(new Runnable() { public void run() { for (int i = 0; i < 1000; i++) { //内部类可直接访问 ticket.sale(); } } }, "thread01").start(); }
6.3 Thread类
- 构造方法
public Thread() :分配一个新的线程对象。 public Thread(String name) :分配一个指定名字的新的线程对象。 public Thread(Runnable target) :分配一个带有指定目标新的线程对象。 //重点掌握,这种最常用 public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字
- 常用方法
public String getName() :获取当前线程名称。 public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。 public void run() :此线程要执行的任务在此处定义代码。 留给子类重写 public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。 public static Thread currentThread() :返回对当前正在执行的线程对象的引用
6.4 线程同步(同步都是加再资源类上的,然后资源类还需要实现runnable接口)
- 同步代码块
- 同步方法
- 锁机制(重点,这个企业用)
//同步代码块 synchronized(同步锁){ 需要同步操作的代码 } //同步方法 public synchronized void method(){ 可能会产生线程安全问题的代码 }//对于静态方法,同步锁是该类的字节码对象(类名.class),对于非静态方法,就是this
public class Ticket implements Runnable{ private int ticket = 100; Lock lock = new ReentrantLock(); @Override public void run() { while(true){ lock.lock(); 要上锁部分的代码 lock.unlock(); } } }
6.5 线程的状态(Thread.State枚举类)
- new:新建的状态
- runnable:获得锁的状态且运行
- blocked:没获得锁时的状态(无法运行)
- waiting(无限等待):会释放掉锁(通过调用锁的wait方法进入无限等待,调用锁的notify方法可以解除无限等待)
- timed waiting(计时等待)
- teminated(终止)
6.7 锁对象的方法(继承于object)
- wait()
- wait(long time)
- notify()
- notifyAll()
6.8 线程池
线程池的顶级接口
EXecutor:但严格意义上说它是产生线程池的工具类的接口
Executors:线程池的工具类
静态方法:
public static ExecutorService newFixedThreadPool(int nThreads) //获取线程池对象
ExecutorService:线程池接口,通过Executors的静态方法获取实现该接口的实例对象
方法
public Future<?> submit(Runnable task) :获取线程池中的某一个线程对象,并执行 Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用 public void shutdown(); 关闭线程池
public class ThreadPoolDemo { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象 MyRunnable r = new MyRunnable(); service.submit(r); // 再获取个线程对象,调用MyRunnable中的run() service.submit(r); service.submit(r); service.shutdown(); //关闭线程池 } }
6.9 Lambda使用前提
- 使用Lambda表达式前提是要有函数式接口
- 什么是函数式接口
- 接口中只允许有且仅有一个抽象方法。
- 我们将这个函数式接口的匿名内部类的实现方式通过Lambda表达式来构造出来(而不是new)
- 使用Lambda必须具有上下文推断。
- 即方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例
- Lambda表达式操作后来其实是生成了一个匿名内部类
- Lambda表达式的标准格式:
(参数类型 参数名称) ‐> { 代码语句 } //虽然能简写,但是这个是规范,最好使用这样
6.10 Lambda省略规则(不建议)
- 小括号内参数的类型可以省略
- 如果小括号内有且仅有一个参,则小括号可以省略;
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号
public static void main(String[] args) { invokeCook(() ‐> System.out.println("吃饭啦!")); //省略了大括号 }
第七章 文件与流
7.1 File类
- 构造方法
public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。 public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例
常用方法
public String getAbsolutePath() :返回此File的绝对路径名字符串。 public String getPath() :将此File转换为路径名字符串。 public String getName() :返回由此File表示的文件或目录的名称。 public long length() :返回由此File表示的文件的长度
判断功能方法
public boolean exists() :此File表示的文件或目录是否实际存在。 public boolean isDirectory() :此File表示的是否为目录。 public boolean isFile() :此File表示的是否为文件。
创建删除功能的方法
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。 public boolean delete() :删除由此File表示的文件或目录。 public boolean mkdir() :创建由此File表示的目录。 public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录
目录遍历方法
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。 public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。 public File[] listFiles(FileFilter) :返回一个File数组,表示该File目录中的满足过滤器的文件
FileFilter接口
抽象方法:
boolean accept(File pathname) :测试pathname是否应该包含在当前File目录中,符合则返回true
代码实现
public class DiGuiDemo4 { public static void main(String[] args) { File dir = new File("D:\\aaa"); printDir2(dir); } public static void printDir2(File dir) { //匿名内部类实现 File[] files = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().endsWith(".java")||pathname.isDirectory(); } }); // 循环打印 for (File file : files) { if (file.isFile()) { System.out.println("文件名:" + file.getAbsolutePath()); } else { printDir2(file); } } } }
7.2 (顶级)IO流
- 字节流
- InputStream
- FileInputStream
- BufferedInputStream
- OutputStream
- FileOutputStream
- BufferedOutputStream
- InputStream
- 字符流
- Reader
- FileReader
- BufferedReader
- Writer
- FileWriter
- BufferedWriter
- Reader
7.3 OutputStream抽象类
- 方法
public void close() :关闭此输出流并释放与此流相关联的任何系统资源。 public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。 public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。 public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。 public abstract void write(int b) :将指定的字节输出流。
7.4 FileOutputStream类
- 构造方法
//这两种默认不支持追加,没有指定文件会自动创建 public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。 public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。 public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的文件。参数2表示能否追加数据(不能则每次都是先清空在写入数据) public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。
7.5 InputStream抽象类
- 方法
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。 public abstract int read() : 从输入流读取数据的下一个字节。 public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
7.6 FileInputStream类
- 构造方法
FileInputStream(File file) ://路径下没有文件会抛异常 FileInputStream(String name) : //路径下没有文件会抛异常
7.7 Reader抽象类
- 方法
public void close() :关闭此流并释放与此流相关联的任何系统资源。 public int read() : 从输入流读取一个字符。 public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中
7.8 FileReader类
- 构造方法
FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。 FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
7.9 Writer抽象类
- 方法
void write(int c) 写入单个字符。 void write(char[] cbuf) 写入字符数组。 abstract void write(char[] cbuf, int off, int len) void write(String str) 写入字符串。 void write(String str, int off, int len) void flush() 刷新该流的缓冲。 void close() 关闭此流,但要先刷新它。
7.10 FileWriter类
- 构造方法
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。 FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
7.11 字节缓冲流
- 构造方法
public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。 public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流 // 创建字节缓冲输入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt")); // 创建字节缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
7.12 字符缓冲流
- 构造方法
public BufferedReader(Reader in) :创建一个 新的缓冲输入流。 public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。 // 创建字符缓冲输入流 BufferedReader br = new BufferedReader(new FileReader("br.txt")); // 创建字符缓冲输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
- 特有方法
BufferedReader: public String readLine() : 读一行文字。 BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。
7.13 转换流
InputStreamReader类:是Reader的子类
构造方法
InputStreamReader(InputStream in) : 创建一个使用平台默认字符集的字符流。 InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。即按指定编码读取流中的内容。
OutputStreamWriter类:是Writer的子类
构造方法
OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。 OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。,即按指定的字符类型输出
7.14 序列化
ObjectOutputStream类:将java对象的原始数据类型写到文件中,实现对象的持久存储
构造方法
public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream
具体操作
- 被序列化的对象其所属类需要实现Serializable接口,该接口是个标记接口
- 若某个属性不想被序列化,可以使用transient关键字修饰
方法
public final void writeObject (Object obj) : 将指定的对象写出
ObjectInputStream类:反序列化操作
构造方法
public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream
方法
public final Object readObject () : 读取一个对象。
注意
- 反序列化对象,必须能够找到其class文件的类,若找不到,会抛异常
- 若其class文件的类在序列化对象后发生修改,也会抛出异常
- Serializable接口给需要序列化的类提供了一个序列版本号 serialVersionUID,用于验证序列化的对象与对应类的版本是否匹配
7.15 打印流
PrintStream类
构造方法
public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流 System.out就是一个PrintStream类型,只不过它是向控制台打印。
public static void main(String[] args) throws IOException { // 调用系统的打印流,控制台直接输出97 System.out.println(97); // 创建打印流,指定文件的名称 PrintStream ps = new PrintStream("ps.txt"); // 设置系统的打印流流向,输出到ps.txt System.setOut(ps); // 调用系统的打印流,ps.txt中输出97 System.out.println(97); }
第八章 网络编程
Socket类:用于客户端套接字
构造方法和成员方法
public Socket(String host, int port)//连上指定主机的端口上 public InputStream getInputStream() : 返回此套接字的输入流 public OutputStream getOutputStream() : 返回此套接字的输出流。 public void close() :关闭此套接字。 //这个也会将流给关闭 public void shutdownOutput() : 禁用此套接字的输出流
ServerSocket类:用于服务端套接字
构造方法和成员方法
public ServerSocket(int port) //指定服务端的端口号 public Socket accept() :侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法 会一直阻塞直到建立连接
服务端实现
public class ServerTCP { public static void main(String[] args) throws IOException { System.out.println("服务端启动 , 等待连接 .... "); // 1.创建 ServerSocket对象,绑定端口,开始等待连接 ServerSocket ss = new ServerSocket(6666); // 2.接收连接 accept 方法, 返回 socket 对象. Socket server = ss.accept(); // 3.通过socket 获取输入流 InputStream is = server.getInputStream(); // 4.一次性读取数据 // 4.1 创建字节数组 byte[] b = new byte[1024]; // 4.2 据读取到字节数组中. int len = is.read(b); // 4.3 解析数组,打印字符串信息 String msg = new String(b, 0, len); System.out.println(msg); //5.关闭资源. is.close(); server.close(); } }
- 客户端实现
public class ClientTCP { public static void main(String[] args) throws Exception { System.out.println("客户端 发送数据"); // 1.创建 Socket ( ip , port ) , 确定连接到哪里. Socket client = new Socket("localhost", 6666); // 2.获取流对象 . 输出流 OutputStream os = client.getOutputStream(); // 3.写出数据. os.write("你好么? tcp ,我来了".getBytes()); // 4. 关闭资源 . os.close(); client.close(); } }
第九章 函数式接口
- @FunctionalInterface注解
- 注解在接口上,给接口进行约束
- 匿名内部类会产生一个class文件,但Lambda表达式不会,有优势(速度快些吧)
- Lambda表达式延迟执行
- 常用的函数式接口
- 暂时不想学
第十章:流式编程
- 不想学了
来源:https://www.cnblogs.com/liujiashun/p/12194674.html