学习java的第五周

一、LinkedList集合

1.特点:线程不安全的类,执行效率高,链接列表结构,查询慢,增删快。
2.特有功能:
public void addFirst(Object e):在列表开头插入元素
public void addLast(Object e):将元素追加到列表的末尾
public Object getFirst():获取列表的第一个元素
public Object getLast():获取列表的最后一个元素
public Object removeFirst(): 删除列表的第一个元素,并获取第一个元素
public Object removeLast():删除列表的最后一个元素,并获取最后一个元素

二、Set集合(无序)

1.能够保证元素唯一(线程不安全的类---->不同步---->执行效率高)
2.HashSet:底层数据结构是一个哈希表(桶结构)
3.Hashset集合不能保证顺序迭代恒久不变
4.应用场景:在一些需求中,如果没有明确要求元素重复,那就可以使用hashSet,保证元素唯一;
类型:String,Integer,Long,…常用类都已经重写了hashCode和equals方法。

三、TreeSet集合(无序,元素唯一)

1.底层依赖于TreeMap集合, 红黑树结构(也称为 “自平衡的二叉树结构”),可以实现Map的自然排序以及比较器排序取决于使用的构造方法
2.TreeSet能够实现两种排序:
自然排序/比较器排序,取决于构造方法
自然排序:TreeSet(),E类型必须实现Comparable接口,实现自然排序(实现的compareTo(T t))
比较器排序:
public TreeSet(Comparator<? super E> comparator)
Comparator是一个接口类型

     1)自定义一个类实现Comparator接口,重写compare方法
                      public class MyComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {

        //主要条件:按照学生的年龄从小到大排序
        //s1---->就是刚才自然排序里面this
        //s2---->就是刚才自然排序里面s
        int num = s1.getAge() - s2.getAge() ;
        //如果年龄相同,比较姓名是否一样
        int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;
        return num2;
    }
}
2)使用接口的匿名内部类(推荐)
  TreeSet<Student>  ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //主要条件:按照学生的年龄从小到大排序
                //s1---->就是刚才自然排序里面this
                //s2---->就是刚才自然排序里面s
                int num = s1.getAge() - s2.getAge() ;
                //如果年龄相同,比较姓名是否一样
                int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;
                return num2;
            }
        }) ;

四、Map集合(键映射到值的对象,Map集合可以多个值,但键必须唯一)

1.Map集合的功能:
V put(K key,V value):添加键值对元素
注意事项:
如果key是第一次添加,那么返回的结果为null
如果key是否重复添加,第二次添加,返回的上一次添加的键对应的值

V remove(Object key):删除指定的键,返回被删除键对应的值
void clear()暴力删除
boolean containsKey(Object key) :是否包含指定的键 (使用居多)
boolean containsValue(Object value):是否包含指定的值
2.高级功能:
Map遍历功能
Set keySet() :获取当前Map集合中的所有的键的集合 (将所有的丈夫集中起来,找对应的妻子)
+
V get(Object key):通过键获取值

方式1// Set<K> keySet()  :获取当前Map集合中的所有的键的集合
        Set<String> keySet = map.keySet(); //推荐第一种方式
        //增强for遍历
        for(String key: keySet){
            //获取所有的键的元素
            //  V get(Object key):通过键获取值
            String value = map.get(key);
            System.out.println(key+"="+value);
}
		
              方式2:
                      获取所有的结婚证  (键值对对象)
                        Set<Map.Entry<K,V>> entrySet()

                            通过键值对象 获取键 /获取值(通过结婚证找男方/女方)
                                K getKey()
                                    V getValue()
 //Set<Map.Entry<K,V>> entrySet()
        Set<Map.Entry<String, String>> entry = map.entrySet();
        //增强for:遍历键值对对象获取到
        for(Map.Entry<String, String> en: entry){
            //获取键和值
            //K getKey()
           // V getValue()
            String key = en.getKey();
            String value = en.getValue();
            System.out.println(key+"="+value);
}

3.Map和Collection集合的区别:
Collection:只能存储一种类型 Collection
Map集合:可以两种类型的,键的类型,值的类型 Map<K,V>
遍历方式不同
Collection:就通过5种方式(List)
Map:两种方式:
方式1:获取所有的K的集合(键的集合)
通过键获取值
方式2: 获取所有的键值对对象Map.Entry<K,V> (“结婚证”)
通过键值对对象获取所有的键(“结婚证男方”)
通过键值对对象获取所有的值(“结婚证女方”)
有内在联系:
TreeSet集合---->Collection---->间接的使用到了TreeMap集合的put方法
HashSet阶------>Collection---->间接使用到了HashMap的put方法

五、Collections:针对集合操作工具类

提供静态功能:

public static <T extends Comparable<? super T>> void sort(List list):按照自然升序排序(针对List集合排序)
public static void sort(List list,Comparator<? super T> c):按照比较器排序针对List集合
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T>:获取当前自然顺序中List的最大值
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T>:最小值
public static void reverse(List<?> list):对List集合顺序反转
public static void shuffle(List<?> list):随机置换

六、System类:不能实例化

1.成员变量:
public static final InputStream in:标准输入流
public static final PrintStream out:标准输出流
public static final PrintStream err:错误输出流(打印错误信息/一些信息需要用户引起注意:相关的日志)
级别
info:详情信息
debug:断点调试模式
error:错误信息
warning:警告信息
System.exit(0) :jvm退出 ,0表示正常终止
public static void gc():手动开启垃圾回收器,会去回收内存中没有更多引用的对象!
2. //重写Object类的finalize()方法
@Override
protected void finalize() throws Throwable {
System.out.println(“gc正在去回收没有更多引用的对象”+this);
super.finalize();
}
七、异常

1.Throwable:包含所有的错误以及异常;它是一个超类(父类)

 error:非常严重问题  (跟代码没有太大有关系)
                  OOM Out Of Memory:内存溢出 (严重问题)

      Exception:异常
              编译时期异常和运行时期异常(RuntimeException):程序在运行过程中出现问题(代码书写不严谨)
              只要不是RuntimeException的子类都是属于编译时期异常

      error---->  在生活中  "地震了,不可抗力的因素"
      Exception:异常

              编译时期异常:  在程序,运行前需要检查的     在生活中   "长途旅行之前,检查你的车胎情况"...
              运行时期异常:在程序.程序代码逻辑问题(代码不严谨)  在生活中  "no zuo no die"

异常的处理两种方式:

        标准格式:try...catch...finally


              变形格式
                     try{

                          //可能出现问题的代码
                      }catch(异常类名 变量名){
                          //处理异常
                      }



                      try{
                            //可能出现问题的代码
                      }catch(异常类名 变量名){
                         //处理异常1
                      }catch(异常类名 变量名){
                         //处理异常2
                      }

                      //多线程:jdk5以后:Lock:接口 (锁:可重复入的互斥锁)
                      try{

                          //可能出现问题的代码
                      }finally{
                          //释放资源(系统资源)
                      }
     throws:抛出

2.try…catch处理多个异常
jdk7以后提供的 try{
可能出现问题的代码
}catch(异常类名1 | 异常类名2 | 异常类名3 …变量名){ //异常类名必须为同级别
处理异常
}//使用trt…catch…catch…catch…不能将大的异常(Exception)放在最前面(包含了所有编译时期/运行时期异常)
3.编译时期异常和运行时期异常的区别
RuntimeException:运行时期异常
很多的子类:NullPointerException,ClassCastException,ArrayIndexOutOfBoundsException…

运行时期异常:
一般程序员逻辑结构不严谨导致的问题,调用者可以进行显示处理(try…catch…/throws)
也可以不进行显示处理,通过逻辑语句进行处理。

编译时期异常:调用者必须显示处理,不处理,编译通过不了,程序运行不了
如果在当前方法中已经去捕获了try…catch…,调用者无需进行处理,
但是如果在方法中抛出异常的,调用者必须处理(捕获/抛出throws)。
注: 1)有的时候没有办法去抛出,继承关系中,如果子类继承父类,
父类的该方法没有异常,子类重写该方法的时候,只能try…catch
2)子类继承父类,如果父类的该方法本身抛出异常了,那么子类重写该方法的时候,
要么跟父类的方法的异常类名一致,要么是该异常的子类。
4.throws和throw的区别
共同点:都是抛出
用法不同:
1)使用位置不同
throws:
a)将异常抛出在方法声明上
b)在方法名的后面可以跟多个异常类名,中间逗号隔开!
throw
a)在方法的语句体中某个逻辑语句中
b)它后面只能跟异常对象,而不是类名
2)调用者是否处理不同
throws:调用者必须进行显示处理(try…catch/throws),否则报错
throw:调用者无须显示处理,一般情况都是在逻辑语句进行处理
3)出现异常是否肯定性
throws:在方法上的,执行某个方法的代码中,可能有问题(表示出现异常的一种可能性)
throw:执行某段代码一定会执行这个异常(表示出现异常的一种肯定性)
4)
throws---->将具体的处理交给jvm—通过jvm吧异常信息打印控制台上
显示的底层源码而且会显示当前错误消息字符串
throw---->程序 中某段代码有问题:只是打印异常类名(jvm处理)
注:不管使用throws/try…catch…finally,都是要通过jvm调用Throwable里面的功能完成日志(错误信息)打印。
finally:不能单独使用,它是结合try…catch…finally:异常的标准格式
finally用法:
特点:
释放相关的资源,代码一定执行的
除非在执行finally之前,jvm退出了。
5.finally和finalize的区别
finally:是处理异常的一种标准格式
finally语句中存储的内容都是释放资源的代码 ---->即使代码出问题了,finally语句也一定会执行
特例:当执行finally语句,jvm退出了
finalize是一个方法,Object类中的一个方法,该方法调用通过垃圾回收器线程----垃圾回收器GC
当垃圾回收启动时候,寻找内存中没有更多引用的对象,调用finalize()进行内存清楚并释放资源

八、数组高级查找算法之二分搜索算法

1前提条件:数组必须有序,如果数组本身无序,让我们查询元素,先排序再去查找(有条件需求先排序,再查
如果没有条件需求,只能使用基本元素查找法:从头查找到尾)

public static int binarySearch(int[] arr,int target) {
        //防止空指针异常
        if (arr != null) {
            //定义数组的最小索引:
            int min = 0;
            //定义最大索引
            int max = arr.length - 1;
            //使用循环while
            while (min <= max) {
                //计算中位点索引
                int mid = (min + max) / 2;

                //如果当前中位点对应的元素小于要要查找的元素
                if (target < arr[mid]) {
                    //左半区域:继续折半
                    max = mid - 1;
                } else if (target > arr[mid]) {
                    //右边区域:继续折半
                    min = mid + 1;
                } else {
                    //查询到了
                    return mid;
                }
            }
        }
        //循环结束之后,还没有找,则返回-1
        return -1;
    }

九、进程和线程
1.进程: 能够调用的系统资源的独立单位
2.线程 :属于程序中执行的最小单元(进程中的一条任务线),一个进程由多个线程组成,多个线程可组成线程组(ThreadGroup)
3.多线程的意义:
多线程的特点:具有随机性
多个线程在抢占CPU的执行权
4.线程的优先级
Thread类中静态常量字段(成员变量field)
public static final int MAX_PRIORITY 10 最大优先级
public static final int MIN_PRIORITY 1 最小优先级
public static final int NORM_PRIORITY 5 默认优先级
public final void setPriority(int newPriority):设置线程的优先级
public final int getPriority():获取优先级

public final void join() throws InterruptedException:等待该线程终止

public static void yield():暂停当前正在执行的线程,执行对方线程

public final void setDaemon(boolean on)
参数为true,表示标记当前线程为守护线程,当正在运行的线程如果都是守护线程,则jvm自动退出
这个方法必须在启动线程之前调用(start()之前)
如果运行的线程都是守护线程,jvm退出,运行的线程不会立即停止掉
5.线程有6种状态:
NEW, 新建 (未执行)
RUNNABLE, 运行状态 (可能出现阻塞的情况)
BLOCKED, 线程阻塞状态(wait,sleep…)
WAITTING, 死死等待(底层调用wait()方法)
TIMED_WAITTING, 超时等待(直接调用wait(long timeout))
TERMINATED; 线程终止死亡状态(线程执行完毕)
6.创建线程的实现 方式1:
1)将一个类声明为Thread的子类
2) 这个子类应该重写Thread类的run方法
3)然后可以分配并启动子类的实例。启动线程用的start()而不是run()
run()只是一个普通方法,不会出现线程的执行具有随机性(不会互相抢占cpu执行权)
不会出现两个线程并发执行
方式1 多线程的创建方式存在弊端
1)它是一个继承关系, 具有"局限性"
2)不能够体现资源共享的概念-----
7.多线程的实现方式2步骤
1)自定义类实现Runnable接口
2)重写Runnable接口的run方法
3)在main用户线程中
可以分配类的实例(创建类的实例)
4)创建当前类对象,然后创建Thread类对象,将当前类对象作为参数来传递
当前类---->“资源共享类”
Thread(Runnable target, String name)
5)分别启动线程
8.检验多线程安全问题的标准;
1)是否是多线程环境
2)是否存在共享数据
3)是否存在多条语句对共享数据的操作
9.Java提供同步机制(4种):同步代码块 将多条对共享数据包裹起来
synchronized(锁对象){//锁对象:必须为多个线程的同一把锁;锁对象可以是任意Java的类对象
将多条对共享数据包裹起来
}

ThreadLocal:jdk8之后提供这个本地线程类
ThreadLocal
set()
get()

volatile:也是同步的一种:修饰成员变量,线程对象每次执行的时候,会重复读取被volatile的变量

wait()+notify():来实现同步 (生产者和消费者思想模式)
线程等待----->唤醒对方线程
10.同步方法:
将synchronized关键字提取到方法声明上,跟在权限修饰符的后面
权限修饰符 synchronized 返回值类型 方法名(形式列表){ //非静态的同步方法
业务逻辑…
}
默认都是非静态的同步锁的是this:当前类对象的地址值引用
静态的同步方法:锁对象,跟类相关: 当前类的字节码文件对象: 类名.class
11.线程安全问题:可以通过同步方法或者是同步代码块去解决,但是执行过程中就可能出现死锁问题
死锁问题:
(使用同步机制解决线程安全) 线程和线程之间出现了互相等待的情况
解决方案:
多个线程之间的通信:必须使用的是一个资源类对象,而不能是每一个线程在使用自己的资源类对象
使用生成者和消费者模式思想去解决,前提条件:生成者线程和消费者线程 必须操作的同一个资源类对象
12.sleep和wait方法的区别
1)调用方法是是否会释放锁
sleep(long mills)线程睡眠,调用等待睡眠时间到了,继续线程执行,不会去释放锁
wait的方法调用会立即释放锁对象,目的就是为了让锁对象调用notify()来唤醒其他线程…
2)来源不同
sleep方法来源于Thread类
属于线程的功能---->线程执行过程中可能产生阻塞 (睡眠一段时间内是阻塞的)

wait方法来源于Object类
		它和锁对象有关系,线程处于等待过程中 使用锁对象.wait() 

3)共同点:都会抛出一个异常:InterruptedException:中断异常
十、静态代理
Thread类:就是代理类
自定义的MyRunnable implement Runnable —>真实角色

静态代理:
真实角色:只专于自己的事情(自己的业务功能)
代理类:帮助真实角色完成一些事情(针对真实角色的业务功能进行增强)
代理类和真实角色都需要实现同一个接口!

动态代理:在程序中的过程中通过反射的这种反射产生代理角色
jdk动态代理:基于接口的一种代理 (反射)
cglib:基于子类的一种代理(Spring)

十一、Lock接口

1.JDK5以后提供java.util.current.locks.Lock :提供比syncrhonized方法(/同步代码块)更具体的锁定操作
多个线程并发访问,抢占共享资源数据,通过lock实现多个线程对某个共享资源进行独占访问,不会出现安全问题
void lock()获取锁
void unlock() 试图释放锁
2.提供具体的子实现类:ReentrantLock
Lock lock = new ReentrantLock();

十二、线程组 ThreadGroup

1.public final ThreadGroup getThreadGroup() {//获取线程组
return group;
}
2.public final String getName() {:获取默认的线程组名称(默认线程组名称都是main)
return name;
}
3.线程组: 将线程可以都添加一组中,方便管理,
线程启动完毕之后,线程终止之后,不会将这个线程对象在内存中重复利用

十三、线程池

1.特点:在内存中创建一个固定可重用的线程数,当前线程执行完毕终止了,不会被回收掉,再次回到线程池中,等待下一次利用。
2.弊端: 维护成本大
3.ExecutorService—接口
通过 工厂类:
Exceutors
创建一个固定的可重用的线程数,返回值就线程池对象
public static ExecutorService newFixedThreadPool(int nThreads)

      ExecutorService
                  提交队列任务(多个线程并发执行)
                  <T> Future<T> submit(Callable<T> task)
                  提交值返回任务以执行,并返回代表任务待处理结果的Future。
                Future<?> submit(Runnable task)
                submit的返回值:异步计算的结果,如果不做计算,无须返回结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值