java基础学习_Week5

总结:

Map集合的基本功能以及遍历:

基本功能:


     //添加键值对(如果键重复,后面的值会被覆盖)
    v put(K key , v value);
    //判断是否包含指定的键
    boolean containsKey(Object key);
    //判断是否包含指定的值
    boolean containsValue(Object value);
    //判断集合是否为空
    boolean isEmpty();
    //删除Map集合中的键,返回该键对应的值
    V remove(Object key);
    //获取Map集合中所有值得集合
    Collection<v> values():
    //清空Map集合
    void clear();
    

遍历:
方式一(推荐的方式):
获取Map集合中所有键的集合,增强for遍历所有的键,通过键获取值;
Set keySet()—>获取Map集合中所有键的集合
V get(Object key)---->通过键获取值
方式二:(不推荐)
获取所有键值对像Set<Map.Entry<K,V>> entrySet()
Map.Entry<K,V>键值对像就有
K getKey():获取键
V getValue(): 获取值

  //代码示例(方式一遍历)
  public class MapDemo2 {
    public static void main(String[] args) {
        //创建Map集合
        Map<String,String> map = new HashMap<>() ;

        //添加元素
        map.put("杨过","小龙女") ;
        map.put("郭靖","黄蓉") ;
        map.put("令狐冲","岳莹莹") ;
        map.put("陈玄风","梅超风") ;
        map.put("刘备","大乔") ;
        map.put("刘备","小乔") ;

        // Set<K> keySet()--->获取Map集合中所有的键的集合
        Set<String> set = map.keySet();
        //遍历所有的键
        for(String key:set){
            //V get(Object key)------->通过键获取值
            String value = map.get(key);
            System.out.println(key+"="+value);
        }

    }
}

TreeMap集合:
TreeMap<K,V>,集合也是Map集合的子实现类之一,TreeSet集合依赖于TreeMap实现 
 该集合保证元素必须进行排序的,使用TreeMap<K,V>,如果是自定义类型,要保证唯一而且还要排序,底层是一种红黑树结构;
 
 //两种排序方式(构造方法)
 
 //自然排序
 public TreeMap():自然排序,键的这个类型必须实现Comparable接口
 //比较器排序
 Public TreeMap(Compator<K>  comparator):定义一个类实现Compator接口或者使用匿名内部类
//完成自然排序
public class Student implements Comparable<Student> {
    private String name ; //姓名
    private int age ; //年龄

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


//重写CompatorTo(Studen s)

    @Override
    public int compareTo(Student s) {
        按照学生的年龄从小到大排序
        int num = this.age - s.age ;
        //年龄相等,不一定是同一个人
        int num2 = (num==0)?this.name.compareTo(s.name):num ;
        return num2;
    }
}

比较器排序示例:

匿名内部类
 */
public class TreeMapDemo {
    public static void main(String[] args) {
        //TreeMap<Student,String>: K:学生类型 ,V: 爱好 String类型
        //按照学生的年龄从小到大排序
        //接口匿名内部类的方式
        TreeMap<Student,String> tm = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //主要条件:按照年龄从大到小
                int num = s2.getAge()-s1.getAge() ;
                //年龄相等,比较姓名内容是否一致
                int num2 = (num==0)?s1.getName().compareTo(s2.getName()):num;
                return num2;
            }
        }) ;//比较器排序

java中的自动拆装箱:

定义:

自动拆装箱分为拆箱和装箱:
   拆箱:把包装类转换成对应的基本数据类型
   装箱:就是将基本数据类型转换成对应的包装类类型

原理:

 1)valueOf():所有的包装都有多个相同的方法,其中有一个为valueOf();这个方法就是将基本数据类型转换成对应的包装类类型,也可以使用包装类的构造方法直接转换;
2) xxxValue(),其中xxx代表8大基本数据类型,该方法就是将包装类类型转换成对应的基本数据类型

应用:

1)集合
    集合是不接受存放基本数据类型的,但是在实际开发中一个Integer类型的集合是可以直接add一个int变量的,在这个过程就是自动装箱;
    List<Integer> list = newArrayList<>();
    int i= 1 ';
    list.add(i); //着一步直接完成自动装箱
    实际过程是list.add(Integer.valueOf(i);
  2)比较
    我们经常使用包装类与基本数据类型进行比较运算,得到一个布尔值,再进行不同的业务逻辑,这个过程是先将包装类转换成基本数据类型再进行比较大小
 3)运算
   两个包装类进行四则运算时,会将包装类转换成基本数据类型再进行运;

问题:

包装类自动拆装箱的时候也要注意:
1)有些场景会自动进行拆装箱,由于自动拆箱,如果包装类对象为null,那么那么自动拆箱是就可能抛出NPE(空指针异常)
2)如果一个for循环中有大量拆装箱操作,会浪费很多资源
3)包装类进行比较,在-128- 127可以用 == ,这个范围之外需要使用equals进行比较,因为包装类存在静态缓冲区范围为-128 - 127 ,所以在不明确范围的时候避免出现异常,最好使用equals方法比较

扩展:

 基本数据类型对应的包装类类型:
 byte  ----------->   Byte
 short  ----------->  Short
 int    ----------->    Integer
 char ------------>    Character
 long ------------>     Long
 boolean ----------->Boolean
 double -------------> Double
 float --------------->  Float

静态导入:

jdk5提供的新特性:

增强for循环,自动拆装箱,静态导入(导入方法的级别,前提是这个类的方法是静态的),可变参数(方法的形式参数有多个可以使用...表示多个参数)

静态导入:

 导入方式:import static包名.类名.静态方法名:

注 意:

 如果我们在使用静态导入的时候,导入方法级别,前提是自定义的方法名不能和他冲突,如果冲突,系统就不知道这个方法是自定义的还是jdk提供的这个类的方法,此时静态导入就不能用了,所以就需要显示的指明是哪个类

mport static java.lang.Math.abs ; import static java.lang.Math.max; import static java.lang.Math.random; public class Demo { public static void main(String[] args) { 
//静态导入(导入方法的级别,前提是这个类的方法静态的) //java.lang.Math:针对数学运行的工具类
//public static int abs(int a):求一个int类型的绝对值 System.out.println(Math.abs(-10)); System.out.println("--------------------------------"); //为了书写更简单,这个类是java.lang包下不需要导包,但是每次使用方法的 时候比较麻烦,类名.方法名() //优化:jdk5提供静态导入
// System.out.println(abs(-100)); System.out.println(java.lang.Math.abs(-100)); 
//指明 :使用的Math类的 abs方法
//获取最值public static int max(int a,int b) System.out.println(max(10,20)); int num = (int) (random()*10+1); 
System.out.println(num); } public static int abs(int a){//方法名 abs return a; 
} }

进程和线程的概念:
 线程是依赖于进程的:
     1)进程是能够调用系统资源的独立单元,通过任务处理器查看到后台进程有哪些
     多进程的意义:
     现在计算机都是多进程的,可以打游戏的同时,再听音乐:这两个进程是同事的吗?  并不是,其实多个进程在内存中不断进行高效切换,感觉是同时进行的(多进程是为了提高CPU的使用率)
  2)线程:  
    是进程中的最小执行单元!一个线程就相当于一个进程中的某个任务

Jvm是多线程的吗?(面试题)

Jvm(java虚拟机)是多线程的,至少有两条线程
main --- 主线程(用户线程)
还有不断地创建对象,new.....堆内存中的信息需要被gc()垃圾回收器回收线程,帮助程序员,回收美有更多引用的对象,释放空间

java能够直接开启多线程吗?(面试题)

 Java不能直接开启多线程,线程是依赖于进程存在的必须有进程才能有线程!
 而创建进程----->需要创建系统资源,java语言不能直接创建系统资源的,只有C语言底层语言才能够操作系统资源,最底层的还是非java语言实现的,只是jdk为了使用方便将一些操作线程的东西方在了Thread类中,但是里面的非部分功能也是非java语言实现的
 
 start()---->开启线程的方法,底层依赖于start()----被native修饰:非java 语言实现的(表示本地方法----跟系统相关的)
1,实现线程的创建方式第一种:(继承关系)

实现步骤

 1)自定义一个类,继承自Thread(jdk提供的线程类)
 2)在自定义的类中重写Thread类的run方法
 3)在main线程(主线程,或者用户线程 )创建当前自定义类对象------->就是线程对象,启动线程即可
 //资源类 
 public class myThread extends Thread {
 
    //重写run方法(Thread类也实现了Runnable接口)
  public void run(){
  
  //线程需要运行的复杂代码
  
    }
 
 }
 
 //测试类
 
 public class Test{
 
   public static void main (String[] args){
   //创建资源类对象
     MyThread mt = new MyThread();
     
     //创建线程 
     Thread th = new Thread(mt);
     
     //启动线程
     th.start();
     th.join();  //该线程执行,其他线程等待,知道该线程结束,其他线程再次竞争CPU资源
     
   
   }
 
 
 }
2.创建线程的另一种方式(实现Runnable接口的run方法,推荐使用的)

理 念:
体现了数据共享的概念,谁实现了Runnable接口的run方法,谁就是资源类(多个线程必须同时操作同一个资源)
该方式能体现出"资源共享的概念",使用到了代理模式中的静态代理模式
实现步骤:

  1)自定义一个类实现Runnable接口,实现里面的Run方法
  2)在主线程main,创建Runnable接口实现类--就是资源类对象,在创建Thread类对象,使他完成public Thread(Runnable target , String name),在/Thread构造方法中将资源类对象作为参数传递!
  3)启动线程start

        public final void setName()://给线程设置名字
        public final void getname()://获取线程名字
        public final void join()://线程礼让,等待某个线程终止,才能执行其他线程抢占,本身会抛出异常
        public static void yield();//暂停当前正在执行的线程,并执行其他线程,让多个线程更和谐,(并不能完全保证)
        
```java(示例)

    //资源实现类
    public class MyRunnable extends Runnable{
    
    //重写run()方法
    public void run(){
    
   //耗时操作
   
   //获取正在执行的线程名字
 System.out.println(Thread.currentThread().getName());
          }
    
    }
    public class test{
    public static void main(String[] args){
    
    //创建资源实现类对象
     MyRunnable mr = new MyRunnable();
     
     //创建线程对象
     Thread th = new thread(mr,"T1");
    
    
    }
    
    
    
    }
3,Thread类的常量表

      public static final int MAX_PRIORITY 10 //最大优先级
      public static final  int  MIN_PRIORITY 1 //最小优先级
     public static final int NORE_PRIORITY 5 //默认优先级
     注意:线程的优先级越大只能说他抢占CPU的几率越大,并不具有绝对性,线程的执行具有随机性
4.)线程的生命周期,有几种状态?(面试题)
 Thread类的内部枚举 类型:
 public enum State{
 
    规定了六种状态
    NEW,新建
    RUNABLE ,运行状态
    BLOCKED ,阻塞状态
    WAITTING,等待(一直等待)
    TIMD_WAITTING,超时等待
    TERMINATED ,终止死亡状态
    
 
 }

5.java中有23 中设计模式(思想):

分为三大类:

   1) 创建型设计模式:(整个对象的创建):单例模式(重点),静态工厂方法(模式),工厂方法模式(重点)
   2)结构型设计模式:(整个结构组成:抽象类,接口,具体实现类...) --->代理模式(重点)静态,动态代理
   3)行为型设计模式(功能型设计模式:使用具体的应用场景):适配器模式,装饰着模式(IO流中使用)
6.检验多线程安全问题的标准------多线程安全问题的解决思路
1)首先检查你的程序是不是多线程环境 ?
2)你的程序中是否有共享数据 ?
3)你的程序中是否存在多条语句对共享数据进行操作 ?

解决方案:

      java提供了一个同步代码块将对数据操作的代码部分包裹起来,解决线程安全问题(同步锁)
      同步锁
      synchronized(锁对象){
      
      多条语句对共享数据的草做;
      
      }
      注意:锁对象可以 是任意java类型,但是,必须是同一类型;(锁只能有一个)
      //如果一个方法中有同步代码块,可以将synchronized提到方法声明上 此时锁对象是this(这是针对非静态的方法),如果是静态的那就是当前类字节码对象 ,类名.class 属性

面试题:(锁对象问题)

    1)同步方法的锁对象是谁呢? (一般说的都是非静态的)
      非静态同步方法的锁对象是 this:代表当前类对象的地址引用
 
     2)静态的同步方法的锁对象是谁呢?--->静态的东西和类相关
       跟反射有关系,是当前类的字节码文件对象
      之前讲Object类---->Class getClass():获取字节码文件对象 方式1
      任意java类型的class属性(内置属性)--->第二种方式获取字节码文件对象
 
7.死锁问题:(两个线程互相等待)

死锁的产生:

在多线程的环境下,首先考虑的是线程安全问题,解决线程安全问题,使用同步代码块(同步机制,synchronize代码块),虽然解决了安全问题,但是降低了执行效率,可能产生一种"死锁"现象

解决方案: 
使用等待唤醒机制
java Object 类提供了 线程等待 wait()方法,线程等待, 以及唤醒方法 notify() ,线程唤醒机制
8 为什么wait这些方法以及notify都在Object类中,而没有在Thread类中
因为这些方法都是跟锁对象有关系,而锁对象可以是任意java类型-----所以就定义在了Object类中
这两个方法都由锁对象调用,wait执行完后会主动释放锁,notify,会唤醒下同步等待的线程
9,同步机制解决线程安全机制(3个方法)
1)synchronize(锁对象 ){

     同步代码块;    
   }
2)wait()和notify()
3)volatile :同步解决安全问题(不常使用)

10,线程池的使用:

1)创建线程池
    Executors:工厂类(提供专门创建线程池的静态方法)public static ExecutorService newFixedThread(int nThread)  
    解释:创建一个线程数固定的线程池,返回值是一个接口---->底层源码---->肯定返回的接口的子实现类对象
2)提交异步任务:
       ExecutorService :线程池--- 接口里面的方法都要被子实现类ThreadPoloolExecutor:实现
       <T> Future<T> submit(Callable<T> task),提交异步任务并返回结果
3)关闭线程池 
     void shutdown():关闭之后不会接受任何新任务

10.1线程池的几个重要参数:(重点面试题)

 1)corePoolSize:线程池中的核心线程数
 2)maximumPoolSize:最大线程数,此值大于等于1
 3)KeepAliveTime:空闲线程的存活时间
 4)workQueue:任务队列
 5)handle:线程池中的拒绝则略(当工作线程数大于等于最大线程数时如何拒绝请求执行的runnab的策略)
 6)threadFectory: 表示生成线程池中工作的线程工厂

10.2面试题sleep()线程睡眠和线程等待wait()的区别:

1)来源不同 sleep(时间毫秒值) 来自于Thread类中--->是线程的方法 wait()来自于Object类中,是锁对象调用的 
2)是否释放锁 sleep(时间毫秒值) 只是线程睡眠,睡眠时间到了,继续执行线程,调用这个不会是否锁 wait()方法是被锁调用的,线程在等待,会立即释放锁,只有释放锁,才能通知(唤醒)对方 线程 
3)共同点:都是会抛出异常 当线程睡眠被中断或者线程等待被中断,就会抛出InterruptedException中断异常 

public final void wait() throws InterruptedException public static void sleep(long millis) throws InterruptedException

10.3线程的生命周期有几种状态:

 1)NEW   创建线程
 2)RUNNABLE  运行
 3)BLOCKED , 阻塞状态
 4)WAITTING ,等待(一直等待)
 5)TIMED_WAITTING ,超时等待
 6)TERMINATED ,终止死亡状态

11.final 和 finally 有什么区别?(面试题)

单词前缀是一样的,都是关键字;
final : 是状态修饰符,表示最终的,无法更改的 ;
修饰类该类不能被继承,修饰方法该方法不能被重写,修饰变量此时变量是一个常量

finally:  不能单独使用,捕获异常的标准格式
处理异常:
     throws  抛到方法上(不常使用),捕获具体的 异常信息,使用try ---  catch---
     标准书写:
     try{
     
     //可能出现问题的代码块
     
     }catch{
     
     //处理异常
     }finally{
     finally中的代码一定会执行的
     释放资源(IO流中和连接池中经常使用)
     }
     
     变形格式:
     try-----catch--catch---捕捉多个异常
     try----finally----没有异常的语句

11.IO流以及分类:

** IO流概述:在不同设备之间进行数据的传送**

1)按流的方向分:
   输入流:     读
   输出流:     写
   
2)在流的方向上继续按类型分:
  字节流:(抽象类:InputStream)
     字节输入流:    读  具体类 FileInputStream
     字节输出流:    写  具体类 FileOutputStream
   
  字符流:(抽象类:Reader)
     字符输入流:   读  具体类 InputStreamRander
     字符输出流:   写  具体类OutputStreamRander
     
  读写过程:
     一次一个字节(字符)一个字节(字符)读取 比较慢 ,不推荐
     一次一个字节数组(字符数组)一个数组的读,快捷,开发中比较推荐

IO流中的两个细节:
1)字节读入写出时候的换行 write(“/r/n”);
2)

**字节输入输出流

: 基本类FileInputStream和FileOutputStream的使用(标准写法)


public class FIleOutputDemo {   
public static void main(String[] args)  { 

//创建字节输入输出流对象(第一步)
FileOutputStream fos = null;
FileInputStream fis = null ;
try {       
//创建字节输出流对象           
fos = new FileOutputStream(".txt"); 
fis = new FileInputStream("数据源路径");
// 读写数据(第二步)   
//使用方式二 一次读写一个字节数组
byte[] bytes = new byte[1024];  //1kb = 1024b;
int len = 0  ;
//循环读写
while((len = fis.read(bytes) )!=-1){

fos.write("国庆节快乐".getBytes());  
fos.write("\r\n".getBytes());     //字节中换行操作
//或者
fos.write(bytes, 0 ,len );

//刷新缓存(第三步)
f0s.flush();

}

//释放系统中的流对象资源资源 (必须手动关闭)第四步  
} catch (IOException e) {            e.printStackTrace();     
}finally {          
if (fos!=null){  
try {  
fos.close();
} catch (IOException e) {    
e.printStackTrace();     
}      
   }      
    }    }



**/ 高效字节缓冲输入流和字节缓冲输出流的使用: BufferInputStream和BufferOutputStream的使用 **/



import java.io.*;

//高效字节流
public class BufferStreamDemo {
    public static void main(String[] args) {
             BufferedInputStream bis = null ;
             BufferedOutputStream bos = null;
        try {
            //创建高效字节输入流对象
           bis = new BufferedInputStream(new FileInputStream("g://练习.txt"));

            //创建高效字节输出流
          bos = new BufferedOutputStream(new FileOutputStream("CopyTest.mp4"));

            //读写数据(一次读取一个字节数组)
            byte[] bytes = new byte[1024];
            int len = 0;
            while((len =bis.read(bytes)) != -1){
                bos.write(bytes,0,len);
                bos.flush(); //释放前刷新缓冲区
                //刷新缓冲区
                bos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //释放资源
            if (bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }



    }
}

字符输入输出流:(抽象父类:Reader 和 Writer)
 1) 基本子实现类:InputStreamReader(---解码过程)和OutputStreamWriter (---编码过程)不常使用 (代码繁杂)
 2)便捷类:FileReader和FileWriter(经常使用)
 3)高效字符缓冲流:BufferReader和BufferWriter(高效快捷,开发中经常使用)提供内部缓冲区,定义字符数组长度8192个长度
 (注意);如果现在仅仅是键盘录入,可以使用Scanner或者StringBuffer(Reader in) 的 readLine()阻塞式方法,将内容存储在流中

//高效流

public class BufferReaderDemo {
    public static void main(String[] args) throws Exception {
        //创建高效字符输入流
        BufferedReader br = new BufferedReader(new FileReader(""));
        //创建高效字符输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter(""));

        //读取数据(一次读取一个字符数组)
        char[] chars = new char[1024] ;
        int len  = 0 ;
        while ((len=br.read(chars))!=-1){
            bw.write(chars, 0 ,len);
            //刷新缓存
            bw.flush();
        }
        //方式二:(bufferReader的特有功能) readLine() 行读取
        String line = null ;
        while((line = br.readLine())!= null){
            bw.wait();
            //特有功能 换行 newLine();
            bw.newLine();
            //刷新缓存
            bw.flush();
        }
        //释放资源
        bw.close();
        br.close();
    }
}


//基本类的使用代码实现
public class ReaderDemo {
    public static void main(String[] args) throws Exception {
        //创建字符转换输入流
        InputStreamReader isr  = new InputStreamReader(new FileInputStream(
                "F://ideaObject//第三周测试//src//com//qf//Test_04//Animal.java"));
        //创建字符转换输入流
        OutputStreamWriter otw = new OutputStreamWriter(new FileOutputStream("CopyReader.txt"));

        //读写数据
        char[] chars = new char[1024];
        int len = 0 ;
        while ((len = isr.read(chars))!= -1){
            otw.write(chars,0,len);
            otw.flush(); //刷新
        }

        //释放资源
        otw.close();
        isr.close();
    }
}

12,Properties:属性集合列表----和流有关系(重要)

 属于map集合,但是没有泛型,键和值都只能是String类型,属于map,能够使用map集合功能,添加,遍历 等
 
 但是他有自己特有的功能(推荐)
 键和值都是String类型------>后期经常用到  xx.properties :作为配置文件,配置文件中的键和值都是String类型
 key1 = value1 
 key2 = value2
 ......
 .....

Properties的特有功能:

*添加元素,存储和去出不一致:
*public Object setProperties(String key ,String value)

//遍历:
*public set<String>  stringPropertyName()获取所有键的集合

//通过键获取值 
*public String getProperty(String key)


//两个高级功能
*将文件内容加载到属性集合列表中
*public void load(Reader reader) throws IOException ;
*public void load(InputStream inStream) throws IOException

**将文件内容输出到指定文件,并且给属性列表一个描述
*public void store(Writer writer ,String comments) throws IOException 
参数二:针对属性列表的具体表述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值