178_刘鉴_java核心编程

java课堂笔记01

// 单行注释

/

/ 多行注释

​

​

 标识符由数字,字母,下划线(_),以及$组成

 注:数字不能做为标识符的开始 如:1ab

 

 关键字:只有特殊含义的标识符  如:int , void...

 

 用户自定义的标识符:由用户按标识符构成规则生成的非保留字符  如:abc...

​

命名规则:Java类命名规则:类名字母大写,如果多个单词组合,则每个单词首字母大写(大驼峰命名法)

HelloWord    ,  Demo

小驼峰命名法:除了第一个单词外,其他单词首字母大写。类似xxxYyyZzz

​

​

​

​

变量名:

 语法:变量类型  变量名字 赋值符号  值



        int age; //声明变量,不赋值

        age = 0;//声明变量之后赋值

        String name = "龙座";//声明变量,赋值

​

        //修改变量值(重新赋值)

        age = 32;

        name = "艾莫";

​

 int 2num; (非法命名)

 int n1, n2, n3, n4;//批量命名

       

       int number;

       int number;   (不能重复声明)        

        
​

     变量的作用域:

     全局变量:

     定义在方法(函数)和代码块之外的变量

     局部变量:

     定义在方法或代码块之外的变量

 

    //定义全局变量

    int age;

    String name = "龙座";

    //静态变量

    static int number;

​

    public static void main(String[] args) {

        //定义局部变量

        int age;

       
 
 
java常量:程序的整个运行中保持不变的量

​

public class Deom01 {

    //成员常量

    final double PI = 301415926;

    //静态常量,使用final static关键字修饰

    final static float price = 99.9F;

    //成员常量和静态常量再定义同时必需初始化

    //final static long bigData;   变量bigData没有初始化

​

    public static void main(String[] args){

        定义常量,使用关键字final

        final int pi = 3;

        // 常量一旦被定义赋值,则不可再被修改

​

// pi = 6; Variable 'name' might already have been assigned to

​

        // 局部常量

        final String name;

        name = "大锤";

​

        //name = "张三"; // Variable 'name' might already have been assigned to

​

​

        final long n1;

//        final static long n2 = 3L; 错误写法

    }

}

​

 十进制

 int num = 12;

        、

 八进制

 int num1 = 025;

        

 十六进制

 int num2 = 0x5d8e;

        

 科学计数法:1.75e5   注:其中e或E之前必有数字,且e或E之后必为整数



定义常量,使用关键字final

        final int pi = 3;

        // 常量一旦被定义赋值,则不可再被修改

​

// pi = 6; Variable 'name' might already have been assigned to

​

        // 局部常量

        final String name;

        name = "大锤";

​

        //name = "张三"; // Variable 'name' might already have been assigned to

​

​

        final long n1;

//        final static long n2 = 3L; 错误写法

Java中的数据类型:

1、基本数据类型(八种)

byte(字节型【1字节】)、short(短整型)、int(整形)、long(长整型)、float(单精度浮点型)、double(双精度浮点型)

char(字符型)、boolean(布尔型)

2、引用数据类型

除了基本数据类型,其他全部是引用数类型,如:String、数组等

​

package com.zpark.day02;

​

public class Deom02 {

    static String name;

​

    public static void main(String[] args) {

        // 字节型

        byte by = 127;

        // 短整型

        short sh = 56;

        // 整形

        int num = 78946;

        // 长整型,注意: 需要早长整型末尾添加L或者l

        long number = 56L;

​

        // 单精度浮点型, 注意: 需要早长整型末尾添加F或者f

        float fl = 3.14F;

        float fl1 = 3.1415888888879874243246564564561129f; // 精度丢失

​

        // 双精度浮点型,java中小数默认是double类型

        double db = 3.14159;

​

        // 字符型, 字符型的值使用单引号引起来,当值为整形时不需要单引号

        char ch1 = 3;

     

​

        // 布尔值类型,注意:Java中布尔值类型只有true和false两个值

        boolean bool1 = true;

        boolean bool2 = false;

​

//引用数据类型:对一个对象的引用,对象包括对象和数组。事实上,引用类型变量就是一个指针

        // null类型    

​

       String str = null;

​

        System.out.println(name);

​

//        int a = null; 报错

    }

}

Java编程笔记02

  基本数据类型大小排行榜
       byte    1字节
       short   2字节
       char    2字节
       int     4字节
       long    8字节
       float   4字节
       double  8字节
 /

二:Java数据类型转换

1隐式转换(自动类型转换)

需要满足两个条件

(1)、两种数据类型彼此兼容

​(2)、目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据)

注:小类型数据转为大类型数据

例如 byte 类型向 short 类型转换时,由于 short 类型的取值范围较大,会自动将 byte 转换为 short 类型。

自动转换的规则

(1)、数值型数据的转换:byte → short  → Int  → long  →  float  →  double。

​(2)、字符型转换为整型:char  →  int。

注意: char 类型比较特殊,char 自动转换成 int、long、float 和 double,但 byte 和 short 不能自动转换为 char,而且 char 也不能自动转换为 byte 或 short。

2、显式转换(强制类型转换)

(1) 大类型数据转为小类型数据时需要强制转换

(2) 小类型  变量名  =  (需要转换的类型) 大类型;

注意:大类型数据转为小类型数据有可能会造成数据进度丢失和溢出、

注: short类型与char类互相转化需要强制转换

3:不同类型数据相加

4:Java算术运算符

      注意:+可以用作算术运算,也可以做字符串拼接

   任何数据类型与字符串做 + 运算都会变成字符串

1、/

      一元运算符:

  -:取反

  ++:自增

  --:自减

     /

  a ++ 和 ++ a 的区别

a2 = a1 ++;

//先将 a1 的值赋给 a2, a1 再自增 1

a2 = ++ a1;

//先将 a1 的值自增 1 ,再赋值给a2;

a --  和 -- a 同理

2、二元运算符

/

   Java 语言中算术运算符的功能是进行算术运算,

   除了经常使用的加(+)、减(-)、乘(``)和除(\)外,

   还有取模运算(%)。加(+)、减(-)、乘(``)、除(\)

   和我们平常接触的数学运算具有相同的含义

  /

注意: Java 语言算术运算符的优先级是先乘除后加减。

​          如果在一个表达式中的多个算术运算符的优先级别相同,例如“a-b+c”,此时将按照运算符的结合方向决定顺序。算术运算符的结合方向都是“从左至右”,即先左后右。

3、算术赋值运算符

/

   java中赋值运算符:

   =:赋值符号

   +=:如, num += 2;  -----> 本质:num = num + 2;

   -=: 如, num -= 2;  -----> 本质:num = num - 2;

   =: 如, num = 2;  -----> 本质:num = num  2;

   /=: 如, num /= 2;  -----> 本质:num = num / 2;

   %=: 如, num %= 2;  -----> 本质:num = num % 2;

  /

4、 Java赋值运算符

​其语法格式如下所示:

变量名称 = 表达式内容

:在 Java 语言中,“变量名称”和“表达式”内容的类型必须匹配,如果类型不匹配则需要自动转化为对应的类型。

5、java中逻辑运算符:

/

   java中逻辑运算符:

        与、或、非

        &&(短路与):如:a && b, 如果ab全部为true则结果为true,否则为false

        ||(短路或):如:a || b, a或者b有一个为true,或者ab均为true,则为true,否则为false

        !:a为true,则结果为false,a为false,则结果为true

  /

/

    && 与 & 区别:如果 a 为 false,则不计算 b(因为不论 b 为何值,结果都为 false)

    || 与 | 区别:如果 a 为 true,则不计算 b(因为不论 b 为何值,结果都为 true)

  /

逻辑运算符的优先级:

!运算级别最高,&& 运算高于 || 运算。!运算符的优先级高于算术运算符,而 && 和 || 运算则低于关系运算符。

6、关系运算符

/    ==:对等于

        !=:不等于

        >:大于

       <:小于

       >=:大于等于

       <=:小于等于

      注意:关系运算符的结果为布尔值类型

 /

(1)当引用数据类型使用==和!=做比较运算时的区别:

String对象的创建:

1):直接赋一个字面量: String str1 = “ABCD”;

2):通过构造器构造:String str = new String(“ABCD”);

三:java扫描器

/ java扫描器:用户从控制台输入数据,后台Java程序接收

 /

// 创建扫描器对象

Scanner scan = new Scanner(System.in);



      1、当遇到空格或者回车的时候 next()方法停止读取

      2、当遇到回车的时候 nextLine()方法停止读取,读取整行数据
 
Java课堂笔记03
  • if else 语句

1、if 结构

if (条件表达式) {

    语句块;

}

(1)条件表达式:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。

(2)语句块:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。

单分支结构:
     if () {

     }

2、if-else 结构

双分支结构
 if语句:
      if (条件表达式) {
 // 条件为true执行
 // 代码块
      } else {
 // 条件为false执行
      }

3、多条件 if-else-if 语句

多分支结构:
      if () {

      }else if () {

      }else if () {

      }....{

      }else{
// 最后的else语句可要可不要
      }

4、嵌套 if 的使用

if(表达式1) {

    if(表达式2) {

        语句块1;

    } else {

        语句块2;

    }

} else {

    if(表达式3) {

        语句块3;

    } else if(表达式4) {

        语句块4;

    } else {

        if(表达式n) {

   语句块n;

        } else {

   语句块n+1;

        }

    }

}

5、三目运算符

三木运算语法(本质:if语句)
       条件表达式 ? 表达式1 : 表达式2
 当表达式结果true,执行表达式1,否则执行表达式2

 表达式 ? (条件表达式1 ? 表达式1 : 表达式2) : (条件表达式2 ? 表达式1 : 表达式2)

三目运算符使用注意:

在使用条件运算符时,还应该注意优先级问题,例如下面的表达式:

x>y ? x-=y : x+=y;

​在编译时会出现语法错误,因为条件运算符优先于赋值运算符,上面的语句实际等价于:

(x>y ? x-=y : x)+=y;

​而运算符“+=”是赋值运算符,该运算符要求左操作数应该是一个变量,因此出现错误。为了避免这类错误,可以使用括号“0”来加以区分。例如,下面是正确的表达式。

(x>y) ? (x-=y): (x+=y);

  • switch case语句

switch(表达式) {

    case 值1:

        语句块1;

        break;

    case 值2:

        语句块2;

        break;

   

    case 值n:

        语句块n;

        break;

    default:

        语句块n+1;

    break;

}

(1)case

表示“情况,情形”,case 标签可以是:

                               1、类型为 char、byte、 short 或 int 的常量表达式。

                               2、枚举常量。

                               3、从 Java SE 7 开始, case 标签还可以是字符串字面量。

注意:重复的 case 值是不允许的。

(2)default

​表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。

(3)break

​表示“停止”,即跳出当前结构。

​如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。

  • while 和 do while 循环

1、while循环:

      语法:

 while (循环条件) {

     循环体

 }

注:while语句是先判断的循环结构,该语句需要判断一个测试条件,如果该条件为真,则执行循环语句(循环语句可以是一条或多条),否则跳出循环。

2、do-while 语句

do.while循环

      语法:

 do{

     循环体

 } while (循环条件);

特点:(1)先执行循环体,然后判断循环条件是否成立

     (2)至少执行一次循环体          

while循环与do...while循环的区别:

      1、while是先判断后执行,do...while循环是先执行然后再判断

      2、do...while循环至少执行一次

 while循环与do...while的特点:都是循环执行某一语句,循环次数素不固定

  • for循环

1、for循环:

      语法:

     for (表达式1; 表达式2; 表达式3) {

循环体

     }

      特点:循环次数固定

注意:(1)for 关键字后面括号中的 3 个表达式必须用“;”隔开。for 循环中的这 3 部分以及大括号中使循环体必需的 4 个组成部分完美地结合在一起,简单明了。

(2)for 循环语句执行的过程为:首先执行表达式 1 进行初始化,然后判断表达式 2 的值是否为 true,如果为 true,则执行循环体语句块;否则直接退出循环。最后执行表达式 3,改变循环变量的值,至此完成一次循环。

补:

foreach 语句的用法

1)foreach语法:

      for(迭代变量类型 变量的名字 :需要遍历(迭代)的对象){

 语句块;

      }

2)break语句:作用:结束当前循环

3continue; // 结束本次循环,强制进入下一次循环

4)/

      定义方法的语法:

  修饰符  返回值类型   方法名(参数1,参数2...) { 方法体... }

     /

    // 自定义方法输出

    // 无返回值。有参数

    public static void print(String str){

        System.out.println(str);

    }

    // 定义有返回值的方法,但是没有参数

    int fun1(){

        // return关键字的作用:1、结束方法的执行。2、将方法的执行结果返回给调用者

        return 12;

    }

    // 有参有返回值

    String fun2(int[] array, double dou, long num, Date time){

        return "有参有返回值";

    }

    // 无参无返回值的方法

    void fun3(){

}

5)方法(函数)的类型:

  1、无参无返回值

      修饰符  void  方法名(){ 方法体 }

  2、无参有返回值

      修饰符   返回值类型   方法名(){ 方法体}

  3、有参无返回值

      修饰符   void   方法名(参数1, 参数2,....){ 方法体}

  4、有参有返回值

      修饰符   返回值类型  方法名(参数1, 参数2,....){ 方法体}

6)方法重载:

  重载就是在一个类中,有相同的函数名称,但参数列表不相同的方法。

       注意:

  方法重载只与方法名字和参数列表有关,与方法返回值类型无关

       方法签名:方法名字 + 参数列表

       什么是程序?

       答:程序 = 算法 + 数据结构

五:数组

  1. 数组定义:

               用来存放相同类型的一组数据

      数组下标从0开始,对数组元素进行操作是通过数组的下标(索引)

      数组一旦被创建,则数组的长度不可被修改

    语法:

 静态创建数组

 数据类型[] 数组名 = {值1,值2....}

 数据类型 数组名[] = {值1,值2....}

 动态创建数组

 数据类型[] 数组名 = new 数据类型[数组长度]

 数据类型 数组名[] = new 数据类型[数组长度]

2、静态创建数组,特点:创建数组的同时给数组元素赋值

 

3、动态创建数组,特点创建数组时指定数组的长度

注:数组元素必须是相同类型的,不允许出现混合类型。

4、数组的边界:

               数组的下标合法区间为:[0,length-1],如果在此范围之外将会报错,这种情况称为数组下标越界

六、生成随机数

  1、Random random = new Random();

 生成指定范围内的随机数 random.nextInt()

  2、double random = Math.random();

 生成随机数的范围 0.0 - 1.0,但永远到不了1

 
java课堂笔记04

一、Arrays类;

由于数组对象本身并没有什么方法可以供我们调用,但是API中提供了一个根据类Arrays供我们使用,从而可以对数据对象进行一些基本操作。

              Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象类调用(注意是“不用”,而不是“不能”)。

              Arrays类具有以下常用的功能:

                            给数组赋值:通过调用fill方法。

                            对数组进行排序:通过sort方法。

                            比较数组:通过equals方法比较数组中元素的值是否相等。

                            查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。

                            将数组转为字符串输出:通过toString方法实现

1、数组的复制:System.arraycopy(浅拷贝)

例子System.arraycopy(src, 1, dest, 0, 6);

2、Arrays.copyOf(浅拷贝)

src为原数组,1为复制的起始位置,dest为目的数组,0为目的数组放置的起始位置,6为复制的长度

4、数组扩容与缩容:

              数组扩容与缩容的实质:就是创建一个新的数组,新数组的长度比原来的数组(大,扩容,小,缩容),然后将原来数组中的内容全部拷贝到新的数组中,最后将新数组重新赋给原来的数组。

         * 数组扩容与缩容的实质:就是创建一个新的数组,新数组的长度比原来的数组(大,扩容,小,缩容)

        int arr[] = new int[10];

        // 对数组进行缩容

        int arr1[] = Arrays.copyOf(arr, 5);

        System.out.println(Arrays.toString(arr1));

        // 扩容,案例:将arr数组长度扩容到15

        int[] arr2 = Arrays.copyOf(arr, 15);

        System.out.println(Arrays.toString(arr2));

二、冒泡排序

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

1、算法描述​ :

(1)比较相邻的元素。如果第一个比第二个大,就交换它们两个;​

(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;​

(3)针对所有的元素重复以上的步骤,除了最后一个;​

(4)重复步骤1~3,直到排序完成。

算法案例:

public static void main(String[] args) {

        int arr[] = {6,9,3,5,2,8};

        System.out.println("排序前:");

        System.out.println(Arrays.toString(arr));

        for(int i =0;i<arr.length-1;i++){

            for(int j=0;j<arr.length-1-i;j++){

                int tamp = 0;

                if (arr[j]>arr[j+1]) {

                    tamp = arr[j];

                    arr[j] = arr[j+1];

                    arr[j+1] = tamp;

                }

            }

        }

        System.out.println("排序后:");

        System.out.println(Arrays.toString(arr));

    }

}

三、选择排序

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

一、面向对象

面向过程思想:

(1)步骤清晰简单,第一步要做什么,第二步要做什么……

(2)面向过程适合处理一些较为简单的问题

面向对象思想:

1、 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考,最后,才对某个分类。

2、 面向对象适合处理复杂的问题,适合处理需要多人协作的问题

面向过程的结构化程序设计:

结构化程序设计的弊端:

(1)缺乏对数据的封装

(2)数据与方法(操作数据)的分离

类是对象的抽象,对象都是类的属性.

2.什么是面向对象:

面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。

3、类中可以包含:

(1)所有对象所共有的属性/特征------------成员变量

(2)所有对象所共有的行为-----------------方法

4、一个类可以创建多个对象,同一类型所创建的对象,结构相同,数据不同

5、类是对象的模板,对象是类的具体的实例

6、面向对象的三大特征:封装、继承、多态

所谓的OOP就是指的面向对象编程.这是一种计算机编程架构.OOP的一条基本准则是计算机程序是由单个能够引

 * 起子程序作用的单元或对象组合而成.OOP达到了软件工程的三个主要目标:重用性,灵活性和扩展性.为了实现

 * 整体运算,每个对象都能够接收消息,处理数据和向其它对象发送消息.OOP主要有以下的概念和组件.

* 组件: 数据和功能一起在运行着的计算机程序中形成的单元,组件在OOP计算机称重是模块和结构化的基础.

* 抽象性: 程序有能力忽略正在处理中信息的某些方面,即对信息主要方面关注的能力

* 封装: 也叫作信息封装:确保组件不会以不可预期的方式改变其它组件内部状态;只有在那些提供了内部状态改变方法的

* 组建中,才可以访问其内部状态.每类组件都提供了一个与其它组件联系的接口.并规定了其它组件进行调用的方法.

* 多态性: 组件的引用和类集会涉及到其它许多不同类型的组件,而且引用组件所产生的的结果得依据实际调用的类型.

 * 继承性: 允许在现存的组件基础上创建子类组件,着统一并强调了多态性和封装性.典型的来说就是用类来对组件进行分

 * 组,而且还可以定义新类为现存的类的扩展,这样就可以将类组织成树形或网状结构,这体现了动作的通用性.

*      由于抽象性/封装性/重用性以及便于使用等方面的原因,以组件为基础的编程在脚本语言中已经变得特别

 * 流行.Python 和 Ruby 是最近才出现的语言,在开发时完全采用了 OOP 的思想,而流行的 Perl 脚本

 * 语言从版本5开始也慢慢地加入了新的面向对象的功能组件。用组件代替“现实”上的实体成为 JavaScript(ECMAScript)

 * 得以流行的原因,有论证表明对组件进行适当的组合就可以在英特网上代替 HTML 和 XML 的文档对象模型(DOM)。

四、类与对象的创建

 */

public class Student {

    // 内部类

    private class C{

    }

}

// 定义类A

class A{

}

// 注意:一个java文件中只能有一个public修饰的Java类,并且这个被public修饰的Java类名必须与Java文件名字一致

//public class B{

//

//}

课堂实例:

// 定义成员变量

    String name; // 姓名

    int age; // 年龄

    double height; // 身高

    // ....

// 定义方法

    public void run(){

        System.out.println("人在跑");

    }

    public void eat(){

        System.out.println("人在吃饭");

    }

    // 将数组排序

    public int[] sort(int[] arr){

        Arrays.sort(arr);

        return arr;

    }

    @Override

    public String toString() {

        return "Person{" +

                "name='" + name + '\'' +

                ", age=" + age +

                ", height=" + height +

                '}';

    }

}

6.2创建对象:

/**

         * 创建对象语法:

         * 数据类型   引用类型变量   指向(引用)  new关键字        对象

         * Student       zs         =      new           Student();

         */

   案例:创建Person对象:

       

Person per = new Person(); // 实例化对象

        // 访问对象的成员变量和方法,语法:对像名.成员变量名字/方法名字, 能点出什么东西全看类有什么东西

        // 访问person类的成员变量

        per.name = "大锤"; // 访问name变量并且赋值

        // per.salary = 3000; 错误演示

        System.out.println(per.toString());

        per.age = 25;

        per.height = 177.777;

        System.out.println(per.toString());

        // 访问变量

        System.out.println(per.name);

        // 访问成员方法

        per.run();

        int[] ar = {1, 56, 0, 89, 78, 45};

        int[] arr = per.sort(ar);

        System.out.println(Arrays.toString(arr));

        // 实例化对象p2

        Person p2 = per; // 将per的值(对象地址信息)赋给p2,此时per和p2指向相同对象

        System.out.println(p2.toString());

        Person p3 = new Person();

        System.out.println(p3.toString());

        Person p4 = null;

        /**

         * Exception in thread "main" java.lang.NullPointerException

         * 空指针异常:

         *      造成空指针异常的原因:是因为对象为null,然后访问其对象变量或者方法

         */

        // System.out.println(p4.toString());

    }

}

二、面向对象分析产生三种模型

              1、对象模型:对用例模型进行分析,把系统分解成互相协作的分析类,通过类图\对象图描述对象\对象的属性\对象间的关系,是系统的静态模型

              2、动态模型:描述系统的动态行为,通过时序图/协作图/描述对象的交互,以揭示对象间如何协作来完成每个具体的用例。单个对象的状态变化/动态行为可以通过状态图来表示。

              3、功能模型(即用例模型à作为输入)

(1)先读稀疏数组第一行,根据第一行的数据创建原始的二维数组。

(2)再读稀疏数组的后几行数据并赋给原始的二维数组即可。

Java课堂笔记05

一、构造方法构造方法语法结构:         

构造方法是在类中定义的方法,不同于其他的方法,构造方法的定义有如下两点规则

(1)构造方法的名称必须与类名完全相同。              

(2)构造方法没有返回值,连void关键字有没有构造方法的语法:    

修饰符   类名(参数){     *                 方法体....     *              }  

构造方法的作用:用于创建类的对象(实例化对象),还可以初始化成员     

注意:当我们手动添加构造器(构造方法)之后,编译器将不在为我们添加默认的无参构造器

二、默认的构造方法:​ 

1)任何一个类都必须含有构造方法。​ 

2)如果源程序中没有定义构造方法,编译器在编译时会为其添加一个无参的构造方法(称为默认无参构造器)。​ 

3)当定义了构造方法之后,Java编译器不再添加默认的无参构造器。

构造方法的重载:  一个类定义多个构造方法,这些构造方法都有相同的名称,但是方法的参数列表不同一个构造方法可以通过this关键字调用另外一个重载的构造方法构造方法常用于实例化对象和对成员变量进行初始化

4)this关键字的使用:​this关键字用在方法体中,用于指向调用该方法的当前对象,简单来说,那个对象调用方法,this就指的是那个对象,严格来讲在方法中需要通过this关键字指明当前对象。

实例:

(1)Java内存分析堆: new出来的对象(包括实例变量)

(2)栈:局部变量(包括方法的参数)方法区: .

(3)class字节码文件(包括方法、静态变量)内存区域类型:

1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制;

​2. 堆:存放所有new出来的对象;

3. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。);

4. 静态域:存放静态成员(static定义的);​

5. 常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 ;​

6. 非RAM存储:硬盘等永久存储空间对于string的特殊解释对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。

7.对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。​     

这也就是有道面试题:String s = new String(“xyz”);产生几个对象?答:一个或两个,如果常量池中原来没有”xyz”,就是两个。

例如:

1) 堆:    

1.1) 存储new出来的对象(包括实例变量)    

1.2) 垃圾: 没有任何引用所指向的对象         

垃圾回收器(GC):不定时到内存中清理垃圾,回收过程是透明的(看不到的),不一定一发现垃圾就立刻回收,调用System.gc()可以建议虚拟机尽快调度GC来回收

1.3) 内存泄漏: 不再使用的内存没有被及时的回收      

建议: 对象不再使用时及时将引用设置为null

1.4) 实例变量的生命周期:       

在创建对象时存储在堆中,对象被回收时一并被回收

2) 栈:    

2.1) 存储正在调用的方法中的所有局部变量(包括方法的参数)  

2.2) 调用方法时,会在栈中为该方法分配一块对应的栈帧,栈帧中存储方法中的局部变量(包括参数),方法调用结束时,栈帧被清除,局部变量一并被清除   

2.3) 局部变量的生命周期:方法被调用时存储在栈中,方法结束时与栈帧一并被清除3) 方法区:     

3.1) 存储.class字节码文件(包括静态变量、方法)

3.2) 方法只有一份,通过this来区分具体的调用对象对象数组数组是对象:​

1、在Java中,数组属于引用数据类型。​     

2、数组对象存储在堆中,数组变量属于引用类型,存储数组对象的地址信息,指向数组对象。数组的元素可以看成数组对象的成员变量(只不过类型全部相同)访问控制修饰符private修饰的成员变量和方法仅仅只能在本类中访问调用。​

public修饰的成员变量和方法可以在任何地方调用,public修饰的内容是对外提供可以被调用的功能,需要相对稳定,private修饰的内容是对类实现的封装,如果“公开”会增加维护的成本。protected和默认访问控制​

1)用protected修饰的成员变量和方法可以被子类及同一个包中的类使用。​

2)默认的访问控制即不书写任何访问修饰符,默认访问控制的成员变量和方法可以被同一个包中的类调用封装封装,简单的说就是该露的露,该藏的藏。

我们在设计程序是要追求“高内聚,低耦合”,其中,高内聚指的是类的内部数据操作细节由自己完成,不允许外部干涉。低耦合指的是仅暴露少量的方法给外部调用(使用get/set方法)。​

封装(对数据的隐藏),通常来说,应禁止直接访问应该对象中数据的实际表示,而是应该通过操作接口来访问,这种称为信息隐藏。封装的意义:​  

1、对外提供可调用的,稳定的功能。​   

2、封装容易变化的,具体的细节,外界不可访问,这样封装的意义在于:​     a. 降低代码出错的可能性,便于维护。​      b. 当内部的实现细节改变时,只要保证对外的功能定义不变,其他的模块就不会因此而受到牵连。

封装的核心:属性私有化,行为(方法)公开化继承

1、通过extends关键字可以实现类的继承。

2、子类可以继承父类的成员变量及成员方法,同时也可以定义自己的成员变量和成员方法。

3、Java语言不支持多重继承,一个类只能继承一个父类,但是一个父类可以有多个子类。

1、子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。

2、如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动的加入对父类的无参构造方法的调用(如果父类没有无参构造方法,则会有编译错误)。

多态:多态指的是同一方法可以根据发送对象的不同而采用多种不同的行为方式。一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多。

多态存在的条件:     

1、 有继承关系  

2、 子类重写父类的方法  

3、 父类引用指向子类对象

多态的意义:

1、行为的多态(所有抽象方法都是多态的)     

2、对象的多态(所有对象都是多态的) 多态的表现形式:

1、重写:根据对象的不同来表现多态

2、重载:根据参数的不同来表现多态注意:多态是方法的多态性,不是属性的多态性

super关键字在java里面,对于super关键字通常有两种用法:**​ 

1. 用在子类的构造方法里(初始化用),主要是调用父类的默认构造方法,如果父类有不止一个构造方法,可以通过super指定具体的构造函数,比如 super(paras)。​ 

2. 用在子类里调用隐藏或重写的属性或行为,比如 super.onDestroy()等等。​对于第1种需要注意,super表示当前类的父类对象,super()调用的是父类默认的构造方法,即这样可以对父类进行初始化。如果没有对父类进行初始化,当子类调用父类的方法时,便会从逻辑上出现错误,因为没对父类初始化,父类的方法和属性便没有内存空间。

关于super 与 this 关键字的对比(区别):**​ 

1. super(参数):调用基类中的某一个构造函数(应该位于子类构造函数中的第一条语句)。​ 

2. this(参数):调用本类中的构造函数(应该位于构造函数中的第一条语句)。​ 

3. super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)。​ 

4. this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)​ 

5、调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。​ 

6、super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它构造方法。​ 

7、super()和this()均需放在构造方法内第一行。​ 

8、尽管可以用this调用一个构造器,但却不能调用两个。​ 

9、this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。​ 

10、 this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。​ 

11、 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

方法重写方法的重写(Override):

1、发生在父子类中,方法名称相同,参数列表相同,方法体不同

2、重写方法被调用时,看对象的类型   

3、遵循"两同两小一大"原则:------------了解

3.1、两同:    方法名称相同             参数列表相同     

3.2、两小:    派生类方法的返回值类型小于或等于超类方法                   

a、void时,必须相同             

b、基本数据类型时,必须相同              

c、引用数据类型时,小于或等于        

3.2.2、派生类方法抛出的异常小于或等于超类方法的 

3.3、一大:    派生类方法的访问权限大于或等于超类

方法的重写与重载的区别:

1、重写(Override):          

1.1、发生在父子类中,方法名相同,参数列表相同,方法体不同           

1.2、"运行期绑定",看对象的类型绑定方法2、重载(Overload):           

2.1、发生在一个类中,方法名相同,参数列表不同,方法体不同           

2.2、"编译期绑定",看参数/引用的类型绑定方法补充:    编译期:.java源文件,经过编译,生成.class字节码文件

运行期:JVM加载.class并运行.class

编译错误:只是检查语法

Java课堂笔记06

十三、static和final关键字

1、static修饰成员变量

1、用static修饰的成员变量不属于对象的数据结构,属于类的数据结构。

2、static变量是属于类的变量,通常可以通过类名来引用static成员。

3、static成员变量和类的信息一起存储在方法区,而不是在堆中,一个类的static变量只有一份,无论这个类创建了多少个对象。

2、static静态块

Static块属于类的代码块,在类加载期间指向代码块,只执行一次,可以用来在软件中加载静态资源。

/** * instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。 * * instanceof 是 Java 的保留关键字。它的作用是测试它左边的 * 对象是否是它右边的类的实例(实例指的是“类”在实例化之后叫做一个“实例”。 * 实例化:通常把用类创建对象的过程称为实例化),返回 boolean 的数据类型。 */

4、final修饰变量

1、final关键字修饰成员变量,表示变量不可被改变。

2、final修饰成员变量的两种方式初始化:

a. 声明的同时初始化

b. 构造函数中初始化

3、final关键字也可以修饰局部变量,使用之前初始化即可

5、final修饰方法

1、final关键字修饰的方法不可被重写。

2、使一个方法不能被重写的意义在于:防止子类在定义新方法使造成“不间意”重写。

6、final修饰类

1、final关键字修饰的类不可被继承。

2、 JDK中的一些基础类库被定义为final的,例如:String、Math、Integer、Double等。

3、使一个类不能继承的意义在于:可以保护类不被继承修改,可以控制滥用继承对系统造成的危害。

7、static final常量

1、static final修饰的成员变量称为常量,必须声明同时初始化,不可被改变。

2、static final常量会在编译期被替换,例如:

十四、抽象类(abstract)

抽象类描述:(在Java语言中使用abstract class来定义抽象类)

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象方法:

1、由abstract修饰

2、只有方法的定义,没有具体的实现(连{ }都没有)

如果一个方法使用 abstract 来修饰,则说明该方法是抽象方法,抽象方法只有声明没有实现。需要注意的是 abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中。

抽象方法的 3 个特征如下:

1)抽象方法没有方法体

2)抽象方法必须存在于抽象类中

3)子类重写父类时,必须重写父类所有的抽象方法

注意:在使用 abstract 关键字修饰抽象方法时不能使用 private 修饰,因为抽象方法必须被子类重写,而如果使用了 private 声明,则子类是无法重写的。

抽象类:

1、由abstract修饰

2、包含抽象方法的类必须是抽象类

不包含抽象方法的类也可以声明为抽象类------我乐意

3、抽象类不能被实例化

4、抽象类是需要被继承的,派生类:

4.1、重写所有抽象方法--------常用

4.2、也声明为抽象类----------一般不这么做

5、抽象类的意义:

5.1、封装派生类所共有的属性和行为---------代码复用

5.2、给所有派生类提供统一的类型-----------向上造型

5.3、可以包含抽象方法,为所有派生类提供统一的入口

派生类的具体行为不同,但入口是一致的

设计规则:

1、将派生类所共有的属性和行为,抽到超类中--------抽共性

2、所有派生类的行为都一样,设计普通方法

所有派生类的行为都不一样,设计为抽象方法

十五、接口(Interface)

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现(implements)接口的方式,从而来实现接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

1)一个接口可以有多个方法。

2)接口文件保存在 .java 结尾的文件中,文件名使用接口名。

3)接口的字节码文件保存在 .class 结尾的文件中。

4)接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

1)接口不能用于实例化对象。

2)接口没有构造方法。

3)接口中所有的方法必须是抽象方法。

4)接口不能包含成员变量,除了 static 和 final 变量。

5)接口不是被类继承了,而是要被类实现。

6)接口支持多继承(接口不能继承类,接口只能继承接口)。

接口特性:

1)接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

2)接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

3)接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类和接口的区别:

1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

**注:JDK 1.8 以后,接口里可以有静态方法和方法体了

2、static修饰方法

1、通常的方法都会涉及到对具体对象的操作,这些方法在调用时需要隐式传递对象的引用(this)。

2、static修饰的方法则不需要针对某些对象进行操作,其运行结果仅仅与输入的参数有关,调用时直接用类名引用。

3、static在调用时没有具体的对象,因此在static方法中不能对非static成员进行访问,static方法的作用在于提供一些“工具方法”和“工厂方法”等。

3、static静态块

Static块属于类的代码块,在类加载期间指向代码块,只执行一次,可以用来在软件中加载静态资源。

4、final修饰变量

1、final关键字修饰成员变量,表示变量不可被改变。

2、final修饰成员变量的两种方式初始化:

a. 声明的同时初始化

b. 构造函数中初始化

3、final关键字也可以修饰局部变量,使用之前初始化即可

5、final修饰方法

1、final关键字修饰的方法不可被重写。

2、使一个方法不能被重写的意义在于:防止子类在定义新方法使造成“不间意”重写。

6、final修饰类

1、final关键字修饰的类不可被继承。

2、 JDK中的一些基础类库被定义为final的,例如:String、Math、Integer、Double等。

3、使一个类不能继承的意义在于:可以保护类不被继承修改,可以控制滥用继承对系统造成的危害。

7、static final常量

1、static final修饰的成员变量称为常量,必须声明同时初始化,不可被改变。

2、static final常量会在编译期被替换,

十四、抽象类(abstract)

抽象类描述:(在Java语言中使用abstract class来定义抽象类)

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象方法:

1、由abstract修饰

2、只有方法的定义,没有具体的实现(连{ }都没有)

如果一个方法使用 abstract 来修饰,则说明该方法是抽象方法,抽象方法只有声明没有实现。需要注意的是 abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中。

抽象方法的 3 个特征如下:

1)抽象方法没有方法体

2)抽象方法必须存在于抽象类中

3)子类重写父类时,必须重写父类所有的抽象方法

注意:在使用 abstract 关键字修饰抽象方法时不能使用 private 修饰,因为抽象方法必须被子类重写,而如果使用了 private 声明,则子类是无法重写的。

抽象类:

1、由abstract修饰

2、包含抽象方法的类必须是抽象类

不包含抽象方法的类也可以声明为抽象类------我乐意

3、抽象类不能被实例化

4、抽象类是需要被继承的,派生类:

4.1、重写所有抽象方法--------常用

4.2、也声明为抽象类----------一般不这么做

5、抽象类的意义:

5.1、封装派生类所共有的属性和行为---------代码复用

5.2、给所有派生类提供统一的类型-----------向上造型

5.3、可以包含抽象方法,为所有派生类提供统一的入口

派生类的具体行为不同,但入口是一致的

设计规则:

1、将派生类所共有的属性和行为,抽到超类中--------抽共性

2、所有派生类的行为都一样,设计普通方法

所有派生类的行为都不一样,设计为抽象方法

十五、接口(Interface)

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现(implements)接口的方式,从而来实现接口的抽象方法。

接口与类相似点:

1)一个接口可以有多个方法。

2)接口文件保存在 .java 结尾的文件中,文件名使用接口名。

3)接口的字节码文件保存在 .class 结尾的文件中。

4)接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

1)接口不能用于实例化对象。

2)接口没有构造方法。

3)接口中所有的方法必须是抽象方法。

4)接口不能包含成员变量,除了 static 和 final 变量。

5)接口不是被类继承了,而是要被类实现。

6)接口支持多继承(接口不能继承类,接口只能继承接口)。

接口特性:

1)接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

2)接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

3)接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类和接口的区别:

1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

注:JDK 1.8 以后,接口里可以有静态方法和方法体了。

十六、内部类

java内部类的几种类型:成员内部类,静态内部类,方法内部类,匿名内部类。

成员内部类:成员内部类是类内部的非静态类。成员内部类不能定义静态方法和变量(final修饰的除外)。

静态内部类:

静态内部类是 static 修饰的内部类,这种内部类的特点是:

1、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。

2、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与 内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。

3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();

方法内部类(局部内部类):

方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。

需要注意:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。

匿名内部类:

匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。

十七、枚举

枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。

1、声明枚举

声明枚举时必须使用 enum 关键字,然后定义枚举的名称、可访问性、基础类型和成员等。

任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号分隔。

提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。

2、枚举类

Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。

Java课堂笔记07

String字符串处理

  • Java定义字符串
    1
    字符串是Java中特殊的关,使用方法像一般的基本数据类型,被广泛应用在java编程中, java没有内置的字符串类型,而是在标准Java类库中提供了一个String关来创建和操作字符串。
    在java中定义一个学特用品筒中的方法是用双引号把它包围起来。这种用双引号提出来的一串字符实际上都是String对象,如字符串“Hello”在端译后面成为String对象,因此也可以通过创建String类的实例来定义字符串。
  1. 直接定义字符串
    血液定义字将单是物使用双引导的、物串中的内容,例如“Hello jaw”、“Java输配”物,具体方法是用字符串剂量直接切处化一个String对象,示例如下:
    String str="Hello 2ava":

String(char[]value)
分配一个新的字符串,将参数中的字符数组元素全配交为字符串。该字符数组的内容已被复制,后续对字符数组的修改不会影响新创建的字符

sChar变革的值是字符串“Hello”。切便在创建字符串之后,对a数组中的第2个元素进行了修改,但未影响sChar的值。

4. String(char[]value. int offset, int count)
分配一个新的string,它包含来自 答数组参数一个子数组的字符。offset参数身子数组第一个字符的末引, count参数指定子数组的长度。该子数组的内容已被赋值。 “数组的修改不会影响新创建的字符串。例如:
char a□=(&apos;W&apos;,&apos;e&apos;,&apos;1&apos;,&apos;T&apos;,&apos;o&apos;.
String scharenew String(a,1,4);
a[1]= &apos;s &apos; :
sChar变量的值是字符串"ellio"。该构造方法使用字符数组中的部分连接元素来创建字符串对象。offset参数指定起始末引角, count 指定载现元素的个数,创建字符串对象后,即使在后面修改了a数相中第2个元素的值,对sChar的值也没有任何影响。

二、String和int的相互转换
1、String转换为int

2、int转换为String
整型int转String字符串类型有以下3种方法:
1. Strings=String,valueOf(i);
2. Strings=Integer.toStringGi.
3. Strings=""+"

使用第三种方法相对第一第二种耗时比较大。在使用第一种walueOf()方法时,注意valueOf括号中的值不能为空,否则会报空指针异常(NullPointerException)。
 toString()
toString()可以把一个引用类型转换为Suring字符串类型,是sun公司开发Java的时候为了方便所有类的字符串操作而特意加入的一个方法。
这里chars是存放字符的数组, startindex是字符数组中期望得到的子字符串的首字符下标,numChars指定子字符串的长度。2) parse()
parseXxx(String)这种形式,是指把字符串转换为数值型,其中Xxx对应不同的数据类型,然后转换为Xxx指定的类型,如int型和float型。
3) toString()
toString()可以把一个引用类型转换为Suring字符串类型,是sun公司开发Java的时候为了方便所有类的字符串操作而特意加入的一个方法。
 

  • 字符串拼接(连接)
    对于已经定义的字符串,可以对其进行各种操作。连接多个字符串是字符串操作中最简单的一种。通过字符串连接,可以将两个或多个字符串、字符、整数和浮点数等类型的数据连成一个更大的字符串。
    String字符串虽然是不可变字符串,但也可以进行拼接只是会产生一个新的对象。String字符串拼接可以使用“+”运算符或String的concat(string str)方法。"+"运算符优势是可以连接任何类型数据拼接成为字符串,而concat方法只能拼接String类型字符串。
    1、使用连接运算符“+”
    与绝大多数的程序设计语言一样, Java语言允许使用“+”号连接(拼接)两个字符串。“+”远算符是最简单、最快捷,也是使用最多的字符串连接方式。在使用“+”运算符连接字符串和int型(或double型)数据时,“+”将int(或double)型数据自动转换成String类型。

java课堂笔记08

六、分割字符串(spilt())

String 类的 split() 方法可以按指定的分割符对目标字符串进行分割,分割后的内容存放在字符串数组中。该方法主要有如下两种重载形式:

str.split(String sign)
str.split(String sign,int limit)

其中它们的含义如下:

str:为需要分割的目标字符串。

sign:为指定的分割符,可以是任意字符串。

limit:表示分割后生成的字符串的限制个数,如果不指定,则表示不限制,直到将整个目标字符串完全分割为止。

使用分隔符注意如下:

1)“.”和“|”都是转义字符,必须得加“\”。

如果用“.”作为分隔的话,必须写成String.split("\\."),这样才能正确的分隔开,不能用String.split(".")

如果用“|”作为分隔的话,必须写成String.split("\\|"),这样才能正确的分隔开,不能用String.split("|")

2)如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu =? or n=?”,把三个都分隔出来,可以 用String.split("and|or")

七、字符串的替换

1、replace() 方法

replace() 方法用于将目标字符串中的指定字符(串)替换成新的字符(串),其语法格式如下:

字符串.replace(String oldChar, String newChar)

其中,oldChar 表示被替换的字符串;newChar 表示用于替换的字符串。replace() 方法会将字符串中所有 oldChar 替换成 newChar。

2、replaceFirst() 方法

replaceFirst() 方法用于将目标字符串中匹配某正则表达式的第一个子字符串替换成新的字符串,其语法形式如下:

字符串.replaceFirst(String regex, String replacement)

其中,regex 表示正则表达式;replacement 表示用于替换的字符串。

3、replaceAll() 方法

replaceAll() 方法用于将目标字符串中匹配某正则表达式的所有子字符串替换成新的字符串,其语法形式如下:

字符串.replaceAll(String regex, String replacement)

其中,regex 表示正则表达式,replacement 表示用于替换的字符串。

八、字符串比较

字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀串等。在 Java 中,比较字符串的常用方法有 3 个:equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。

1、equals() 方法

equals() 方法将逐个地比较两个字符串的每个字符是否相同。如果两个字符串具有相同的字符和长度,它返回 true,否则返回 false。对于字符的大小写,也在检查的范围之内。equals() 方法的语法格式如下:

str1.equals(str2);

str1 和 str2 可以是字符串变量, 也可以是字符串字面量。

2、equalsIgnoreCase() 方法

equalsIgnoreCase() 方法的作用和语法与 equals() 方法完全相同,唯一不同的是 equalsIgnoreCase() 比较时不区分大小写。当比较两个字符串时,它会认为 A-Z 和 a-z 是一样的。

下面的代码说明了 equalsIgnoreCase() 的使用:

String str1 = "abc";
String str2 = "ABC";
System.out.println(str1.equalsIgnoreCase(str2));    // 输出 true

3、equals()与==的比较

理解 equals() 方法和==运算符执行的是两个不同的操作是重要的。如同刚才解释的那样,equals() 方法比较字符串对象中的字符。而==运算符比较两个对象引用看它们是否引用相同的实例。

4、compareTo() 方法

compareTo() 方法用于按字典顺序比较两个字符串的大小,该比较是基于字符串各个字符的 Unicode 值。compareTo() 方法的语法格式如下:

str.compareTo(String otherstr);

提示:如果两个字符串调用 equals() 方法返回 true,那么调用 compareTo() 方法会返回 0。

九、字符串查找

在给定的字符串中查找字符或字符串是比较常见的操作。字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符。

1、根据字符查找

String 类的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中获取匹配字符(串)的索引值。

1.1、indexOf() 方法

indexOf() 方法用于返回字符(串)在指定字符串中首次出现的索引位置,如果能找到,则返回索引值,否则返回 -1。该方法主要有两种重载形式:

str.indexOf(value)
str.indexOf(value,int fromIndex)

其中,str 表示指定字符串;value 表示待查找的字符(串);fromIndex 表示查找时的起始索引,如果不指定 fromIndex,则默认从指定字符串中的开始位置(即 fromIndex 默认为 0)开始查找。

1.2、lastlndexOf() 方法

lastIndexOf() 方法用于返回字符(串)在指定字符串中最后一次出现的索引位置,如果能找到则返回索引值,否则返回 -1。该方法也有两种重载形式:

str.lastIndexOf(value)str.lastlndexOf(value, int fromIndex)

注意:lastIndexOf() 方法的查找策略是从右往左查找,如果不指定起始索引,则默认从字符串的末尾开始查找。

2、根据索引查找

String 类的 charAt() 方法可以在字符串内根据指定的索引查找字符,该方法的语法形式如下:

字符串名.charAt(索引值)

提示:字符串本质上是字符数组,因此它也有索引,索引从零开始。

十、StringBuffer 类

1、创建 StringBuffer 类

StringBuffer 类提供了 3 个构造方法来创建一个字符串,如下所示: ​ 1、StringBuffer() 构造一个空的字符串缓冲区,并且初始化为 16 个字符的容量。 ​ 2、StringBuffer(int length) 创建一个空的字符串缓冲区,并且初始化为指定长度 length 的容量。 ​ 3、StringBuffer(String str) 创建一个字符串缓冲区,并将其内容初始化为指定的字符串内容 str,字符串缓冲区的初始容量为 16 加上字符串 str 的长度。

2、追加字符串

StringBuffer 类的 append() 方法用于向原有 StringBuffer 对象中追加字符串。该方法的语法格式如下:

StringBuffer 对象.append(String str)

该方法的作用是追加内容到当前 StringBuffer 对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer 对象的内容也发生了改变,

3、替换字符

StringBuffer 类的 setCharAt() 方法用于在字符串的指定索引位置替换一个字符。该方法的语法格式如下:

StringBuffer 对象.setCharAt(int index, char ch);

该方法的作用是修改对象中索引值为 index 位置的字符为新的字符 ch,

4、反转字符串

StringBuffer 类中的 reverse() 方法用于将字符串序列用其反转的形式取代。该方法的语法格式如下:

StringBuffer 对象.reverse();

5、删除字符串

StringBuffer 类提供了 deleteCharAt() 和 delete() 两个删除字符串的方法,下面详细介绍。

1、deleteCharAt() 方法

deleteCharAt() 方法用于移除序列中指定位置的字符,该方法的语法格式如下:

StringBuffer 对象.deleteCharAt(int index);

2、delete() 方法

delete() 方法用于移除序列中子字符串的字符,该方法的语法格式如下:

StringBuffer 对象.delete(int start,int end);

其中,start 表示要删除字符的起始索引值(包括索引值所对应的字符),end 表示要删除字符串的结束索引值(不包括索引值所对应的字符)。该方法的作用是删除指定区域以内的所有字符,

总结

String 是 Java 中基础且重要的类,被声明为 final class,是不可变字符串。因为它的不可变性,所以拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。

StringBuffer 就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类。它提供了 append 和 add 方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列。

在很多情况下我们的字符串拼接操作不需要线程安全,所以 StringBuilder 登场了。StringBuilder 是 JDK1.5 发布的,它和 StringBuffer 本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

线程安全:

StringBuffer:线程安全 ​ StringBuilder:线程不安全

速度:

一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。

使用环境:

操作少量的数据使用 String。 ​ 单线程操作大量数据使用 StringBuilder。 ​ 多线程操作大量数据使用 StringBuffer。

十一、正则表达式

正则表达式(Regular Expression)又称正规表示法、常规表示法,在代码中常简写为 regex、regexp 或 RE,它是计算机科学的一个概念。

    String 类里也提供了如下几个特殊的方法。
            1、boolean matches(String regex):判断该字符串是否匹配指定的正则表达式。
            2、String replaceAll(String regex, String replacement):将该字符串中所有匹配 regex 的子串替换成 replacement。
            3、String replaceFirst(String regex, String replacement):将该字符串中第一个匹配 regex 的子串替换成 replacement。
            4、String[] split(String regex):以 regex 作为分隔符,把该字符串分割成多个子串。

正则表达式中的特殊字符如下表所示。

特殊字符

说明

$

匹配一行的结尾。要匹配 $ 字符本身,请使用\$

^

匹配一行的开头。要匹配 ^ 字符本身,请使用\^

()

标记子表达式的开始和结束位置。要匹配这些字符,请使用\(\)

[]

用于确定中括号表达式的开始和结束位置。要匹配这些字符,请使用\[\]

{}

用于标记前面子表达式的出现频度。要匹配这些字符,请使用\{\}

*

指定前面子表达式可以出现零次或多次。要匹配 * 字符本身,请使用\*

+

指定前面子表达式可以出现一次或多次。要匹配 + 字符本身,请使用\+

?

指定前面子表达式可以出现零次或一次。要匹配 ?字符本身,请使用\?

.

匹配除换行符\n之外的任何单字符。要匹配.字符本身,请使用\.

\

用于转义下一个字符,或指定八进制、十六进制字符。如果需匹配\字符,请用\\

|

指定两项之间任选一项。如果要匹配字符本身,请使用\|

正则表达式支持如下表所示的预定义字符。

预定义字符

说明

.

可以匹配任何字符

\d

匹配 0~9 的所有数字

\D

匹配非数字

\s

匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等

\S

匹配所有的非空白字符

\w

匹配所有的单词字符,包括 0~9 所有数字、26 个英文字母和下画线_

\W

匹配所有的非单词字符

上面的 7 个预定义字符其实很容易记忆,其中: ​ d 是 digit 的意思,代表数字。 ​ s 是 space 的意思,代表空白。 ​ w 是 word 的意思,代表单词。 ​ d、s、w 的大写形式恰好匹配与之相反的字符。

方括号表达式

说明

表示枚举

例如[abc]表示 a、b、c 其中任意一个字符;[gz]表示 g、z 其中任意一个字符

表示范围:-

例如[a-f]表示 a~f 范围内的任意字符;[\\u0041-\\u0056]表示十六进制字符 \u0041 到 \u0056 范围的字符。范围可以和枚举结合使用,如[a-cx-z],表示 a~c、x~z 范围内的任意字符

表示求否:^

例如[^abc]表示非 a、b、c 的任意字符;[^a-f]表示不是 a~f 范围内的任意字符

表示“与”运算:&&

例如 [a-z&&[def]]是 a~z 和 [def] 的交集,表示 d、e f[a-z&&^bc]]是 a~z 范围内的所有字符,除 b 和 c 之外 [ad-z] [a-z&&[m-p]]是 a~z 范围内的所有字符,除 m~p 范围之外的字符

表示“并”运算

并运算与前面的枚举类似。例如[a-d[m-p]]表示 [a-dm-p]

Java 正则表达式还支持如下表所示的几个边界匹配符。

边界匹配符

说明

^

行的开头

$

行的结尾

\b

单词的边界

\B

非单词的边界

\A

输入的开头

\G

前一个匹配的结尾

\Z

输入的结尾,仅用于最后的结束符

\z

输入的结尾

数字和日期处理

一、Math类的常用方法

Java 中的 +、-、*、/ 和 % 等基本算术运算符不能进行更复杂的数学运算,例如,三角函数、对数运算、指数运算等。于是 Java 提供了 Math 工具类来完成这些复杂的运算。

Math 类位于 java.lang 包,它的构造方法是 private 的,因此无法创建 Math 类的对象,并且 Math 类中的所有方法都是类方法,可以直接通过类名来调用它们。

1、静态常量

Math 类中包含 E 和 PI 两个静态常量,正如它们名字所暗示的,它们的值分别等于 e(自然对数)和 π(圆周率)。

2、求最大值、最小值和绝对值

在程序中常见的就是求最大值、最小值和绝对值问题,如果使用 Math 类提供的方法可以很容易实现。这些方法的说明如下表所示。

方法

说明

static int abs(int a)

返回 a 的绝对值

static long abs(long a)

返回 a 的绝对值

static float abs(float a)

返回 a 的绝对值

static double abs(double a)

返回 a 的绝对值

static int max(int x,int y)

返回 x 和 y 中的最大值

static double max(double x,double y)

返回 x 和 y 中的最大值

static long max(long x,long y)

返回 x 和 y 中的最大值

static float max(float x,float y)

返回 x 和 y 中的最大值

static int min(int x,int y)

返回 x 和 y 中的最小值

static long min(long x,long y)

返回 x 和 y 中的最小值

static double min(double x,double y)

返回 x 和 y 中的最小值

static float min(float x,float y)

返回 x 和 y 中的最小值

二、生成随机数(random()和Random类)

在 Java 中要生成一个指定范围之内的随机数字有两种方法:一种是调用 Math 类的 random() 方法,一种是使用 Random 类。

Random 类位于 java.util 包中,该类常用的有如下两个构造方法。 Random():该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。 Random(long seed):使用单个 long 类型的参数创建一个新的随机数生成器。

三、数字格式化

符号

说明

0

显示数字,如果位数不够则补 0

#

显示数字,如果位数不够不发生变化

.

小数分隔符

-

减号

,

组分隔符

E

分隔科学记数法中的尾数和小数

%

前缀或后缀,乘以 100 后作为百分比显示

?

乘以 1000 后作为千进制货币符显示。用货币符号代替。如果双写,用国际货币符号代替; 如果出现在一个模式中,用货币十进制分隔符代替十进制分隔符

四、Java大数字运算

在 Java 中提供了用于大数字运算的类,即 java.math.BigInteger 类和 java.math.BigDecimal 类。这两个类用于高精度计算,其中 BigInteger 类是针对整型大数字的处理类,而 BigDecimal 类是针对大小数的处理类。

1、BigDecimal 类

BigInteger 和 BigDecimal 都能实现大数字的运算,不同的是 BigDecimal 加入了小数的概念。

BigDecimal 常用的构造方法如下。

1、BigDecimal(double val):实例化时将双精度型转换为 BigDecimal 类型。

2、BigDecimal(String val):实例化时将字符串形式转换为 BigDecimal 类型。

五、Java时间日期的处理

1、Date 类

Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。

1.1、构造方法

Date 类有如下两个构造方法。

1、Date():此种形式表示分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),使用该构造方法创建的对象可 以获取本地的当前时间。

2、Date(long date):此种形式表示从 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒开始经过参数 date 指定的毫 秒数。

六、Java日期格式化

SimpleDateFormat 类主要有如下 3 种构造方法。 ​ SimpleDateFormat():用默认的格式和默认的语言环境构造 SimpleDateFormat。 ​ SimpleDateFormat(String pattern):用指定的格式和默认的语言环境构造 SimpleDateF ormat。 ​ SimpleDateFormat(String pattern,Locale locale):用指定的格式和指定的语言环境构造 SimpleDateF ormat。

SimpleDateFormat 自定义格式中常用的字母及含义如下表所示。

字母

含义

示例

y

年份。一般用 yy 表示两位年份,yyyy 表示 4 位年份

使用 yy 表示的年扮,如 11; 使用 yyyy 表示的年份,如 2011

M

月份。一般用 MM 表示月份,如果使用 MMM,则会 根据语言环境显示不同语言的月份

使用 MM 表示的月份,如 05; 使用 MMM 表示月份,在 Locale.CHINA 语言环境下,如“十月”;在 Locale.US 语言环境下,如 Oct

d

月份中的天数。一般用 dd 表示天数

使用 dd 表示的天数,如 10

D

年份中的天数。表示当天是当年的第几天, 用 D 表示

使用 D 表示的年份中的天数,如 295

E

星期几。用 E 表示,会根据语言环境的不同, 显示不 同语言的星期几

使用 E 表示星期几,在 Locale.CHINA 语 言环境下,如“星期四”;在 Locale.US 语 言环境下,如 Thu

H

一天中的小时数(0~23)。一般用 HH 表示小时数

使用 HH 表示的小时数,如 18

h

一天中的小时数(1~12)。一般使用 hh 表示小时数

使用 hh 表示的小时数,如 10 (注意 10 有 可能是 10 点,也可能是 22 点)

m

分钟数。一般使用 mm 表示分钟数

使用 mm 表示的分钟数,如 29

s

秒数。一般使用 ss 表示秒数

使用 ss 表示的秒数,如 38

S

毫秒数。一般使用 SSS 表示毫秒数

使用 SSS 表示的毫秒数,如 156

内置类及包装类

一、包装类、装箱和拆箱

1、包装类

在 Java 的设计中提倡一种思想,即一切皆对象。但是从数据类型的划分中,我们知道 Java 中的数据类型分为基本数据类型和引用数据类型,但是基本数据类型怎么能够称为对象呢?于是 Java 为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes),也有地方称为外覆类或数据类型类。

2、装箱和拆箱

基本数据类型转换为包装类的过程称为装箱,例如把 int 包装成 Integer 类的对象;包装类变为基本数据类型的过程称为拆箱,例如把 Integer 类的对象重新简化为 int。

3、包装类的应用

1) 实现 int 和 Integer 的相互转换

可以通过 Integer 类的构造方法将 int 装箱,通过 Integer 类的 intValue 方法将 Integer 拆箱。

2) 将字符串转换为数值类型

在 Integer 和 Float 类中分别提供了以下两种方法:

① Integer 类(String 转 int 型)

int parseInt(String s);

s 为要转换的字符串。

② Float 类(String 转 float 型)

float parseFloat(String s)

注意:使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。

3) 将整数转换为字符串

Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串。

二、Object类

Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类。

1、toString() 方法

toString() 方法返回该对象的字符串,当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。

哈希码(hashCode),每个 Java 对象都有哈希码属性,哈希码可以用来标识对象,提高对象在集合操作中的执行效率。

2、equals() 方法

在前面学习字符串比较时,曾经介绍过两种比较方法,分别是==运算符和 equals() 方法,==运算符是比较两个引用变量是否指向同一个实例,equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。

3、getClass() 方法

getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。

4、接收任意引用类型的对象

既然 Object 类是所有对象的父类,则所有的对象都可以向 Object 进行转换,在这其中也包含了数组和接口类型,即一切的引用数据类型都可以使用 Object 进行接收。

三、Integer类

Integer 类在对象中包装了一个基本类型 int 的值。Integer 类对象包含一个 int 类型的字段。此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。

1、Integer 类的构造方法

Integer 类中的构造方法有以下两个: ​ Integer(int value):构造一个新分配的 Integer 对象,它表示指定的 int 值。 ​ Integer(String s):构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。

2、Integer 类的常量

Integer 类包含以下 4 个常量。 ​ MAX_VALUE:值为 231-1 的常量,它表示 int 类型能够表示的最大值。 ​ MIN_VALUE:值为 -231 的常量,它表示 int 类型能够表示的最小值。 ​ SIZE:用来以二进制补码形式表示 int 值的比特位数。 ​ TYPE:表示基本类型 int 的 Class 实例

四、Float类

1、Float 类的构造方法

Float 类中的构造方法有以下 3 个。 ​ Float(double value):构造一个新分配的 Float 对象,它表示转换为 float 类型的参数。 ​ Float(float value):构造一个新分配的 Float 对象,它表示基本的 float 参数。 ​ Float(String s):构造一个新分配的 Float 对象,它表示 String 参数所指示的 float 值。

五、Double类

1、Double 类的构造方法

Double 类中的构造方法有如下两个。 ​ Double(double value):构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。 ​ Double(String s):构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。

四、Number类

Number 是一个抽象类,也是一个超类(即父类)。Number 类属于 java.lang 包,所有的包装类(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象类 Number 的子类。

Number 类定义了一些抽象方法,以各种不同数字格式返回对象的值。如 xxxValue() 方法,它将 Number 对象转换为 xxx 数据类型的值并返回。

五、Character类

Character 类是字符数据类型 char 的包装类。Character 类的对象包含类型为 char 的单个字段,这样能把基本数据类型当对象来处理,

六、Boolean类

1、Boolean 类的构造方法

Boolean 类有以下两种构造形式:

Boolean(boolean boolValue);
Boolean(String boolString);

其中 boolValue 必须是 true 或 false(不区分大小写),boolString 包含字符串 true(不区分大小写),那么新的 Boolean 对象将包含 true;否则将包含 false。

3、Boolean 类的常用常量

在 Boolean 类中包含了很多的常量,其中较为常用的常量如下。

TRUE:对应基值 true 的 Boolean 对象。

FALSE:对应基值 false 的 Boolean 对象。

TYPE:表示基本类型 boolean 的 Class 对象

七、System类

System 类提供了一些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法。

1、System 类的成员变量

System 类有 3 个静态成员变量,分别是 PrintStream out、InputStream in 和 PrintStream err。

1)PrintStream out**

标准输出流。此流已打开并准备接收输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。

2)InputStream in

标准输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

3)PrintStream err

标准的错误输出流。其语法与 System.out 类似,不需要提供参数就可输出错误信息。

2、System 类的成员方法

System 类中提供了一些系统级的操作方法,常用的方法有 arraycopy()、currentTimeMillis()、exit()、gc() 和 getProperty()。

1)arraycopy() 方法

该方法的作用是数组复制,即从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。

2)currentTimeMillis() 方法

该方法的作用是返回当前的计算机时间,时间的格式为当前计算机时间与 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒所差的毫秒数。一般用它来测试程序的执行时间。

3)exit() 方法

该方法的作用是终止当前正在运行的 Java 虚拟机,

4)gc() 方法

该方法的作用是请求系统进行垃圾回收,完成内存中的垃圾清除。

异常处理

一、异常(Exception)处理及常见异常

1、异常简介

在 Java 中一个异常的产生,主要有如下三种原因:

1、Java 内部错误发生异常,Java 虚拟机产生的异常。

2、编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。

3、通过 throw 语句手动生成的异常,一般用来告知该方法的调用者一些必要信息。

2、异常类型

Java 专门引入了异常类。在 Java 中所有异常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于异常类层次结构的顶层。Throwable 类下有两个异常分支 Exception 和 Error

下面有 Error 和 Exception 两个子类分别表示错误和异常。其中异常类 Exception 又分为运行时异常和非运行时异常,这两种异常有很大的区别,也称为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。 1、Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。 2、Error 定义了在通常环境下不希望被程序捕获的异常。一般指的是 JVM 错误,如堆栈溢出。

非运行时异常是指 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常(一般情况下不自定义检查异常)。

表 1 和表 2 分别列出了 java.lang 中定义的运行时异常和非运行时异常的类型及作用。

表 1 Java中常见运行时异常

异常类型

说明

ArithmeticException

算术错误异常,如以零做除数

ArraylndexOutOfBoundException

数组索引越界

ArrayStoreException

向类型不兼容的数组元素赋值

ClassCastException

类型转换异常

IllegalArgumentException

使用非法实参调用方法

lIIegalStateException

环境或应用程序处于不正确的状态

lIIegalThreadStateException

被请求的操作与当前线程状态不兼容

IndexOutOfBoundsException

某种类型的索引越界

NullPointerException

尝试访问 null 对象成员,空指针异常

NegativeArraySizeException

再负数范围内创建的数组

NumberFormatException

数字转化格式异常,比如字符串到 float 型数字的转换无效

TypeNotPresentException

类型未找到

表 2 Java常见非运行时异常

异常类型

说明

ClassNotFoundException

没有找到类

IllegalAccessException

访问类被拒绝

InstantiationException

试图创建抽象类或接口的对象

InterruptedException

线程被另一个线程中断

NoSuchFieldException

请求的域不存在

NoSuchMethodException

请求的方法不存在

ReflectiveOperationException

与反射有关的异常的超类

二、Error和Exception的异同

Error(错误)和 Exception(异常)都是 java.lang.Throwable 类的子类,在 Java 代码中只有继承了 Throwable 类的实例才能被 throw 或者 catch。

Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源码里必须显示的进行捕获处理,这里是编译期检查的一部分。不检查异常就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译器强制要求。

如下是常见的 Error 和 Exception:

1)运行时异常(RuntimeException): ​ NullPropagation:空指针异常; ​ ClassCastException:类型强制转换异常 ​ IllegalArgumentException:传递非法参数异常 ​ IndexOutOfBoundsException:下标越界异常 ​ NumberFormatException:数字格式异常

2)非运行时异常: ​ ClassNotFoundException:找不到指定 class 的异常 ​ IOException:IO 操作异常

3)错误(Error): ​ NoClassDefFoundError:找不到 class 定义异常 ​ StackOverflowError:深递归导致栈被耗尽而抛出的异常 ​ OutOfMemoryError:内存溢出异常

java笔记09

三、异常处理机制

Java 的异常处理通过 5 个关键字来实现:try、catch、throw、throws 和 finally。try catch 语句用于捕获并处理异常,finally 语句用于在任何情况下(除特殊情况外)都必须执行的代码,throw 语句用于拋出异常,throws 语句用于声明可能会出现的异常。

Java 的异常处理机制提供了一种结构性和控制性的方式来处理程序执行期间发生的事件。异常处理的机制如下: ​ 1、在方法中用 try catch 语句捕获并处理异常,catch 语句可以有多个,用来匹配多个异常。 ​ 2、对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 语句拋出异常,即由上层的调用方法来处理。

四、try catch finally语句

Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只回收堆内存中对象所占用的内存。

使用 try-catch-finally 语句时需注意以下几点: 1、异常处理语法结构中只有 try 块是必需的,也就是说,如果没有 try 块,则不能有后面的 catch 块和 finally 块; 2、catch 块和 finally 块都是可选的,但 catch 块和 finally 块至少出现其中之一,也可以同时出现; 3、可以有多个 catch 块,捕获父类异常的 catch 块必须位于捕获子类异常的后面; 4、不能只有 try 块,既没有 catch 块,也没有 finally 块; 5、多个 catch 块必须位于 try 块之后,finally 块必须位于所有的 catch 块之后。 6、finally 与 try 语句块匹配的语法格式,此种情况会导致异常丢失,所以不常见。

五、声明和抛出异常

1、throws 声明异常

throws 具体格式如下:

returnType method_name(paramList) throws Exception 1,Exception2,…{…}

其中,returnType 表示返回值类型;method_name 表示方法名;paramList 表示参数列表;Exception 1,Exception2,… 表示异常类。

方法重写时声明抛出异常的限制

使用 throws 声明抛出异常时有一个限制,是方法重写中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。

throws 关键字和 throw 关键字在使用上的几点区别如下: 1、throws 用来声明一个方法可能抛出的所有异常信息,表示出现异常的一种可能性,但并不一定会发生这些异常;throw 则是指拋出的一个具体的异常类型,执行 throw 则一定抛出了某种异常对象。 通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw 声明一个具体的异常信息。 2、throws 通常不用显示地捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法; throw 则需要用户自己捕获相关的异常,而后再对其进行相关包装,最后将包装后的异常信息抛出。

六、自定义异常

自定义异常类一般包含两个构造方法:一个是无参的默认构造方法,另一个构造方法以字符串形式接收一个定制的异常消息,并将该消息传递给超类的构造方法。

Lambda 表达式

一、Java 中 Lambda 表达式

1、Lambda 简介

Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、C#、Java、 Python 和 JavaScript 等。

Lambda 表达式是推动 Java 8 发布的重要新特性,它允许把函数作为一个方法的参数(函数作为参数传递进方法中),

2Java Lambda 表达式的优缺点

优点:

代码简洁,开发迅速方便函数式编程非常容易进行并行计算

Java 引入 Lambda,改善了集合操作(引入 Stream API)

缺点:

代码可读性变差在非并行计算中,很多计算未必有传统的 for 性能要高不容易进行调试

3、函数式接口

Lambda 表达式实现的接口不是普通的接口,而是函数式接口。

集合、泛型

一、集合简介

为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),Java 提供了集合类。集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。

接口名称

作 用

Iterator 接口

集合的输出接口,主要用于遍历输出(即迭代访问)Collection 集合中的元素,Iterator 对象被称之为迭代器。迭代器接口是集合接口的父接口,实现类实现 Collection 时就必须实现 Iterator 接口。

Collection 接口

是 List、Set 和 Queue 的父接口,是存放一组单值的最大接口。所谓的单值是指集合中的每个元素都是一个对象。一般很少直接使用此接口直接操作。

Queue 接口

Queue 是 Java 提供的队列实现,有点类似于 List。

Dueue 接口

是 Queue 的一个子接口,为双向队列。

List 接口

是最常用的接口。是有序集合,允许有相同的元素。使用 List 能够精确地控制每个元素插入的位置,用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,与数组类似。

Set 接口

不能包含重复的元素。

Map 接口

是存放一对值的最大接口,即接口中的每个元素都是一对,以 key➡value 的形式保存。

对于 Set、List、Queue 和 Map 这 4 种集合,Java 最常用的实现类分别是 HashSet、TreeSet、ArrayList、ArrayDueue、LinkedList 和 HashMap、TreeMap 等。下表介绍了集合中这些常用的实现类。

类名称

作用

HashSet

为优化査询速度而设计的 Set。它是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,实现比较简单

TreeSet

实现了 Set 接口,是一个有序的 Set,这样就能从 Set 里面提取一个有序序列

ArrayList

一个用数组实现的 List,能进行快速的随机访问,效率高而且实现了可变大小的数组

ArrayDueue

是一个基于数组实现的双端队列,按“先进先出”的方式操作集合元素

LinkedList

对顺序访问进行了优化,但随机访问的速度相对较慢。此外它还有 addFirst()、addLast()、getFirst()、getLast()、removeFirst() 和 removeLast() 等方法,能把它当成栈(Stack)或队列(Queue)来用

HsahMap

按哈希算法来存取键对象

TreeMap

可以对键对象进行排序

二、Collection接口

Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。

方法名称

说明

boolean add(E e)

向集合中添加一个元素,如果集合对象被添加操作改变了,则返回 true。E 是元素的数据类型

boolean addAll(Collection c)

向集合中添加集合 c 中的所有元素,如果集合对象被添加操作改变了,则返回 true。

void clear()

清除集合中的所有元素,将集合长度变为 0。

boolean contains(Object o)

判断集合中是否存在指定元素

boolean containsAll(Collection c)

判断集合中是否包含集合 c 中的所有元素

boolean isEmpty()

判断集合是否为空

Iterator<E>iterator()

返回一个 Iterator 对象,用于遍历集合中的元素

boolean remove(Object o)

从集合中删除一个指定元素,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法将返回 true。

boolean removeAll(Collection c)

从集合中删除所有在集合 c 中出现的元素(相当于把调用该方法的集合减去集合 c)。如果该操作改变了调用该方法的集合,则该方法返回 true。

boolean retainAll(Collection c)

从集合中删除集合 c 里不包含的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回 true。

int size()

返回集合中元素的个数

Object[] toArray()

把集合转换为一个数组,所有的集合元素变成对应的数组元素。

三、List集合

List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。

List 实现了 Collection 接口,它主要有两个常用的实现类:ArrayList 类和 LinkedList 类。

1、ArrayList 类

ArrayList 类实现了可变数组的大小,存储在内的数据称为元素。

ArrayList 类的常用构造方法有如下两种重载形式:

            1、ArrayList():构造一个初始容量为 10 的空列表。

            2、ArrayList(Collection<?extends E>c):构造一个包含指定 Collection 元素的列表,这些元素是按照该 Collection 的迭代器返        回它们的顺序排列的。

2、LinkedList类

LinkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素。

3、ArrayList 类和 LinkedList 类的区别

ArrayList 与 LinkedList 都是 List 接口的实现类,因此都实现了 List 的所有未实现的方法,只是实现的方式有所不同。

ArrayList 是基于动态数组数据结构的实现,访问元素速度优于 LinkedList。LinkedList 是基于链表数据结构的实现,占用的内存空间比较大,但在批量插入或删除数据时优于 ArrayList。

对于快速访问对象的需求,使用 ArrayList 实现执行效率上会比较好。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高。

四、Set集合

Set 实现了 Collection 接口,它主要有两个常用的实现类:HashSet 类和 TreeSet类。

1、HashSet 类

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 是按照 Hash 算法来存储集合中的元素。因此具有很好的存取和查找性能。

HashSet 具有以下特点: ​ 1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。 ​ 2、HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。 ​ 3、集合元素值可以是 null。

五、Map集合

Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据。

Map 集合里保存着两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 的 key 不允许重复,value 可以重复,即同一个 Map 对象的任何两个 key 通过 equals 方法比较总是返回 false。

Map 中的 key 和 value 之间存在单向一对一关系,即通过指定的 key,总能找到唯一的、确定的 value。从 Map 中取出数据时,只要给出指定的 key,就可以取出对应的 value。

Map接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。

Map 集合最典型的用法就是成对地添加、删除 key-value 对,接下来即可判断该

* Map 中是否包含指定 key,也可以通过 Map 提供的 keySet() 方法获取所有 key

* 组成的集合,进而遍历 Map 中所有的 key-value 对。

1、排序(正向和逆向)

Collections 提供了如下方法用于对 List 集合元素进行排序。

void reverse(List list):对指定 List 集合元素进行逆向排序。

void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。

void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。

void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。

void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。

void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。

2、查找、替换操作

Collections 还提供了如下常用的用于查找、替换集合元素的方法。

int binarySearch(List list, Object key):使用二分搜索法搜索指定的 List 集合,以获得指定对象在 List 集合中的索引。如果要使该方法可以正常工作,则必须保证 List 中的元素已经处于有序状态。

Object max(Collection coll):根据元素的自然顺序,返回给定集合中的最大元素。

Object max(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最大元素。

Object min(Collection coll):根据元素的自然顺序,返回给定集合中的最小元素。

Object min(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最小元素。

void fill(List list, Object obj):使用指定元素 obj 替换指定 List 集合中的所有元素。

int frequency(Collection c, Object o):返回指定集合中指定元素的出现次数。

int indexOfSubList(List source, List target):返回子 List 对象在父 List 对象中第一次出现的位置索引;如果父 List 中没有出现这样的子 List,则返回 -1。

int lastIndexOfSubList(List source, List target):返回子 List 对象在父 List 对象中最后一次出现的位置索引;如果父 List 中没有岀现这样的子 List,则返回 -1。

boolean replaceAll(List list, Object oldVal, Object newVal):使用一个新值 newVal 替换 List 对象的所有旧值 oldVal。

八、Lambda表达式遍历Collection集合

Java 8 为 Iterable 接口新增了一个 forEach(Consumer action) 默认方法,该方法所需参数的类型是一个函数式接口,而 Iterable 接口是 Collection 接口的父接口,因此 Collection 集合也可直接调用该方法。

当程序调用 Iterable 的 forEach(Consumer action) 遍历集合元素时,程序会依次将集合元素传给 Consumer 的 accept(T t) 方法(该接口中唯一的抽象方法)。正因为 Consumer 是函数式接口,因此可以使用 Lambda 表达式来遍历集合元素。

九、Iterator(迭代器)

Iterator(迭代器)是一个接口,它的作用就是遍历容器的所有元素,也是 Java 集合框架的成员,但它与 Collection 和 Map 系列的集合不一样,Collection 和 Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问)Collection 集合中的元素。

Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。Iterator 接口里定义了如下 4 个方法。 ​ 1、boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回 true。 ​ 2、Object next():返回集合里的下一个元素。 ​ 3、void remove():删除集合里上一次 next 方法返回的元素。 ​ 4、void forEachRemaining(Consumer action):这是 Java 8 为 Iterator 新增的默认方法,该方法可使用 Lambda 表达式来遍 历集合元素。

Java 8 为 Iterator 引入了一个 forEachRemaining(Consumer action) 默认方法,

* 该方法所需的 Consumer 参数同样也是函数式接口。当程序调用 Iterator 的

* forEachRemaining(Consumer action) 遍历集合元素时,程序会依次将集合元素传给

* Consumer 的 accept(T t) 方法(该接口中唯一的抽象方法)

Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值