Java高级总结

Java高级

方法的递归调用

简单的说: **递归就是方法自己调用自己,**每次调用时传入不同的变量.递归有助于编程者解决复杂问题,同时可以让代码变得简洁。

//求1-n的和的递归方法
    public int sumone2n(int n){
        int sum = n;
        if(n == 1){
            return 1;//等于1就不再调用,加完n=1就结束了
        }else {
            return  n + sumone2n(n - 1);
        }
        
    }
    //求n的阶乘
    public int factorial(int n){
        if (n == 1 ){
            return 1;
        }else {
            return n*factorial(n - 1);
        }
    }
    //斐波那契数列递归
    public long fibonacci(int n){
        if(n == 1 || n == 2){
            return 1;
        }else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        }

    }
  • 递归阶乘的分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gq02Xhlt-1660528654074)(C:\Users\13749\AppData\Roaming\Typora\typora-user-images\image-20220814140112009.png)]

  • 递归重要规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F3QVLutV-1660528654075)(C:\Users\13749\AppData\Roaming\Typora\typora-user-images\image-20220814140423333.png)]

异常

程序没有按照设计的正常的逻辑执行,出现了不可预知的情况,就叫异常。

一旦程序出现异常,就会终止执行。

学习异常的目的:

  1. 当我们的程序处理不了的情况,抛出(产生)一个异常,终止程序
  2. 当发生了异常的时候,给出提示,让程序能够继续执行

当我们调用的方法抛出了非Runtime的异常,就会报编译错误

要求代码添加 try catch 语句来处理异常,catch 语句可以有多个,也可以只有一个(异常类型要大于等于抛出最大的异常)

finally语句块的代码一定会执行(不管有没有异常)

只要有非运行时异常时,try/catch 必不可少,finally 可要可不要

try {
            createException.getName();
            createException.getSex(3);
        /*} catch (IOException e) {
            e.printStackTrace();*/
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //finally的代码一定会执行(不管有没有异常)
            System.out.println("finally语句");
        }
CreateException createException = new CreateException();
try {//  try/catch 捕获异常
    createException.getSex(3);
} catch (Exception e) {
    e.printStackTrace();
    System.out.println("异常出现的原因=" + e.getMessage());
}
System.out.println("cl");

集合

一些数据结构的统称集合,包含List、Set、Map

List

List就是列表,用来存储一组数据的数据结构

List是可变长的数据结构,可以知道List里面存有多少个数据

List里面可以保存不同类型的数据

List是有序的列表,数据可以重复

ArrayList

​ ArrayList是采用数组方式实现的

​ 读和遍历速度比较快,插入和删除数据比较慢

LinkedList

采取双向链表实现的,插入和删除速度快, 查询和遍历速度慢

  • 链表里面的数据是保存的地址
  • 每个节点除了自身的数据的地址外,还保存了上一个和下一个节点的地址

Set

无序集合,元素不重复, 允许存null(存一个)

没有索引(序号),不能通过下标访问只能遍历

给出一个数组,把数组中的重复元素去掉,返回新数组

{1,30,25,40,18,30,22,40}

        HashSet<Integer> set = new HashSet<>();//Integer整数
        int[] arrInt = {1,30,25,40,18,30,22,40};
        for (int i = 0; i < arrInt.length; i++) {
            set.add(arrInt[i]);
        }
        //定义新数组,长度与原数组相同
        int[] str1 = new int[set.size()];
        int i = 0;//数组下标
        for (int a : set){//遍历set
            str1[i] = a;//放元素
            i++;
        }
        System.out.println(Arrays.toString(str1));

哈希表 hash table

哈希表,散列表,是一种高效数据结构

要保存的数据称为值,根据hash算法给每个值算出一个hash code

保存数据用hash code跟值一一对应。

hash toble保存数据的原理

根据hash code从表里查找是否存在:

  • 不存在就当成新的值保存
  • 存在,判断equals是否相等:falsh,直接添加;true,说明两个值是一样的,不添加

Collections集合工具类

  • Collection跟Collections的区别

​ Collection是一个接口,它是List 和Set的父接口

​ Collections是一个处理集合类型数据的工具类

Map

  • 保存键值对数据(key - value)

  • key不能重复, value可以重复

  • key和value都可以为null

IO 文件读写

Input输入, Output输出

信息需要永久保存(持久化),一般用文件的形式把信息保存到磁盘。

程序运行需要一些基本配置信息,这种配置信息也是保存在磁盘的文件中。

程序从磁盘上读取文件,就称为Input; 把文件写到磁盘,称为Output ( 参考位置是内存)

多线程

进程和线程

进程是指运行中的程序,比如使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。当使用迅雷,又启动了一个进程,操作系统将为迅雷分配新的内存空间。每个进程独享一段内存空间,进程之间互不干扰。

线程由进程创建,是进程的一个实体,一个进程可以拥有多个线程,多个线程之间共享同一进程资源

并发

并发是指在某个时间段内,多任务交替的执行任务。执行同一个方法或访问同一个属性。

并发可能导致数据不一致(混乱)。

**解决并发:**把并发代码(或方法)添加一个同步关键字:synchronized

同步和异步

同步就是当A请求一个资源的时候,这个资源正在被B使用,那么A就必须要等待,等到B使用完了A才能请求到。

异步就是当A请求一个资源的时候,这个资源正在被B使用,A不需要等也可以请求到

同步是安全的保险的,异步是不安全的,容易导致死锁,一个线程死掉就会导致整个进程崩溃。

实现线程方式

1继承Thread类,重写run( )方法

2、实现Runnable接口,实现run()方法

3.实现Callable接口,实现call方法创建FutureTask对象,构造方法是实现了Callable接口对象创建Thread对象, 构造方法的参数是FutureTask对象

死锁

  1. 互斥条件:线程使用的资源必须至少有一个是不能共享的。即在一段时间内,一个资源只能被一个进程占用,直到被该进程释放。

  2. 请求与保持条件:指的是进程至少有一个资源,但又提出了新的资源请求,而该资源已被其它线程占有,此时请求进程阻塞,但又对自己获得的其它资源保持不释放。

  3. 不可抢占条件:指的是进程已获得资源,在未使用完之前,不能被抢占,只能在使用完时由自己释放。

  4. 循环等待条件:第一个线程等待其他的线程释放资源。后者又在等待第一个线程释放资源。

怎样避免死锁

  • 以相同的顺序去所锁定资源
  • 另外建立一个锁的对象,只锁一个对象,不要锁多个对象

生命周期

  • New 新生状态

    新生状态,当线程被实例化后new Thread(),就进入新生状态。

  • Runnable 就绪状态

    就绪状态,当线程对象执行了start()后进入就绪状态。

    就绪状态的线程可以执行,但不会执行,等待线程调度触发它执行

  • Running 运行状态

    运行状态,当线程被激活执行,这时候线程就是运行状态,执行run()方法

    不一定在一个执行周期内能执行完成run()方法,如果cpu时间片消耗完毕或者线程的yield()方法被调用,线程会退回就绪状态,等待下一次运行

  • Blocked 阻塞状态

    阻塞状态,暂停运行, 正在运行的线程执行了sleep()方法或wait()方法,就进入到阻塞状态。

    因sleep阻塞的线程,sleep时间到了后,重新回到就绪状态

    因wait()方法阻塞的线程,等待notify()或notifyAll()被执行,才重新回到就绪状态

  • Terminated 终止状态

    终止状态,run()正常执行完毕,就进入到终止状态,线程生命周期就结束

学习代码

1.打印2~100的所有质数

 public static void main(String[] args) {

        for (int i = 2; i <=100; i++) {
            int a = 0;
            for (int j = 2; j <i ; j++) {
              if (i%j==0){
                  a++;
              }
            }
            if (a==0){
                System.out.println(i);
            }
        }
    }

2.给出一个数组{5,7,20, 18, 6}, 找出数组中最大的元素

假设最大的数为 int max = arr[0]

package come.hqyj;

public class GetArrMax {
    public static void main(String[] args) {
        int[] arr = {5, 7, 20, 18, 6};
        int getmax = arr[0];
        for (int i = 0; i < arr.length; i++) {
            getmax = getmax < arr[i] ? arr[i] : getmax;
        }
        System.out.println(getmax);
    }

}

3.双色球号码生成

6个红球,红球范围1~32 , 随机生成,不能有重复

1个蓝球,蓝球范围1~7

package com.hqyj.homework;

/**
 * 扑克牌的类
 */
public class Card {
    //花色。黑桃,红桃,梅花,方块
    private String type;
    //点数。2~10,A,K,Q,J
    private String num;

    public Card() {
    }

    public Card(String type, String num) {
        this.type = type;
        this.num = num;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

    @Override
    public String toString() {
        return "Card{" +
                "type='" + type + '\'' +
                ", num='" + num + '\'' +
                '}';
    }
}

package com.hqyj.homework;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CardGame {
    public static void main(String[] args) {
        //生成一副牌

        List<Card> cardList = new ArrayList<>();
        //生成一副扑克牌
        initCard(cardList);

        //洗牌
        Collections.shuffle(cardList);



        //发牌
        Player[] players = new Player[4];  //玩家数组
        for (int i = 0; i < players.length; i++) {
            players[i] = new Player("玩家"+ i);
        }

        for (int i = 0; i < cardList.size(); i++) {
            Card card = cardList.get(i);//按顺序取出一张牌
            //通过循环变量i模4,得到玩家的序号
            int playerIndex = i % players.length;
//            给玩家发一张牌
            players[playerIndex].getCards().add(card);
        }

        //打印玩家的牌
        for (Player player : players
             ) {
            System.out.println(player.getName()); //打印玩家姓名
            List<Card> cards = player.getCards(); //返回玩家手上的牌
            //遍历并打印玩家的牌
            for (Card card : cards
                 ) {
                System.out.println(card);
            }
        }

    }

    private static void initCard(List<Card> cardList) {
        String[] types = {"黑桃", "红桃", "梅花", "方块"};
        String[] nums = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
        //外层循环,花色
        for (int i = 0; i < types.length; i++) {
            //内层循环,每种花色的点数
            for (int j = 0; j < nums.length; j++) {
                String type = types[i]; //花色
                String num = nums[j];//点数
                Card card = new Card(type, num); //用不同的花色和点数创建一张牌
                cardList.add(card); //把牌添加到List
            }
        }
    }
}

package com.hqyj.homework;

import java.util.ArrayList;
import java.util.List;

/**
 * 游戏玩家
 */
public class Player {
    //玩家名字
    private String name;
    //玩家手上的牌
    private List<Card> cards = new ArrayList<>(); //先初始化, 否则getCards()方法返回的是null
    public Player() {
    }

    public Player(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Card> getCards() {
        return cards;
    }

    public void setCards(List<Card> cards) {
        this.cards = cards;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值