1.3 File类的获取方法 public String getAbsolutePath();//获取该File对象的绝对路径 public String getPath();//获取该File对象构造时,传入的对象 public String getName();//获取该File对象的代表的文件或文件夹的名字 public long length();//获取该File对象的文件字节
4.2 字节输出流 顶层父类(抽象类) 共性方法: public void close();//关闭该流,释放资源 public void flush();//刷新缓冲区(主要字符流使用)
public void write(int b);//一次写一个字节,输入是int,但是只能写一个byte的大小,即最大127 public void write(byte[] bs);//一次写一个字节数组 public void write(byte[] bs,int startIndex,int len);//一次写这一个字节数组中的一部分
4.4 FileOutputStream类的使用 文件的字节输出流(向文件中写字节数据)
•构造方法 public FileOutputStream(String path);//必须传入文件的路径 public FileOutputStream(File file);//必须传入文件的File对象
publicclassFileOutputStream_Demo04 { publicstaticvoidmain(String[] args)throws IOException { FileOutputStreamfos=newFileOutputStream("1.txt",true); for (inti=0; i < 10; i++) { fos.write("java \n".getBytes()); } } }
•flush public void flush();//对于字节输出流没用
•close public void close();//关闭该流,释放资源 一个流使用完毕,及时释放流,别的程序就可以使用该资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicclassFileOutputStream_Demo04 { publicstaticvoidmain(String[] args)throws IOException { FileOutputStreamfos=newFileOutputStream("1.txt", true); for (inti=0; i < 10; i++) { fos.write("java \n".getBytes()); }
fos.close();
while (true) { } //程序不会停止,但是流已关闭,可以对文件进行增删改操作 } }
4.4 字节输入流InputStream 顶层父类(抽象类) 共性方法: public void close();//关闭该流,释放资源 public int read();//一次读一个字节 public int read(byte[] bs);//一次读一个字节数组,返回值表示实际读取的字节个数 public int read(byte[] bs,int startIndex,int len);//一次读一个字节数组的一部分(基本不用)
4.5 FileInputStream的作用 文件的字节输入流(向文件中读字节数据) •构造方法 public FileInputputStream(String path);//必须传入文件的路径 public FileInputStream(File file);//必须传入文件的File对象
工具类中的静态方法:创建一个线程池对象 public static ExecutorService newFixedThreadPool(int nThreads);//用于创建一个具有指定线程个数的线程池对象
如何向线程池中提交任务: 调用ExecutorService接口中规定的方法 public Future submit(Runnable task);//向线程池中提交无返回值的任务 public Future submit(Callable task);//向线程池中提交有返回值的任务,返回Future类型(封装线程执行完毕后结果的那个对象)
三.线程状态 3.1 线程的六种状态(A thread state. A thread can be in one of the following states:) •新建状态-NEW A thread that has not yet started is in this state. 刚创建,且未调用strat方法的状态
•运行状态-RUNNABLE A thread executing in the Java virtual machine is in this state. 处于新建状态的线程start方法之后 可运行状态(就绪) 可运行状态(运行) 注意:只有新建状态的线程才能调用start()
•受(锁)阻塞状态-BLOCKED A thread that is blocked waiting for a monitor lock is in this state. 状态进入: 线程运行过程中,遇到同步方法,线程需要锁对象,但是锁对象已被其他线程持有 状态返回: 其他线程释放锁,当前线程抢到锁,才能从锁阻塞回到可运行状态
•限时等待状态-TIMED_WAITING A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. 状态进入: 线程指定到代码调用Thread.slee(毫秒值),线程就处于限时等待状态 状态返回: sleep时间到了,返回RUNNABLE状态
•永久等待-WAITING A thread that is waiting indefinitely for another thread to perform a particular action is in this state. 状态进入: 当前线程必须持有锁对象 调用锁对象的wait()方法 此时线程就会进入永久等待,进入之前,当前线程会自动释放锁对象 状态返回: 其他线程要持有锁(必须锁刚刚进入无限等待的线程释放的锁) 调用锁对象的notify()方法
注意:被唤醒的线程是没有锁对象的,会进入锁阻塞,直到其他线程释放锁对象,才能进入可运行状态
•TERMINATED A thread that has exited is in this state. 当线程任务执行完毕,已退出的线程状态(消亡状态) 注意:处于消亡状态的线程,不能再调用start方法
//create thread newThread(newRunnable() { @Override publicvoidrun() { synchronized (lock) { //get in code block System.out.println("Thread A get into Wating"); System.out.println("Thread A Get Lock"); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } //wake back to task System.out.println("A Wake"); } } }).start();
Thread.sleep(1000);
//New Threak wake up Thread A newThread(newRunnable() { @Override publicvoidrun() { //Same lock Object synchronized (lock) { System.out.println("Thread B Got Lock"); System.out.println("Thread B Wake A Up"); lock.notify(); for (inti=0; i < 10; i++) { System.out.println(i); } } } }).start(); } }
1.6 解决方法3:Lock锁 Lock是一个接口,我们需要使用其实现类ReentrantLock ReentrantLock的API: public ReentrantLock(); public void lock();//加锁 public void unlock();//解锁 格式: ReentrantLock lock = new ReentrantLock(); lock.lock();//加锁 lock.unloc();//解锁
publicclassMythreadextendsThread{ // public static List<Integer> list = new ArrayList<>();//ArrayIndexOutOfBoundsException publicstatic List<Integer> list = newCopyOnWriteArrayList<>();
@Override publicvoidrun() { for (inti=0; i < 10000; i++) { list.add(i); } System.out.println("Done"); } }
publicclassMythreadextendsThread { // public static List<Integer> list = new ArrayList<>(); publicstatic List<Integer> list = newCopyOnWriteArrayList<>(); @Override publicvoidrun() { for (inti=0; i < 10000; i++) { list.add(i); } System.out.println("Done"); } }
b.Thread类的构造方法 public Thread();//无参构造 public Thread(String name);//带有线程名的构造 public Thread(Runnable r);//带有线程任务的构造 public Thread(Runnable r,String name);//即带有线程名字,又有线程任务的构造
c.Thread类的成员方法 public String getName();//获取线程的名字。无参构造,线程会有自己的名字,如Thread0,Thread1 public String setName(String name);//修改线程的名字 public void run();//代表线程要执行的任务,任务有关的代码需要写在此方法中 public void start();//线程只创建并不会执行,必须调用start开启后才会执行任务
public static void sleep(long millis);//让当前线程休眠X毫秒(指Thread.sleep(1000)代码写在哪个线程中,所在的线程就当前线程) public static Thread currentThread();//获取当前线程对象(指Thread.currentThread()代码写在哪个线程中,所在的线程就当前线程)
public static void join();//等待这个线程死亡 public static void setDaemon(boolean on);//将此线程标记为守护线程,当允许的线程都是守护线程时,Java虚拟机将退出
public final int getPriority();//返回此线程的优先级 public final void setPriority(int newPriority);//更改此线程的优先级 线程优先级高,仅表示获取CPU时间片的几率高,并不表示会优先执行
1.4 创建新的线程方式一:继承方式 a. API描述:将类声明为Thread的子类。该子类重写Thread类的run方法。接下来可以分配并启动该子类的实例 b.分析创建步骤: I.创建子类 继承 Thread II.子类中重写run方法(在run中编写线程要执行的任务代码)
4.2 AtomicInteger类示例 a.AtomicInteger是什么:是对int类型变量进程操作原子类 b.AtomicInteger的构造方法:public AtomicInteger(int num); c.AtomicInteger的成员方法: public int getAndIncrement();//就相当于我们的 变量++ public int ncrementAndGet();//就相当于我们的 ++变量
方法名 说明 public void printStackTrace(); 以深红色在控制台打印异常的详细信息(包括异常类型,异常的原因,异常的位置)【最常用】 public String getMessage(); 返回此throwable的详细消息字符串 public String toString(); 获取异常的类型和异常的描述信息 打印方法如下:
1.3 Map接口中定义的通用方法 增:public V put(K key, V value) ;添加一个键值对Entry,返回null 删:public V remove(Object key);根据键Key去删键值对Entry,返回被删除的键值对的值 查:public V get(Object key);根据键Key获取对应的值Value 改:public V put(K key, V value) ;添加一个重复的键时,该方法变为修改,返回修改前的值 其他: public boolean containKey(Object K);判断Map中是否包含该键 public boolean containKey(Object V);判断Map中是否包含该值
1.4 LinkedList的数据结构以及使用 a.LinkedList的方法(7个collection+1个迭代器+4个List接口中的) 有特有方法: public void addFirst(E e);//添加元素到集合首 public void addLast(E e);//添加元素到集合尾 public E getFirst(E e);//获取集合的首元素 public E getLast(E e);//获取集合的尾元素 public E removeFirst(E e);//删除集合的首元素 public E removeLast(E e);//删除集合的尾元素
public void pop(E e);//删除集合中的首元素,底层就是removeFirst public void push(E e);//添加集合中的首元素,底层就是addFirst 源码:
voidlinkLast(E e) { final Node<E> l = last;//一个临时变量,存储最后一个节点 final Node<E> newNode = newNode<>(l, e, null);//创建一个Node对象 last = newNode;//将新Node对象存储到last if (l == null)//如果没有最后一个元素,说明当前是第一个节点 first = newNode;//将新节点存为第一个节点 else l.next = newNode;//否则不是第一个节点,就赋值到当前的last的next成员 size++;//总数量 + 1 modCount++;// }
•LinkedList的get()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public E get(int index) { checkElementIndex(index);//检查索引的合法性(必须在0-size之间),如果不合法,此方法抛出异常 return node(index).item; }
Node<E> node(int index) {//此方法接收一个索引,返回一个Node // assert isElementIndex(index); if (index < (size >> 1)) {//判断要查找的index是否小于size / 2,二分法查找 Node<E> x = first;// x = 第一个节点——从前往后找 for (inti=0; i < index; i++)//从0开始,条件:i < index,此循环只控制次数 x = x.next;//每次 x = 当前节点.next; return x;//循环完毕,x就是index索引的节点。 } else { Node<E> x = last;// x = 最后一个节点——从后往前找 for (inti= size - 1; i > index; i--)//从最后位置开始,条件:i > index x = x.prev;//每次 x = 当前节点.prev; return x;//循环完毕,x就是index索引的节点 } }
//...... final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
Node<K, V>[] tab; //临时变量,存储"哈希表"——由此可见,哈希表是一个Node[]数组 Node<K,V> p;//临时变量,用于存储从"哈希表"中获取的Node int n, i;//n存储哈希表长度;i存储哈希表索引 if ((tab = table) == null || (n = tab.length) == 0)//判断当前是否还没有生成哈希表 n = (tab = resize()).length;//resize()方法用于生成一个哈希表,默认长度:16,赋给n if ((p = tab[i = (n - 1) & hash]) == null)//(n-1)&hash等效于hash % n,转换为数组索 tab[i] = newNode(hash, key, value, null);//此位置没有元素,直接存储 else{//否则此位置已经有元素了 Node<K,V> e; K k; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))//判断哈希值和 e = p;//将哈希表中的元素存储为e elseif (p instanceof TreeNode)//判断是否为"树"结构 e = ((TreeNode<K, V>) p).putTreeVal(this, tab, hash, key, value); else {//排除以上两种情况,将其存为新的Node节点 for (intbinCount=0; ; ++binCount) {//遍历链表 if ((e = p.next) == null) {//找到最后一个节点 p.next = newNode(hash, key, value, null);//产生一个新节点,赋值到链 if (binCount >= TREEIFY_THRESHOLD - 1) //判断链表长度是否大于了8 treeifyBin(tab, hash);//树形化 break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))//跟当前 变量的元素比较,如果hashCode相同,equals也相同 break;//结束循环 p = e;//将p设为当前遍历的Node节点 } } if (e != null) { // 如果存在此键 } }
总结:
Collection { Iterator it = cc.iterator(); public boolean add(E e);添加元素,返回值表示是否添加成功。 public boolean remove(E e);删除元素,返回值表示是否删除成功。 无修改方法。 无查询方法。 public boolean contains(Object obj);判断集合中是否包含某个元素。 public void clear();清空集合(把集合中的元素全部删除,不是把集合置为Null) public boolean isEmpty();判断集合是否为空(指集合中没有元素,而非集合是否为Null) public int size();返回集合中元素的个数 public Object[] toArray();将集合转成数组 } List接口: 特点:有序,有索引,元素可重复 特有方法: add(int index,E e); remove(int index,E e); set(int index,E e); get(int index,E e);
ArrayList: 底层是数组结构 特有方法:无 特点:有序,有索引,元素可重复
LinkedList 底层是链表结构 特有方法: public void addFirst(E e);//添加元素到集合首 public void addLast(E e);//添加元素到集合尾 public E getFirst(E e);//获取集合的首元素 public E getLast(E e);//获取集合的尾元素 public E removeFirst(E e);//删除集合的首元素 public E removeLast(E e);//删除集合的尾元素 public void pop(E e);//删除集合中的首元素,底层就是removeFirst public void push(E e);//添加集合中的首元素,底层就是addFirst 特点:有序,有索引,元素可重复
1.集合的介绍&集合和数组的区别 a.什么是集合 集合就是Java用来保存数据的容器。 b.学过的容器 数组,ArrayList 数组定义: 数据类型[] 变量名 = new 数据类型[数组的长度] 集合定义: ArrayList<数据类型> 变量名 = new ArrayList<数据类型>(); c.数组和集合区别在哪里 I.数组的长度固定,集合的长度可变 II.数组中的元素类型可以是基本类型,也可以是引用类型。 集合中的元素类型必须只能是引用类型,如果想保存基本类型,要写该基本类型对应的写包装类。 例如: ArrayList arr = new ArrayList();
2.集合框架的继承体系
List接口特点: 有序,有索引,元素可以重复
Set接口特点: 无序,无索引,元素不可以重复
3.Collection中的通用方法 增:增加 public boolean add(E e);添加元素,返回值表示是否添加成功。 删:删除 public boolean remove(E e);删除元素,返回值表示是否删除成功。 改:修改 无修改方法。 查:查询 无查询方法。 其他方法: public boolean contains(Object obj);判断集合中是否包含某个元素。 public void clear();清空集合(把集合中的元素全部删除,不是把集合置为Null) public boolean isEmpty();判断集合是否为空(指集合中没有元素,而非集合是否为Null) public int size();返回集合中元素的个数 public Object[] toArray();将集合转成数组
比如: 在JDK1.5之前,创建集合:ArrayList arr = new ArrayList();集合中可以保存任意对象 在JDK1.5时,创建集合:ArrayList<具体的引用类型> arr = new new ArrayList<具体的引用类型>(); 这种参数类型可以用在类、方法和接口中,分别被称为泛型类,泛型方法,泛型接口