栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

有一定基础的JAVA学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

有一定基础的JAVA学习笔记

目录

1、异常机制本质

2、异常的处理

3、数组的声明

4、数组的初始化

5、数组的遍历

6、数组的拷贝

7、java.util.Arrays类

8、多维数组

9、冒泡排序

10、包装类

11、String类、StringBuffer类和StringBuilder类

12、时间相关的类

13、Math类

14、File类

15、枚举类型


1、异常机制本质

就是当程序出现错误,程序安全退出的机制,Java是采用面向对象的方式来处理异常抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE捕获异常:JRE得到该异常后,在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止

Error:程序无法处理的错误,表示运行应用程序中较严重问题,一般编程操作无法处理Exception:程序本身能够处理的异常,如空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算术异常(ArithmeticException)等RuntimeException:如被 0 除、数组下标越界、空指针等,通常是由编程错误导致的Checked Exception:所有不是RuntimeException的异常的统称,又被称为“已检查异常”,如IOException、SQLException等以及用户自定义的Exception异常。这类异常在编译时就必须做出处理,否则无法通过编译。

2、异常的处理

捕捉异常:捕获异常通过3个关键词来实现:try-catch-finally。用try来执行一段程序,如果出现异常,系统抛出一个异常,可以通过它的类型来捕捉(catch)并处理它,最后通过finally语句为异常处理提供一个统一的出口,finally所指定的代码都要被执行(catch语句可有多条,finally语句最多只能有一条)。声明异常:在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理,或者当CheckedException产生时,不一定立刻处理它,可以再把异常throws出去。如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开。自定义异常:在程序中,可能会遇到JDK提供的任何标准异常类都无法充分描述清楚我们想要表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。自定义异常类只需从Exception类或者它的子类派生一个子类即可。自定义异常类如果继承Exception类,则为受检查异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常RuntimeException类。习惯上,自定义异常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器:

class IllegalAgeException extends Exception {
    //默认构造器
    public IllegalAgeException() {
     
    }
    //带有详细信息的构造器,信息存储在message中
    public IllegalAgeException(String message) {
        super(message);
    }
}

3、数组的声明
//创建基本类型一维数组
public class Test {
    public static void main(String args[]) {
        int[] s = null; // 声明数组;
        s = new int[10]; // 给数组分配空间;
        for (int i = 0; i < 10; i++) {
            s[i] = 2 * i + 1;//给数组元素赋值;
        } 
    }
}
//创建引用类型一维数组
class Man{
    private int age;
    private int id;
    public Man(int id,int age) {
        super();
        this.age = age;
        this.id = id;
    }
}

public class Test {
    public static void main(String[] args) {
        Man[] mans;  //声明引用类型数组; 
        mans = new Man[10];  //给引用类型数组分配空间;
         
        Man m1 = new Man(1,11);
        Man m2 = new Man(2,22);  
         
        mans[0]=m1;//给引用类型数组元素赋值;
        mans[1]=m2;//给引用类型数组元素赋值;
    }
}

声明的时候数组并没有真正创建,只有在实例化数组对象时,JVM才分配空间

4、数组的初始化

静态初始化:在定义数组的同时就为数组元素分配空间并赋值

int[] a = { 1, 2, 3 };// 静态初始化基本类型数组;
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
动态初始化:数组定义与为数组元素分配空间并赋值的操作分开进行
int[] a1 = new int[2];//动态初始化数组,先分配空间;
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;
默认初始化:数组一经分配空间,其中的元素也按照实例变量同样的方式被隐式初始化
int a2[] = new int[2]; // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null

5、数组的遍历

采用一般循环也可以遍历数组,但JDK1.5新增加了for-each循环,专门用于数组遍历:

public class Test {
    public static void main(String[] args) {
        String[] ss = { "aa", "bbb", "ccc", "ddd" };
        for (String temp : ss) {
            System.out.println(temp);
        }
    }
}
但是使用该方法遍历数组时无法对元素进行修改

6、数组的拷贝

System类里包含了static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将src数组里的元素赋给dest数组的元素srcpos:指定从src数组的第几个元素开始赋值length:指定将src数组的多少个元素赋给dest数组的元素

public class Test {
    public static void main(String args[]) {
        String[] s = {"A","B","C","D","E"}; 
        String[] sBak = new String[6];
        System.arraycopy(s,0,sBak,0,s.length);//数组的拷贝        
    }
}

7、java.util.Arrays类

JDK提供的java.util.Arrays类包含了常用的数组操作,包括排序、查找、填充、打印内容等打印数组:

System.out.println(Arrays.toString(a)); 
数组元素排序:
Arrays.sort(a);
数组元素是引用类型的排序(Comparable接口的应用):
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        Man[] msMans = { new Man(3, "a"), new Man(60, "b"), new Man(2, "c") };
        Arrays.sort(msMans);
        System.out.println(Arrays.toString(msMans));
    }
}

class Man implements Comparable {
    int age;
    int id;
    String name;
 
    public Man(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }
 
    public String toString() {
        return this.name;
    }
 
    public int compareTo(Object o) {
        Man man = (Man) o;
        if (this.age < man.age) {
            return -1;
        }
        if (this.age > man.age) {
            return 1;
        }
        return 0;
    }
}
二分法查找:
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int[] a = {1,2,323,23,543,12,59};
        System.out.println(Arrays.toString(a));
        Arrays.sort(a);   //使用二分法查找,必须先对数组进行排序;
        System.out.println(Arrays.toString(a));
        //返回排序后新的索引位置,若未找到返回负数。
        System.out.println("该元素的索引:"+Arrays.binarySearch(a, 12)); 
    }
}
数组填充:
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int[] a= {1,2,323,23,543,12,59};
        System.out.println(Arrays.toString(a));
        Arrays.fill(a, 2, 4, 100);  //将2到4索引的元素替换为100;
        System.out.println(Arrays.toString(a));
    }
}

8、多维数组

二维数组的声明:

public class Test {
    public static void main(String[] args) {
        // Java中多维数组的声明和初始化应按从低维到高维的顺序进行
        int[][] a = new int[3][];
        a[0] = new int[2];
        a[1] = new int[4];
        a[2] = new int[3];
        // int a1[][]=new int[][4];//非法
    }
}
二维数组的静态初始化:
public class Test {
    public static void main(String[] args) {
        int[][] a = { { 1, 2, 3 }, { 3, 4 }, { 3, 5, 6, 7 } };
        System.out.println(a[2][3]);
    }
}
二维数组的动态初始化:
public class Test {
    public static void main(String[] args) {
        int[][] a = new int[3][];
        // a[0] = {1,2,5}; //错误,没有声明类型就初始化
        a[0] = new int[] { 1, 2 };
        a[1] = new int[] { 2, 2 };
        a[2] = new int[] { 2, 2, 3, 4 };
    }
}

9、冒泡排序
    比较相邻的元素,如果第一个比第二个大,就交换他们两个;对每一对相邻元素作同样的工作直到结尾的最后一对,此时最后的元素应该是最大的数;对除了该次操作中最后一个元素外所有元素,重复以上步骤;直到最后只剩下开始的一对元素并且完成比较,此时第一个元素应该是最小的数。
    import java.util.Arrays;
    
    public class Test {
        public static void main(String[] args) {
            int[] values = { 3, 1, 6, 2, 9, 0, 7, 4, 5, 8 };
            bubbleSort(values);
            System.out.println(Arrays.toString(values));
        }
     
        public static void bubbleSort(int[] values) {
            int temp;
            for (int i = 0; i < values.length; i++) {
                for (int j = 0; j < values.length - 1 - i; j++) {
                    if (values[j] > values[j + 1]) {
                        temp = values[j];
                        values[j] = values[j + 1];
                        values[j + 1] = temp;
                    }
                }
            }
        }
    }

优化:可以增加逻辑判断,判断每一趟是否发生了数组元素的交换,如果没有发生,则说明此时数组已经有序,可以中止比较。

10、包装类

 Java是面向对象的语言,但基本数据类型不是对象,包装类可以将基本数据转化成对象,以便于操作。

八个类中除了Character和Boolean外都是数字型,而数字型都是java.lang.Number的子类。Number类是抽象类,提供了抽象方法:intValue()、longValue()、floatValue()、doublevalue(),意味着所有的数字型包装类都可以互相转型。

public class Test {
    
    void testInteger() {
        // 基本类型转化成Integer对象
        Integer int1 = new Integer(10);
        Integer int2 = Integer.valueOf(20); // 官方推荐这种写法
        // Integer对象转化成int
        int a = int1.intValue();
        // 字符串转化成Integer对象
        Integer int3 = Integer.parseInt("334");
        Integer int4 = new Integer("999");
        // Integer对象转化成字符串
        String str1 = int3.toString();
        // 一些常见int类型相关的常量
        System.out.println("int能表示的最大整数:" + Integer.MAX_VALUE); 
    }

    public static void main(String[] args) {
        Test test  = new Test();
        test.testInteger();
    }
}
JDK1.5后,Java引入了自动装箱(autoboxing)/拆箱(unboxing)
Integer i = 5;  //自动装箱
int j = i;      //自动拆箱
自动装箱:基本类型的数据处于需要对象的环境中时,会自动转为“对象”,即自动执行了valueOf()方法自动拆箱:每当需要一个值时,对象会自动转成基本数据类型,即自动执行了xxxValue()方法包装类空指针异常问题:当对象为null时,表示没有指向任何对象的实体,如果进行自动拆箱,就会出现NullPointerException错误包装类的缓存问题:包装类在自动装箱时为了提高效率,对于-128~127之间的值会进行缓存处理,超过范围后,对象之间不能再使用“==”进行数值的比较,而是使用equals方法

11、String类、StringBuffer类和StringBuilder类

String类的对象代表不可变的Unicode字符序列,内部的成员变量的值无法再改变StringBuffer类的对象代表可变的字符序列,是JDK1.0版本提供的类,线程安全,做线程同步检查, 效率较低StringBuilder类的对象也代表可变的字符序列,是JDK1.5版本提供的类,线程不安全,不做线程同步检查,因此效率较高,一般采用该类String类对字符串的操作实际上是对其副本的操作,原来的字符串一点都没有改变,如果多次执行会导致大量副本字符串对象存留在内存中,降低效率。而StringBuilder和StringBuffer类是对原字符串本身操作的,可以对字符串进行修改而不产生副本拷贝或者产生少量的副本,因此可以在循环中使用。

StringBuffer/StringBuilder类常用方法

public StringBuilder append(…)方法:为该StringBuilder 对象添加字符序列,返回自身对象public StringBuilder delete(int start,int end)方法:删除从start到end-1的字符序列,返回自身对象public StringBuilder deleteCharAt(int index)方法:移除此序列指定位置上的字符,返回自身对象public StringBuilder insert(…)方法:为该StringBuilder 对象在指定位置插入字符序列,返回自身对象public StringBuilder reverse()方法:将字符序列逆序,返回自身对象public String toString()方法:返回此序列中数据的字符串表示形式

public class Test {
    public static void main(String[] args) {
        //StringBuilder
        StringBuilder sb = new StringBuilder();
        sb.append('a');//追加单个字符
        System.out.println(sb.toString());//转换成String输出
        sb.append(" and b");//追加字符串
        System.out.println(sb.toString());
        //StringBuffer
        StringBuffer sb2 = new StringBuffer("d");
        sb2.insert(0, " and ").insert(0, "c");//插入字符串
        System.out.println(sb2);
        sb2.delete(0, 2);//删除子字符串
        System.out.println(sb2);
        sb2.deleteCharAt(0);//删除某个字符
        System.out.println(sb2.charAt(0));//获取某个字符
        System.out.println(sb2.reverse());//字符串逆序
    }

12、时间相关的类

时间用long类型的变量来表示

Date类(较为过时)

import java.util.Date;

public class Test{
    public static void main(String[] args) {
        //默认是当前时间,按年月日时分秒的时间格式
        Date date1 = new Date();
        System.out.println(date1.toString());
        //转换为自标准基准时间(1970年1月1日00:00:00 GMT)以来的毫秒数
        long i = date1.getTime();
        Date date2 = new Date(i - 1000);
        System.out.println(date1.after(date2));   //测试此日期是否在指定日期之后
        System.out.println(date1.before(date2));  //测试此日期是否在指定日期之前
        System.out.println(date1.equals(date2));  //测试两个日期是否相同
        //转换为时间格式
        System.out.println(new Date(1000L * 60 * 60 * 24 * 365 * 39L).toString());
    }
}

DateFormat类和SimpleDateFormat类

该类的作用是将时间对象转化成指定格式的字符串,胡者将指定格式的字符串转化成时间对象DateFormat是一个抽象类,一般使用它的的子类SimpleDateFormat类来实现功能

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test {
    public static void main(String[] args) throws ParseException {
        // new出SimpleDateFormat对象
        SimpleDateFormat s1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        // 将时间对象转换成字符串
        String daytime = s1.format(new Date());
        System.out.println(daytime);
        System.out.println(new SimpleDateFormat("hh:mm:ss").format(new Date()));
        // 将符合指定格式的字符串转成成时间对象
        String time = "2007-10-7 20:15:30";
        Date date = s1.parse(time);
        System.out.println("date: " + date);
    }
}
格式化字符:

Calendar日历类

Calendar 类是一个抽象类,一般由子类GregorianCalendar为我们提供关于日期计算的相关功能,比如年月日时分秒的展示和计算,还提供了世界上大多数国家/地区的标准日历系统注意月份的表示,一月是0,二月是1,以此类推,12月是11

import java.util.*;

public class Test {
    public static void main(String[] args) {
        // 创建日历对象
        GregorianCalendar calendar = new GregorianCalendar(1999, 10, 9, 22, 10, 50);
        int year = calendar.get(Calendar.YEAR); // 年,打印:1999
        int month = calendar.get(Calendar.MONTH); // 月,打印:10
        // Calendar.DATE和Calendar.DAY_OF_MONTH同义
        int day = calendar.get(Calendar.DAY_OF_MONTH); // 日,打印:9
        int day2 = calendar.get(Calendar.DATE); // 日,打印:9
        int date = calendar.get(Calendar.DAY_OF_WEEK); // 星期,打印:3
        System.out.println(year+" "+month+" "+day+" "+day2+" "+date);
        // 设置日期
        calendar.set(Calendar.YEAR, 2022);
        calendar.set(Calendar.MONTH, Calendar.FEBRUARY);//父类Calendar用英文单词常量表示月份
        calendar.set(Calendar.DATE, 13);//会自动计算星期
        calendar.set(Calendar.HOUR_OF_DAY, 10);
        calendar.set(Calendar.MINUTE, 20);
        calendar.set(Calendar.SECOND, 23);
        printCalendar(calendar);
        // 日期计算
        calendar.add(Calendar.MONTH, 7); // 月份加7
        calendar.add(Calendar.DATE, -7); // 天数减7
        printCalendar(calendar);
        // 日历对象和时间对象转化
        Date d = calendar.getTime(); //日历对象转换为时间对象
        GregorianCalendar calendar0 = new GregorianCalendar();
        calendar0.setTime(d); //时间对象转换为日历对象
    }
    //打印日历对象的函数
    static void printCalendar(Calendar calendar) {
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int date = calendar.get(Calendar.DAY_OF_WEEK) - 1; // 星期几
        String week = "" + ((date == 0) ? "日" : date);
        int hour = calendar.get(Calendar.HOUR);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        System.out.printf("%d年%d月%d日,星期%s %d:%d:%dn", year, month, day,
                week, hour, minute, second);
    }
}
可以利用GregorianCalendar类,打印当前月份的日历:
import java.text.ParseException;
import java.util.*;

public class Test {
    public static void main(String[] args) throws ParseException {
        System.out.println("请输入日期(格式为:1900-1-1):");
        Scanner scanner = new Scanner(System.in);
        String dateString = scanner.nextLine();
        // 将输入的字符串转化成日期类
        System.out.println("您刚刚输入的日期是:" + dateString);
        String[] str = dateString.split("-");
        int year = Integer.parseInt(str[0]);
        int month = Integer.parseInt(str[1]);
        int day = Integer.parseInt(str[2]);
        Calendar c = new GregorianCalendar(year, month-1, day);
        //也可以将字符串通过SImpleDateFormat转化成Date对象,再转化成日历类
        c.set(Calendar.DATE, 1);
        int dow = c.get(Calendar.DAY_OF_WEEK); // week:1-7 日一二三四五六
        System.out.println("日t一t二t三t四t五t六");
        for (int i = 0; i < dow - 1; i++) {
            System.out.print("t");
        }
        int maxDate = c.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= maxDate; i++) {
            StringBuilder sBuilder = new StringBuilder();
            if (c.get(Calendar.DATE) == day) {
                sBuilder.append(c.get(Calendar.DATE) + "*t");
            } else {
                sBuilder.append(c.get(Calendar.DATE) + "t");
            }
            System.out.print(sBuilder);
            if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
                System.out.print("n");
            }
            c.add(Calendar.DATE, 1);
        }
    }
}

13、Math类
public class Test {
    public static void main(String[] args) {
        System.out.println(Math.ceil(3.2));  //大于a的最小整数
        System.out.println(Math.floor(3.2)); //小于a的最大整数
        System.out.println(Math.round(3.2)); //double型转换为long型(四舍五入)
        System.out.println(Math.abs(-45));   //a的绝对值
        System.out.println(Math.sqrt(64));   //a的平方根
        System.out.println(Math.pow(5, 2));  //a的b次幂
        System.out.println(Math.PI);         //圆周率
        System.out.println(Math.E);          //自然常数
        System.out.println(Math.sin(Math.PI/6));  //余弦函数
        System.out.println(Math.asin(0.5));  //余弦函数
        System.out.println(Math.random());   // [0,1)的随机数
    }
}

Math类无需导入,属于 java.lang复杂随机数可以使用java.util包下的Random类产生:

import java.util.Random;

public class Test {
    public static void main(String[] args) {
        Random rand = new Random();
        //随机生成int类型允许范围之内的整型数据
        System.out.println(rand.nextInt());
        //随机生成[0,10)之间的int类型的数据
        System.out.print(rand.nextInt(10));
        //随机生成[20,30)之间的int类型的数据
        System.out.print(20 + rand.nextInt(10));
        //随机生成[0,1)之间的double类型的数据
        System.out.println(rand.nextDouble());
        //随机生成[0,1)之间的float类型的数据
        System.out.println(rand.nextFloat());
        //随机生成false或者true
        System.out.println(rand.nextBoolean());
    }
}

14、File类

java.io.File类代表文件和目录,在开发中进行文件操作时会用到本类

import java.io.File;
import java.util.Date;

public class Test {
    public static void main(String[] args) throws Exception {
        System.out.println(System.getProperty("user.dir"));  //user.dir指本项目的目录
        File f = new File("a.txt"); //相对路径:默认放到user.dir目录下面
        boolean flag = f.createNewFile();//创建文件,flag判断是否成功
        //检查文件相关信息
        System.out.println("File是否存在:" + f.exists());
        System.out.println("File是否是目录:" + f.isDirectory());
        System.out.println("File是否是文件:" + f.isFile());
        System.out.println("File最后修改时间:" + new Date(f.lastModified()));
        System.out.println("File的大小:" + f.length());
        System.out.println("File的文件名:" + f.getName());
        System.out.println("File的目录路径:" + f.getPath());
        flag = f.renameTo(new File("readme.txt"));  //文件重命名
        flag = f.delete(); // 将该文件删除
        File f2 = new File("d:/电影/华语");
        flag = f2.mkdir(); //mkdir只能创建单个目录,中间目录缺失则创建失败
        System.out.println(flag);//创建失败
        flag = f2.mkdirs(); //mkdir能创建多个目录,中间目录缺失则补充创建
        System.out.println(flag);//创建成功
    }
}
以树状结构展示目录树(递归算法)
import java.io.File;

public class Test {
    public static void main(String[] args) {
        File f = new File("d:/电影");
        printFile(f, 0);
    }

    static void printFile(File file, int level) {
        //每有一层打印一个“-”
        for (int i = 0; i < level; i++) {
            System.out.print("-");
        }
        //输出文件名
        System.out.println(file.getName());
        //如果file是目录,则获取子文件列表,并对每个子文件进行相同的操作
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File temp : files) {
                printFile(temp, level + 1);  //递归调用
            }
        }
    }
}

15、枚举类型
import java.util.Random;

public class Test {
    public static void main(String[] args) {
        // 枚举的遍历
        for (Season k : Season.values()) {
            System.out.println(k);
        }
        // switch语句中使用枚举
        int a = new Random().nextInt(4); // 生成0,1,2,3的随机数
        switch (Season.values()[a]) {
            case SPRING:
                System.out.println("春天");
                break;
            case SUMMER:
                System.out.println("夏天");
                break;
            case AUTUMN:
                System.out.println("秋天");
                break;
            case WINTER:
                System.out.println("冬天");
                break;
        }
    }
}
//季节枚举
enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

枚举体用于放置一些常量,隐性继承自 java.lang.Enum尽量不要使用枚举的高级特性,其高级特性都可以使用普通类来实现

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/731684.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号