继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

自己看的JAVA笔记,定期学习更新

没茅台
关注TA
已关注
手记 3
粉丝 1
获赞 49
通过Set管理集合
  • Set接口及其实现类
    • set是元素无序并且不可重复的集合,被称为集
    • HashSet ----哈希集,是set的一个重要实现类

List 为有序的
Set 为无序的

  • 循环遍历Set中的元素
    • foreach
    • iterator 迭代器 </br>
      <font color= "red">不能像List方法那样调用他的get()方法 </font>
      因为Set本身是无序的,不可能去查询位置上的某个元素 </br>

Set中添加某个对象,无论添加多少次,最终只会保留一个该对象的引用,并且保存的是第一次添加的那个
Set中可以添加NULL对象

Map和HashMap
  • Map接口

    • Map接口提供了一种映射关系,其中的元素是以键对值(key - value)的形式存储的,能够实现根据key快速查找value
    • Map中的键值对是以Entry类型的对象实例形式存在
    • 键(key)不可重复, value值可以
    • 一个value值可以和很多key值形成映射关系,但是一个key值能能对应一个value值
    • Map接口提供了分别返回key值集合、value值集合以及 entry(键值对)集合的方法
    • Map支持泛型,形式为Map<K,V>
      k为Key值的类型,v为value值的类型

    • HashMap类
    • HashMap类是Map中的一个重要的实现类,也是最常用的,基于哈希表实现
    • HashMap中的entry对象是无序排列的
    • key值和value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key值不可以)

    indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
    lastIndexOf(object o) 返回此列表中最后一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。

    • 泛型不能使用基本类型,若果要使用,只能用基本类型的包装类
    • byte ---- Byte
    • short ----- Short
    • int ----- Integer
    • long ---- Long
    • float -----Float
    • double ----- Double
    • char ----- Character
    • boolean ------ Boolean
    Collections工具类

    是JAVA集合框架中用来操作集合对象的工具类
    也是JAVA集合框架的成员
    Collections中定义了一个sort()方法,用来对集合进行排序

    要用Collections.sort()方法进行排序,必须实现Comparble接口

    Comparble---------默认比较规则
    <font color=red> Compartor---------临时比较规则 </font>

  • Comparble接口------可比较的

    • 定义该接口表示:这个类的大小可以比较大小,可以进行自然排序
    • 定义了默认的比较规则
    • 其实现类需实现compareTo()方法
    • compareTo()方法返回正数代表大,负数代表小,0代表相等
  • Compartor-------比较接口工具
    • 用于定义临时比较规则,而不是默认比较规则
    • 其实现类需要实现compare()方法
    • Comparbl和Compartor都是JAVA集合框架的成员
JAVA多线程
  • 创建线程的第一种方法:

    • 1.定义类继承Thread
    • 2.重写Thread中的run方法
      目的:将自定义的代码存储在run中,让线程执行
    • 3.创建一个继承了Thread线程类对象,相当于创建了一个线程
    • 4.调用线程的start()方法
      • 该方法有两个作用
      • 1.启动线程
      • 2.调用run方法

    线程是一个子任务,CPU以不确定的方式,或者说是以随机的时间来调用线程中的run方法,所以
    在使用多线程技术时,代码的运行结果与代码执行顺序或调用顺序是无关的。
    因为多个线程都在获取CPU的使用权,CPU执行到谁,谁就执行
    在某个时刻,只能有一个程序在运行
    CPU在做着快速的切换,以达到看上去是同时运行的效果
    我们可以形象的把多线程的运行形容为互相在抢夺CPU的资源
    这就是多线程的一个特性:随机性

    线程都有自己默认的名称
    Thread-编号 该编号从0开始
    static Thread currentThread():获取当前线程对象
    getName():获取线程名称

    设置线程名称:setName或者构造函数传值super关键字

  • 创建线程的第二种方式:

    • 1.定义实现Runnable接口。
    • 2.覆盖Runnable接口中的run方法。
      将线程要运行的代码存储在run方法中
    • 3.通过Thread类建立线程对象 。
    • 4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
      为什么要将Runnable接口的子类对象传递给Thread的构造函数。
      因为自定义的run方法所属对象是Runnable接口的子类对象
      所以要让线程去执行指定对象的run方法。
    • 5.调用Thread类对象的start方法开启线程并调用Runnable接口子类的run方法。

    实现方式和继承方式有什么区别?
    实现方式的好处:避免了单继承的局限性
    在定义线程时,建议使用实现方式。

    JAVA对于多线程的安全问题提供了专业的处理方式
    就是同步代码块

      synchronized(对象){
        //需要被同步的代码块
      }

    对象如同锁,持有锁的线程可以再同步中执行
    没有持有锁的线程即使获取CPU的执行权,也进不去,因为没有获取锁

    
    public class Ticket implements Runnable{
    private  static  int tick = 200;
    Object obj =new Object();
    public void run(){
               while (true){
                   synchronized (obj) {
                       if (tick > 0) {
                           try {
                               Thread.sleep(5);
                               //延迟操作5毫秒
                           } catch (Exception e) {
                           }
                           System.out.println(Thread.currentThread().getName() + "----" + tick);
                           tick--;
                       }
                   }
               }
     }

}


``` java
 public class Test {
    public static void main(String[] args)  {

            Ticket t  = new Ticket();
            Thread  t1 = new Thread(t);
            Thread  t2 = new Thread(t);
            t1.start();
            t2.start();
    }
}

同步的前提:

  1. 必须要有两个或者两个以上的线程。
  2. 必须是多个线程使用一个锁

必须保证同步中只有一个线程在执行
优点:解决了线程的安全问题
缺点:多个线程都需要判断锁,较为消耗资源

同步的另一种方法-------同步函数
只要将synchronized作为函数的修饰符就行了
函数都需要被对象调用,那么函数都有一个所属对象引用,就是this。
所以同步函数使用的锁是this。

同步函数改写了Ticker类

public class Ticket implements Runnable{
    private  static  int tick = 200;
    //Object obj =new Object();
    public void run(){
                while (true){
                   this.show();
                    }

      }
      public void show(){
          if (tick > 0) {
              try {
                  Thread.sleep(5);
              } catch (Exception e) {
              }
              System.out.println(Thread.currentThread().getName() + "----" + tick);
              tick--;
          }
      }

}

通过验证,同步函数被静态修饰后,使用的锁不再是this,因为静态方法中也不可定义this
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
类名.class 该对象的类型是Class。
静态的同步方法,使用的锁是该方法所在类的字节码文件对象 类名.class

java线程间通讯

java线程间通讯,其实就是多个线程在操作同一个资源,只是操作的动作不一样
wait:
notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以都使用在同步中,因为同步中才有锁
为什么这些方法要定义在Object类中呢?
因为这些方法在操作同步中线程时,都<font color =red >必须要标识它们所操作线程持有的锁</font>
只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。

JDK1.5中提供了多线程升级的解决方案
将同步的synchronized替换成现实Lock操作
将Object中的wait,notify,notifyAll替换成了Condition对象。
该对象可以Lock锁,进行获取

停止线程

stop方法已经过时
只有让run方法结束,线程才会结束
只要控制住循环,就可以让run方法结束,也就是线程结束
当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对线程冻结进行清楚
强制让线程恢复到运行状态中来,这样子就可以操作标记让线程结束
Thread提供了interrupt()方法。
如:

StopThread类
import Book.Run;

/**
 * Created by asus on 2016/11/18.
 */
public class StopThread  implements Runnable {
    private boolean flag = true ;
    public synchronized void run(){
        while (flag){
            try{
              this.wait();
            }catch(InterruptedException e ){
                //线程被强行打断后,就会报异常,这时就可以通过操作flag让while循环停止,从而结束线程
                System.out.println(Thread.currentThread().getName()+".....Exception");
                flag =false;
            }
            System.out.println(Thread.currentThread().getName()+"....run");
        }
    }

}
StopThreadDemo类
public class StopThreadDemo {

    public static void main(String[] args){
            StopThread st =new StopThread();
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(st);

        t1.start();
        t2.start();

        int num = 0 ;
        while(true){
            if (num++  ==60){
            t1.interrupt();//强行打断冻结的线程,让线程运行
            t2.interrupt();
            break;
            }

        System.out.println(Thread.currentThread().getName()+"....."+num);
    }
    System.out.println("over");
    }

}
JAVA I/O 输入输出流

1.解决编码问题
2.file类的使用
3.RandomAccessFile的使用
4.字节流的使用
5.字符流的使用
6.对象的序列化和反序列化

  • 字节流抽象基类
    • InputStream
    • OutputStrea
  • 字符流的抽象基类

    • Reader
    • Writer
      <font color =red>
      注:
      由这4个子类派生出来的子类名称都是以其父类名作为子类名的后缀
      如:InputStream的子类FileInputStream.
      Reader的子类FileReader</font>
  • Writer
    • writer()方法:写入字符串
    • flush()方法:刷新流数据的缓冲,将要写入的字符串写入到指定文件中
    • close()方法:关闭该流,但是会先刷新一次,关闭后无法进行流操作
打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP