欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

笔记-迎难而上之Java基础进阶3

程序员文章站 2024-01-06 10:51:16
统计字符串中每一个不同的字符 JDK9的新特性: List接口,Set接口,Map接口里边增加了一个静态方法of,可以给集合一次性添加多个元素 使用前提:当集合中存储的元素的个数已经确定了,不再改变使用,也就是说,添加完元素之后,就不能再使用put方法来添加元素了 注意事项: 1. of方法只适用于 ......

统计字符串中每一个不同的字符

import java.util.*;
//统计字符串每一个字符出现的字数
public class stringdemo{
    public static void main(string[] args){
    scanner ascanner = new scanner(system.in);
    //让用户输入字符串
    system.out.println("请输入你要统计的语句");
    string astring = ascanner.next();
    //要统计每一个字符,就要把字符串转换为字符,可以调用字符串的方法tochararray
    char[] achararray = astring.tochararray();
    //创建hashmap集合,让其存储键与值
    hashmap<character,integer> ahashmap = new hashmap<>();
    //遍历字符数组
    for(character key:achararray){
    //把achar作为键,先判断集合中有没有该键,若有则value加一,没有的话添加键进去
    if(ahashmap.containskey(key)){
        integer value =ahashmap.get(key);
        value++;
        //后来的值会取代前面的值,put方法把值添加进去,
        ahashmap.put(key,value);
    }else{
        //不存在添加进去
        ahashmap.put(key,1);
    
    }
    }
    //把key存储都set集合中,遍历集合
    set<character> aset = ahashmap.keyset();
    //遍历ahashmap
    for(character key : aset){
        integer value = ahashmap.get(key);
        system.out.println(key+"="+value);
    }
    
    
    }
}

jdk9的新特性:

list接口,set接口,map接口里边增加了一个静态方法of,可以给集合一次性添加多个元素

使用前提:当集合中存储的元素的个数已经确定了,不再改变使用,也就是说,添加完元素之后,就不能再使用put方法来添加元素了

注意事项:

  1. of方法只适用于list接口,set接口,map接口,不适用于接口的实现类

  2. of方法的返回值是一个不能够改变的集合

  3. set接口和map接口在调用of方法适合,不能存放重复元素,否则会抛出异常

import java.util.*;
public class jdk9demo{
    public static void main(string[] args){
    list<string> list = list.of("a","b","c","d","a");//可以重复元素
    system.out.println(list);
    
    set<string> set = set.of("a","b","c");//不允许重复元素
    system.out.println(set);
    
    map<string,integer> map = map.of("张三",18,"李四",17,"王五",16,"赵三",18);//不允许重复元素,键不允许重复,值可以
    system.out.println(map);
    }
}

debug追踪

debug调试程序

​ 可以让代码逐行执行,查看代码执行的过程,调试程序中出现的bug

f8:逐行执行程序 f7:进入到方法中 shift+f8跳出方法

f9:跳到下一个断点 ctrl +f2 退出debug模式,停止程序

console:切换到控制台

斗地主案列

import java.lang.reflect.array;
import java.util.arraylist;
import java.util.collections;
import java.util.hashmap;
import java.util.list;

public class doudizhu {
    public static void main(string[] args){
        //integer表示的索引,string表示牌的大小
        hashmap<integer,string> poker = new hashmap<>();
        //创建一个list集合,存储牌的索引,sort方法可以对索引进行排序
        arraylist<integer> pokerindex = new arraylist<>();
        //定义两个集合,存储花色和牌的序号
        list<string> colors = list.of("♠","♥","♣","♦");
        list<string> numbers = list.of("2","a","k","q","j","10","9","8","7","6","5","4","3");
        //把大小王存储到集合中
        int index = 0;
        poker.put(index,"大王");
        pokerindex.add(0);
        index++;
        poker.put(index,"小王");
        pokerindex.add(index);
        index++;
        //0索引代表着大王,1索引代表着小王,以此类推,到后面就可以对索引排序,也就是对牌排序
        for(string number : numbers){
            for(string color :colors){
                string str = color+number;
                poker.put(index,str);
                //牌的索引也要添加,因为他代表着牌的大小,
                pokerindex.add(index);
                index++;
            }
        }
        //使用collections中的方法shuffle();
        collections.shuffle(pokerindex);
        arraylist<integer> p1 = new arraylist<>();
        arraylist<integer> p2 = new arraylist<>();
        arraylist<integer> p3 = new arraylist<>();
        arraylist<integer> p4 = new arraylist<>();
        for(int i=0;i <pokerindex.size();i++){
            //先转为integer类型,不然会添加失败
            integer in = pokerindex.get(i);
            if(i>=51){
                p4.add(in);
            }else if(i%3==0){
                p1.add(in);
            }else if(i%3==1){
                p2.add(in);
            }else if(i%3==2){
                p3.add(in);
            }

        }
        //把分完的牌进行排序
        collections.sort(p1);
        collections.sort(p2);
        collections.sort(p3);
        collections.sort(p4);
        lookpoker("刘德华",poker,p1);
        lookpoker("周润发",poker,p2);
        lookpoker("周星驰",poker,p3);
        lookpoker("底牌",poker,p4);
    }
    public static void lookpoker(string name,hashmap<integer,string> poker,arraylist<integer> list){
            system.out.print(name+": ");
            for(integer key : list){
                //通过索引获取值
                string value = poker.get(key);
                system.out.print(value+" ");
            }
            system.out.println();
    }
}
异常

throwable有两个子类exception和error

error:严重错误error,无法通过处理的错误,只能实现避免,好比绝症

exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的

throw关键字可以在指定的方法里面抛出指定的异常对象

/*
throw关键字
作用:
    可以使用throw关键字在指定的方法中抛出指定的异常
    使用格式:
        throw  new xxxexception("异常产生的原因");
    注意:
        1.throw关键字必须写在方法的内部
        2.throw关键字后边new的对象必须是exception或者exception的子类对象
        3.throw关键字抛出指定的异常对象,我们必须处理这个异常对象
            throw关键字后边创建的是runtimeexception或者是runtimeexception的子类对象,我们可以不处理,默认交给jvm处理
            throw关键字后边创建的是编译器异常,我们必须处理这个异常,
*/  
public class throwdemo{

    public static void main(string[] args){
        int[] arr= new int[3];
        int e = getelement(arr,-2);
        system.out.println(e);
        //抛出指定了异常
        //exception in thread "main" java.lang.nullpointerexception: 传递的数组是空
        //at throwdemo.getelement(throwdemo.java:24)
        //at throwdemo.main(throwdemo.java:18)
    }
    //如果传递的参数不合法,那么我们就必须使用抛出异常的方式,告知方法的调用者,传递参数有问题
    public static int getelement(int[] arr,int index){
        
    if(index<0 || index>arr.length-1){
        throw new arrayindexoutofboundsexception("传递的索引不能超过范围或者低于范围");
    }
    if(arr == null){
        //如果是空,就指定他为空指针异常
        throw new nullpointerexception("传递的数组是空");
    }
    int i = arr[index];
    return i;
    }   
}

objects的非空判断

objects.requirenonnull();可以判断一个对象是否为null

import java.util.objects;
public class throwdemo{

    public static void main(string[] args){
        method("云想衣裳花想容");//传递null将会返回nullpointerexception异常
    }
    public static void method(object obj){
        object objects=objects.requirenonnull(obj);
        system.out.println(objects);
    }
}

throws关键字_异常处理的第一种方式

/*
    throws关键字:当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象,可以使用thorws关键字来处理异常对象,会把异常对象声明抛出给方法的调用者处理

*/
import java.io.filenotfoundexception;
public class throwsdemo{
    public static void main(string[] args)throws filenotfoundexception{
        readfile("d:\\a.txt");
    }
    public static void readfile(string filename)throws filenotfoundexception{
    //传递进来的文件不对就抛出异常
    if(!filename.equals("c:\\a.txt")){
        throw new filenotfoundexception("传递的文件路径不对,请重新传递");
    }
    
    system.out.println("传递路径成功");
    }
}

try_catch异常处理的第二种方式

捕获异常语法格式
try{
    编写可能会出现异常的代码
}catch(用来接收try中抛出的异常信息 异常类型 e){
    处理异常代码
}
....
 catch(){}

注意:
try中可能会抛出多个异常对象,那么久可以使用多个catch来处理这些异常对象
如果try中产生了异常,那么就会执行catch中的异常处理逻辑
import java.io.filenotfoundexception;
public class throwsdemo1{
    public static void main(string[] args){
        try{
            readfile("d:\\a.txt");
        }catch(filenotfoundexception e){
            system.out.println("传递的文件不对");
        }
        system.out.println("后续代码");
    }
    public static void readfile(string filename)throws filenotfoundexception{
    //传递进来的文件不对就抛出异常
    if(!filename.equals("c:\\a.txt")){
        throw new filenotfoundexception("传递的文件路径不对,请重新传递");
    }
    system.out.println("路径没有问题");
}
}

throwable类中3个异常处理的方法

getmessage() :简短的描述

tostring() :详细的消息字符串

printstacktrace():打印的异常信息最全面

字异常符类
public class fu{
    public void show1()throws nullpointerexception,classcastexception{}
    public void show2()throws indexoutofboundsexception{}
    public void show3()throws indexoutofboundsexception{}
    


class zi extens fu{
//子类重写父类方法是,抛出和父类相同异常
public void show1()throws nullpointerexception,classcastexception{}
//子类重写父类方法时,抛出父类异常的子类
    public void show2()throws arrayindexindexoutofboundsexception{}
//子类重写父类方法时,不抛出异常
    public void show3(){}
//父类没有抛出异常,子类也不可以抛出异常,如若有异常,需要try  catch处理异常

自定义异常

//自定义一个注册异常
//需要一个空参数的构造方法,一个带异常信息的构造方法
//继承exception //那么自定义的异常类就是一个编译器异常,那就需要throws或者try...catch处理
//继承的是runtimeexception,那么异常无序处理,交给虚拟机

public class registerexception extends exception{
    public registerexception(){}
    public registerexception(string message){
    super(message);
    }

}
import java.util.*;

//使用自定义异常类
public class exceptiondemo{
    //定义一个集合,存储姓名
    public static void main(string[] args){
    arraylist<string> list = new arraylist<>();
    list.add("詹姆斯");
    list.add("科比");
    list.add("乔丹");
    list.add("诺维斯基");
    list.add("邓肯");
    system.out.println(list);
    //让用户输入昵称
    scanner sc = new scanner(system.in);
    system.out.println("请输入你的昵称");
    string nicheng = sc.next();
    //向里面添加姓名,如果不存在则添加成功,如果存在则返回注册异常
    for(string name : list){
        //使用字符串的方法equals判断集合是否存在元素,将会返回一个boolean
        //为真,就表示昵称已经存在,需要返回一个注册异常
        if(name.equals(nicheng)){
            try{
                throw new registerexception("亲,该昵称已经被注册过了");
            }catch(registerexception e){
                e.printstacktrace();
                return;//一旦放生异常,立马结束方法
            }               
        }
        //遍历完了,如果没有发生异常,就表示昵称可以创建
        
    }
        list.add(nicheng);
        system.out.println("恭喜您,注册成功");
    }
}
多线程
public class threaddemo{
    public static void main(string[] args){
    mythread mt = new mythread();
    //执行start方法,开启线程,执行run方法
  //如果使用mt.run();的话程序会在堆内存中执行,那就不是多行程了,而是单线程
  //每一次使用start();都会开辟一条新的线程,在栈空间里面执行run方法,多行程的好处就是线程之间互相不影响,cup喜欢哪一个线程就执行哪一个线程
    mt.start();
    for(int i= 0;i<10;i++){
        system.out.println("main线程"+i);
    }
    }
}
public class mythread extends thread{
    //重写run方法
    public void run(){
        for(int i=0;i<10;i++){
        system.out.println("run线程"+i);
        }
    }
}

笔记-迎难而上之Java基础进阶3

thread类的常用方法

获取线程名称的方法

1.使用thread类中的方法getname
    string getname() 返回该线程的名称,那条线程调用我,我就返其的名称
2.可以先获取到当前正在执行的线程,然后使用线程中的方法getname()获取线程的名称
public class mythread1 extends thread{
    public void run(){
        /*第一种获取名字的方式
        string name=getname();
        system.out.println(name);*/
       // 第二种获取名字的方式
        //先获取当前线程(currentthread是一个静态方法,可以通过类名直接获取线程)
        thread t = thread.currentthread();//这个方法将会返回当前的线程
        //通过线程获取名字
        string naem =t.getname();
        system.out.println(name);
    }
}
public class threadname{
    public static void main(string[] args){
        mythread1 mt = new mythread1();
        mt.start();
    }
}

设置线程名称

一种通过setname方法,一种通过构造方法来设置

public class threadname{
    public static void main(string[] args){
        mythread1 mt = new mythread1();
        mt.setname("小强");
        mt.start();
        new mythread1("旺财").start();
    }
}
public class mythread1 extends thread{
    public mythread1(){}
    public mythread1(string name){
        super(name);
    }
    public void run(){
    /*第一种获取名字的方式
        string name=getname();
        system.out.println(name);*/
       // 第二种获取名字的方式
        //先获取当前线程
        thread t = thread.currentthread();
        //通过线程获取名字
        string name =t.getname();
        system.out.println(name);
    }
}

sleep方法

是一个静态方法,使用类名就可以直接调用,让当前线程睡眠指定时间

创建多线程程序的第二种方式_实现runnable接口

实现步骤:

1.创建一个runnable接口的实现类

  1. 在实现类中重写runnable接口的run方法,设置线程任务

  2. 创建一个runnable接口的实现类对象

  3. 创建thread类对象,构造方法中传递runnable接口的实现类对象

  4. 调用thread类的start方法,开启线程

    public class runnableimp implements runnable{
     public void run(){  
         for(int i=0;i<10;i++){
             //获取当前的线程,然后获取线程名字
         system.out.println(thread.currentthread().getname()+"--"+i);
         }
     }
    }
    public class runnabledemo {
     public static void main(string[] args){
         //创建runnable接口实现类对象
         runnableimp run = new runnableimp();
         //thread中有个构造方法可以接runnable接口作为参数传递
         new thread(run).start();
    
         for(int i=0;i<10;i++){
                 //想要获取main方法的线程,只能够用下面的方式获取,然后获取线程名字
                 system.out.println(thread.currentthread().getname()+"--"+i);
             }
     }
    }