Java 基础总结(一)

Java 基础知识总结

一、Java概述

JDK:Java Development Kit,java的开发和运行环境,java的开发工具和jre。

JRE:Java Runtime Environment,java程序的运行环境,java运行的所需的类库+JVM(java虚拟机)。

JVM:Java Virtual Machine,java虚拟机,用于保证java的跨平台的特性(java语言是跨平台,JVM不是跨平台的)。

配置环境变量:让java jdk\bin目录下的工具,可以在任意目录下运行,原因是,将该工具所在目录告诉了系统,当使用该工具时,由系统帮我们去找指定的目录。

win10 配置Java环境变量例子

1、打开 我的电脑 -> 属性 -> 高级系统设置 -> 高级 -> 环境变量 -> 系统变量 
2、添加系统变量 JAVA_HOME
    
    变量名:JAVA_HOME
    变量值:C:\Program Files\Java\jdk1.8.0_201

3、添加系统变量 CLASSPATH

    .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar

4、在系统变量 PATH 中,添加环境变量
    
    %JAVA_HOME%\bin
    %JAVA_HOME%\jre\bin

5、打开 cmd 命令提示符,验证 java 环境是否安装成功

    javac / java -version

注意:在定义classpath环境变量时,如果没有定义环境变量classpath,java启动jvm后,会在当前目录下查找要运行的类文件;如果指定了classpath,那么会在指定的目录下查找要运行的类文件。

CLASSPATH环境变量:它是javac编译器的一个环境变量。它的作用与import、package关键字有关。当你写下improt java.util.*时,编译器面对import关键字时,就知道你要引入java.util这个package中的类;但是编译器如何知道你把这个package放在哪里了呢?所以你首先得告诉编译器这个package的所在位置;如何告诉它呢?就是设置CLASSPATH,如果java.util这个package在c:/jdk/ 目录下,你得把c:/jdk/这个路径设置到CLASSPATH中去!当编译器面对import java.util.*这个语句时,它先会查找CLASSPATH所指定的目录,并检视子目录java/util是否存在,然后找出名称吻合的已编译文件(.class文件)。如果没有找到就会报错!CLASSPATH有点像c/c++编译器中的INCLUDE路径的设置哦,是不是?当c/c++编译器遇到include 这样的语句,它是如何运作的?哦,其实道理都差不多!搜索INCLUDE路径,检视文件!当你自己开发一个package时,然后想要用这个package中的类;自然,你也得把这个package所在的目录设置到CLASSPATH中去!CLASSPATH的设定,对JAVA的初学者而言是一件棘手的事。所以Sun让JAVA2的JDK更聪明一些。你会发现,在你安装之后,即使完全没有设定CLASSPATH,你仍然能够编译基本的JAVA程序,并且加以执行。

PATH环境变量:PATH环境变量。作用是指定命令搜索路径,在命令行下面执行命令如javac编译java程序时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序。我们需要把jdk安装目录下的bin目录增加到现有的PATH变量中,bin目录中包含经常要用到的可执行文件如javac/java/javadoc等待,设置好PATH变量后,就可以在任何目录下执行javac/java等工具了。

 javac:负责的是编译的部分,当执行javac时,会启动java的编译器程序。对指定扩展名的.java文件进行编译。 生成了jvm可以识别的字节码文件。也就是class文件,也就是java的运行程序。

  java:负责运行的部分,会启动jvm,加载运行时所需的类库,并对class文件进行执行, 一个文件要被执行,必须要有一个执行的起始点,这个起始点就是main函数。

------------------------------------------------------------------------------------------------------

环境配置好后,搭建第一个Java程序

1、以记事本等文本编辑器新建 HelloJava.java 文件。
2、加入以下内容

   public class HelloJava {
       public static void main(String arg[]){
          System.out.print("hello world");
       }
   }

    注意:class 后的名称要与文件名称相同

3、进入当前文件所在目录,打开cmd。
4、执行 javac HelloJava.java 命令进行编译,编译成功后会生产同文件名的.class文件。
5、执行 java HelloJava 命令启动程序。

控制台输入输出

    import  java.util.Scanner; 
    Scanner in = new Scanner(System.in);
    System.out.println("请输入您的名字:");
    String name = in.nextLine();
    Systme.out.println("请属于一个整数:");
    Integer num = in.nextInt();

    补充:根据不同类型,使用不同方法接收数据

        1、nextLine()
        2、next()
        3、nextInt()
        4、nextDouble()
        5、nextByte()
        6、nextFloat()
        7、nextShort()
        ... 
        等(自行查找)

二、Java基础

数据类型

在Java中,数据类型分为基本数据类型和引用数据类型。
基本数据类型有数值型,字符型,布尔类型。其中数值型分为整数形和浮点型。
引用数据类型有类、接口、数组

基本数据类型依次为:byte、short、int、long、float、double、char、boolean

        字节    位数
byte     1       8
short    2       16
int      4       32 
long     8       64
float    4       32
double   8       64
char     2       16
boolean  1       8

变量

变量的命名必须是合法的标识符,标识符是由任意的字母、数字、下划线、美元符号和数字组成,并且第一个字符不能是数字,标识符也不能是Java中的保留关键字。

Java关键字
intpublicthisfinallybooleanabstractcontinuefloat
longshortthrowthrowsreturnbreakforstatic
newinterfaceifgotodefaultbytedocase
strictfppackagesupervoidtryswitchelsecatch
implementprivatefinalclassextendsvolatilewhilesynchronized
instanceofcharprotectedimporttransientdafaultdouble

说明:Java中可以使用汉字作为表示符,例如: int 年龄 = 13;在程序运行时不会出错,但是不建议使用。

final 关键字

在程序中一直不会改变的量称为常量,通常也被称为 “final变量”。常量在整个程序中只被赋值一次。当定义的final变量属于全局变量(成员变量)时,必须在定义时就设置其初始值。而局部变量可不设置初始值。

    final修饰类时:不能被继承
    final修饰方法时:不能被覆盖(重写),但是可以被继承
    final修饰变量时:表示常量,只能被赋值一次,赋值后不可以修改
    final不能修饰构造方法
    
使用final的原因:
    1、把方法锁定,防止任何继承类修改其意义和实现
    2、高效。编译器在遇到有final时,会转入内嵌机制,大大提高效率。(在《Java编程思想》中有存疑)

运算符

1、算术运算符

    +、-、*、/、%、++、--

2、赋值运算符

    =、+=、-=、*=、/=、%=

3、比较运算符

    <、>、=、<=、>=、==、!=

4、逻辑运算符

    &&、&、||、!

5、位运算符
    
    &、|、^、~

6、条件运算符(三元运算符)

    布尔表达式 ? 表达式1 :表达式2

7、移位操作
    
    <<、>>、>>>

注意:

    1、算数运算符中,0不能作为除数。
    2、在逻辑运算符中,&&和&的区别是:&&具有短路功能,&没有。
    3、异或运算(^)规则:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
    4、按位与运算(&)规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为 
       0。
    5、按位或运算(|)规则:两个数都转为二进制,然后从高位开始比较,两个数只要有一个为1则为1,否 
       则就为0。
    6、按位异或(^)规则:两个数都转为二进制,然后从高位开始比较,两个数同时为0或1时,结果为0,否 
       则为1。
    7、位非(按位取反)运算(~)规则:如果位为0,结果是1,如果位为1,结果是0。
       在Java中,所有数据的表示方法都是以补码的形式表示,如果没有特殊说明,Java中的数据类型默认            
       是int,int数据类型的长度是8位,一位是四个字节,就是32字节,32bit.

       例:37转为二进制是100101,补码后为:00000000 00000000 00000000 00100101
          取反为:11111111 11111111 11111111 11011010
          因为高位是1,所以原码为负数,负数的补码是其绝对值的原码取反,末尾再加1。
          因此,我们可将这个二进制数的补码进行还原:首先,末尾减1得反码:11111111 11111111     
          11111111 11011001 其次,将各位取反得原码:00000000 00000000 00000000 00100110,
          此时二进制转原码为38。
          所以~37 = -38. 

    8、左移(<<):就是将运算符左边的操作数的二进制数据按照运算符右边操作数指定的位数向左移动,右 
       面移空的部位补0。一个数左移n,相当于这个数乘以2的n次方。
    9、右移(>>): 就是将运算符左边的操作数的二进制数据按照运算符右边操作数指定的位数向右移动,如 
       果高位是0,左侧被移空的高位就填入0,如果高位是1,左侧被移空的高位就填1.
        
        例:101100 >> 1 = 110110
           001101 >> 1 = 000110

    10、无符号右移(>>>):无论高位是0还是1,左侧被移空的高位都填入0。

运算符由高到低的顺序是

增量和减量运算 -> 算术运算符 -> 比较运算符 -> 逻辑运算符 -> 赋值运算符
如果两个运算有相同的优先级,那么左边的表达式要比右面的表达式优先被处理。
运算符优先级
优先级描述运算符
1括号()
2正负号+、-
3一元运算符++、--、!
4乘除、取余*、/、%
5加减+、-
6移位运算>>、<<、>>>
7比较大小<、>、<=、>=
8比较是否相等==、!=
9按位与运算&
10按位异或运算^
11按位或运算|
12逻辑与运算&&
13逻辑或运算||
14三元运算符? :
15赋值运算符=

数据转换

隐式类型转换:从低类型向高类型的转换,系统将自动执行。
从高到低排列顺序为byte < short < int < long < float < double

显式类型转换:从高类型向低类型的转换,又称强制类型转换。
当执行显示类型转换时,可能导致数据精度丢失,只要是 boolean 类型以为其他基本类型之间的转换,全部都能以显式类型转换的方法达到。

转义字符

转义字符是Java中一种特殊的字符变量,它以反斜杠"\"开头,后面跟一个或多个字符。
转义字符有特殊的含义,不同于字符串原有的意义,故称 “转义”。

转义字符            含义
\ddd                1 ~ 3位八进制数据所表示的字符,如\123 
\uxxxx              4位十六进制数据所表示的字符,如\u0052
\'                  单引号字符
\\                  反斜杠字符
\t                  垂直制表符,将光标移动到下一制表符位置
\r                  回车
\n                  换行
\b                  退格
\f                  换页

控制流程

顺序控制、条件控制、循环控制

1、顺序控制:从上到下依次执行每条语句。
2、条件控制:if()、if -> else、switch()。
3、循环分为:for()、while()、do while()、foreach()。

说明:

    1、switch:

    在jdk1.7版本以前,switch的条件仅限于int类型的值,byte、short、int、char均满足条件
    在jdk1.7版本以后,整形,boolean,String,枚举均支持,当条件为String时,switch会调用
    String.hashCode自动转为int类型

    switch中,如果表达式的值和某个case后面的常量值相同,则执行该case语句后若干个语句,直至遇到 
    break为止。若没有一个常量值与表达式的值相同,则执行default后面的语句,default语句为可选语 
    句,如果不存在,且switch语句中表达式的值不与任何case相同,switch不做任何处理。

   2、while()、do while()

    while()只有条件满足时,才会循环代码块,而do while()中会先执行一次代码块后,在判断循环条件。

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

    表达式1:初始化表达式,负责完成变量得到初始化。
    表达式2:循环条件表达式,值为boolean类型,指定循环条件。
    表达式3:循环后操作表达式,负责修正变量,改变循环条件。

    当执行for循环时,首先执行表达式1,完成初始化工作,下一步判断表达式2的值,若表达式2为true,则 
    进入循环体,之后进行表达式3,结束当前循环体。第二轮循环从表达式2开始,若表达式2为true,则继续 
    循环,否则跳出整个循环。
    
    for(;;) 这样的表达式表示无限循环,可以用break跳出循环。

   4、foreach(元素变量x:遍历对象)

    元素变量x,不必对其进行初始化。

   5、break、continue

    break、continue都可以在循环中使用,但是break可以在switch中使用,continue不可以。

    break表示跳出当前循环或跳出当前switch语句块,当有多层循环时break只跳出其“包裹”循环,无法跳出    
    所有循环。同样,在多层 switch 嵌套的程序中,break 也只能跳出其所在的距离它最近的 switch。但 
    多层 switch 嵌套实在是少见。

    continue为结束本次循环,即跳过循环体中未执行的代码块,重新执行下一次是否循环的判断。

    在嵌套循环,使用break、continue跳出指定循环体,使用标签方法,
     标签名:循环体{
         break 标签名;   
     }

     标签名:循环体{
         continue 标签名;   
     }

String

String 源码:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    ........
}

1、String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。
2、String类其实是通过char数组来保存字符串的。
3、无论是sub、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串 
   对象。也就是说进行这些操作后,最原始的字符串并没有被改变。

String对象一旦被创建就是固定不变的了,对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象。
Java中String是一个特殊的包装类数据,有两种创建形式:

    1、String s1 = "s1";
    2、String s2 = new String("s2");

    第一种创建方式,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中    
    的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串     
    的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串
    
    第二种创建方式直接在堆内存中创建对象

注意:String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了。这里的不可变是指引用对象不可变,而引用对象所指向的值还是可变的。如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类。

Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。
所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)变量,还包含类、方法的信息,占用class文件绝大部分空间。
而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。
==和equals的区别:
java所有类都继承于Object基类,而Object中equals用==来实现,所以equals和==是一样的,都是比较对象地址,java api里的类大部分都重写了equals方法,包括基本数据类型的封装类、String类等。对于String类==用于比较两个String对象的地址,equals则用于比较两个String对象的内容(值)。

1、字符串常量池的使用
    String s0 = "abc"; 
    String s1 = "abc"; 
    System.out.println(s0==s1); //true  可以看出s0和s1是指向同一个对象的。

2、==与equals的区别 
    String s0 =new String ("abc"); 
    String s1 =new String ("abc"); 
    System.out.println(s0==s1); //false 可以看出用new的方式是生成不同的对象 
    System.out.println(s0.equals(s1)); //true 可以看出equals比较的是两个String对象的内容(值)

3、编译期确定
    String s0="helloworld"; 
    String s1="helloworld"; 
    String s2="hello" + "word"; 
    System.out.println( s0==s1 ); //true 可以看出s0跟s1是同一个对象 
    System.out.println( s0==s2 ); //true 可以看出s0跟s2是同一个对象

    解析:因为例子中的 s0和s1中的"helloworld”都是字符串常量,它们在编译期就被确定了,所以s0==s1    
         为true;而"hello”和"world”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它 
         自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池 
         中"helloworld”的一个引用。所以我们得出s0==s1==s2;

4、编译期无法确定
    String s0="helloworld"; 
    String s1=new String("helloworld"); 
    String s2="hello" + new String("world"); 
    System.out.println( s0==s1 ); //false  
    System.out.println( s0==s2 ); //false 
    System.out.println( s1==s2 ); //false

    解析:用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符 
         串不放入常量池中,它们有自己的地址空间。

5、编译期优化
    String s0 = "a1"; 
    String s1 = "a" + 1; 
    System.out.println((s0 == s1)); //result = true  
    String s2 = "atrue"; 
    String s3= "a" + "true"; 
    System.out.println((s2 == s3)); //result = true  
    String s4 = "a3.4"; 
    String s5 = "a" + 3.4; 
    System.out.println((a == b)); //result = true

    解析:在程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化 
         后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为 
         true。

6、编译期无法确定 
    String s0 = "ab"; 
    String s1 = "b"; 
    String s2 = "a" + s1; 
    System.out.println((s0 == s2)); //result = false

    解析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是 
         无法确定的,即"a" + s1无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋 
         给s2。所以上面程序的结果也就为false。

7、编译期确定 
    String s0 = "ab"; 
    final String s1 = "b"; 
    String s2 = "a" + s1;  
    System.out.println((s0 == s2)); //result = true

    解析:和[6]中唯一不同的是s1字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量 
         值的一个本地拷贝存储到自己的常量 池中或嵌入到它的字节码流中。所以此时的"a" + s1和"a" + 
         "b"效果是一样的。故上面程序的结果为true。

8、编译期无法确定
    String s0 = "ab"; 
    final String s1 = getS1(); 
    String s2 = "a" + s1; 
    System.out.println((s0 == s2)); //result = false 
    private static String getS1() {  return "b";  }

    解析:JVM对于字符串引用s1,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值 
         和"a"来动态连接并分配地址为s2,故上面 程序的结果为false。
字符串不可变性

 String是不可改变类(记:基本类型的包装类都是不可改变的)的典型代表,也是Immutable设计模式的典型应 
 用,String变量一旦初始化后就不能更改,禁止改变对象的状态,从而增加共享对象的坚固性、减少对象访问的 
 错误,同时还避免了在多线程共享时进行同步的需要。

 Immutable模式的实现主要有以下两个要点:

    1.除了构造函数之外,不应该有其它任何函数(至少是任何public函数)修改任何成员变量。
    2.任何使成员变量获得新值的函数都应该将新的值保存在新的对象中,而保持原来的对象不被修改。
字符串常用方法

    String str = "";

    1、字符串长度

        str.length()

    2、查找指定字符串所在字符串中首次出现位置

        str.indexOf(String str)

    3、查找指定字符串所在字符串中最后出现位置,如果只条件只是""(没有空格),那么将返回字符串的长度

        str.lastIndexOf(String str)

    4、获取指定索引位置的字符

        str.charAt(int index)

    5、字符串截取

        // 表示从 beginIndex 下标开始,一直截取到最后
        str.substring(int beginIndex)
        // 表示从 beginIndex 下标开始,一直接去到 endIndex下标位
        str.substring(int beginIndex, int endIndex)

    6、去除首尾空格

        str.trim()

    7、替换字符串

        str.replace("替换字符串","替换后字符串")

    8、判断字符串的开头与结尾

        str.startsWith(String prefix)
        str.endsWith(String suffix)

    9、字符串比较

       str.equals(String otherStr)
       str.equalsIgnoreCase(String otherStr)
       equals 区分大小写,equalsIgnoreCase不区分大小写

    10、字母大小写转换

        str.toLowerCase(String otherStr)
        str.toUpperCase(String otherStr)

    11、字符串分割

        str.splic(String sign,int limit)
        sign:分割字符串的分隔符,也可以使用正则表达式
        limit:限制的分割次数

    12、格式化字符串
    
        String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。format()方法有两种 
        重载形式。

        a、format(String format, Object... args) 新字符串使用本地语言环境,制定字符串格式和参    
           数生成格式化的新字符串。

            format:格式字符串。
            args:有格式说明符引用的参数。此参数的数目是可变的,可以为0。

        b、format(Locale locale, String format, Object... args) 使用指定的语言环境,制定字符 
           串格式和参数生成格式化的字符串。
           locale:格式化过程中要应用的语言环境。如果为null,则不进行本地化。
           fromat:同上。
           args:  同上。

     13、日期和时间字符串格式化

        使用format格式化字符串进行日期转换。详细转换条件,请见下表。
常规转换符
转换符说明示例
%b、%B结果被格式化为布尔型true
%h、%H结果被格式化为散列码A05A5198
%s、%S结果被格式化为字符串类型"string"
%c、%C结果被格式化为字符类型'a'
%d结果被格式化为十进制整数40
%o结果被格式化为八进制整数11
%x、%X结果被格式化为十六进制整数4b1
%e结果被格式化为用计算机科学计数法表示的十进制数1.700000e+01
%a结果被格式化为带有效位数和指数的十六禁止浮点值0X1.C00000001P4
%n结果为特定于平台的行分隔符
%%结果为字面"值"%

常用的日期格式转换符
转换符说明示例
%te一个月中的某一天2
%tb指定语言环境的月份简称Feb(英文)、二月(中文)
%tB指定语言环境的月份全称February(英文)、二月(中文)
%tA指定语言环境的星期几全称Mondy(英文)、星期一(中文)
%ta指定语言环境的星期几简称Mon(英文)、星期一(中文)
%tc包括全部日期和时间信息星期二 三月 25 13:37:22 CST 2008
%tY4为年份2008

%tj

一年中的第几天(001-366)085
%tm月份03
%td一月中的第几天(01-31)02

%ty

2位年份08
时间格式化转化符
转换符说明示例
%tH2位数字的24时制的小时(00-23)14
%tI2位数字的12时制的小时(01-12)05
%tK2位数字的24时制的小时(0-23)5
%tl2位数字的12时制的小时(1-12)10
%tM2位数字的分钟(00-59)05
%tS2位数字的秒数(00-60)12
%tL3位数字的毫秒数(000-999)920
%tN9位数字的微秒数(000000000-999999999)062000000
%tp指定语言环境下上午或下午标记下午(中文)、pm(英文)
%tz相对于GMT RFC 82格式的数字时区偏移量+0800
%tZ时区缩写形成的字符串CST
%ts1970-01-01 00:00:00 至现在经过的秒数1206426646
%tQ1970-01-01 00:00:00 至现在经过的豪秒数206426737453
常见的日期和时间组合的格式
转换符说明示例
%tF"年-月-日"格式,4位年份2019-02-19
%tD"月/日/年"格式,2位年份19/02/19
%tc全部日期和时间信息星期二 二月 19 15:20:00 CST 2019 
%tr"时:分:秒 PM(AM)"格式 24小时制03:22:03 下午
%tT"时:分:秒"格式 24小时制15:23:50
%tR"时:分"格式 24小时制15:25

正则表达式

   正则表达式通常被用于判断语句中,用来检查某一字段是否满足某一格式。正则表达式是含有一些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符。

正则表达式中的元字符
元字符正则表达式中写法意义
..代表任意一个字符
\d\d代表0-9的任意一个数字
\D\D代表任何一个非数字字符
\s\s代表空白字符,如'\t'、'\n'
\S\S代表非空白字符
\w\w代表可用作标识符的字符,但不包括"$"
\W\W代表不可用作标识符的字符
\p{Lower}\p{Lower}代表小写字母 a-z
\p{Upper}\p{Upper}代表大写字母 A-Z
\p{ASCII}\p{ASCII}ASCII 字符
\p{Alpha}\p{Alpha}字母字符
\p{Digit}\p{Digit}十进制数字,即 0-9
\p{Alnum}\p{Alnum}数字或字母字符
\p{Punct}\p{Punct}标点符号:!"#$%&'()*+,-/:;<=>?@[\]^_`{|}~
\p{Graph}\p{Graph}可见字符:[\p{Alnum}\p{Punct}]
\p{Print}\p{Print}可打印字符:[\p{Graph}\x20]
\p{Blank}\p{Blank}空格或制表符:[\t]
\p{Cntrl}\p{Cntrl}控制字符:[\x00-\x1F\x7F]

 在正则表达式中,"."代表任何一个字符,因此在正则表达式中如果想使用普通意义的点"."字符,必须用转义字符"\"进行转义。

 在正则表达式中,允许使用限定修饰符来限定元字符出现的次数。

限定修饰符
限定修饰符意义示例
?0次或1次A?
*0次或多次A*
+一次或多次A+
{n}正好出现n次A{2}
{n,}至少出现n次A{2,}
{n,m}出现n-m次A{2,4}

数组

    数组是最为常见的一种数据结构,是相同类型的、用一个标识符封装到一起的基本类型数据序列或对象序列。可以用一个统一的数组名和下标来唯一确定数组中的元素。实际上,数组是一个简单的线性序列,因此访问速度很快。

概述:数组是具有相同数据类型的一组数据集合。

声明:

    1、数组元素类型 数组名字[];
    2、数组元素类型[] 数组名字;

初始化:

    1、数组元素类型 数组名字[] = new 数组元素的类型[数组元素的个数];
    2、数组元素类型 数组名字[] = new 数组元素的类型[]{值1,值2,...,值n};
    3、数组元素类型 数组名字[] = {值1,值2,...,值n};

二维数组:如果一维数组中的各个元素仍然是一个数组,那么他就是一个二维数组。二维数组常用于表示表,表中的信息以行和列的形式组织,第一个下标表示所在行,第二个下标表示元素所在列。

声明:

    1、数组元素的类型 数组名字[][];
    2、数组元素的类型[][] 数组名字;

初始化:

    1、先new运算符进行分配,在分别为每一维数组分配内存

        int marray[][] = new int[2][4];
        marray[0] = new int[4];
        marray[1] = new int[4];

    2、声明同时为数组分配内存
    
        int marray[][] = {value1,value2,...,value};

数组常用的操作

1、数组的长度

    数组有length属性,数组名.length即为数组数组长度。

2、填充替换数组元素(仅以int类型说明)

    Arrays.fill(int a[], int value)
    Arrays.fill(int a[], int fromIndex, int toIndex, int value)

    a:要进行填充的数组。
    fromIndex:要使用指定值填充的第一个元素的索引(包括第一个元素)。
    toIndex:要是有指定值填充的最后一个元素的索引(不包括最后一个元素)。
    value:要存储在数组所有元素中的值。

3、数组排序

    通过Arrays的sort()方法可以实现数组排序。sort()方法提供了多种重载形式,可以对任意类型的数组进行        
    升序排序。

4、复制数组

    Arrays的copyOf()方法和copyOfRange()方法可以实现对数组的复制。copyOf()方法是复制数组至指定 
    长度,copyOfRange()方法则是将指定数组的指定长度复制到一个新数组中。

    Arrays.copyOf(arr, int newLength)
    Arrays.copyOfRange(arr, int fromIndex, int toIndex)

    arr:要进行复制的数组对象。
    newLength:复制后的新数组长度。如果新数组长度大于数组arr的长度,新位置用0填充。如果复制后的 
               数组长度小于数组arr的长度,则会在数组arr的第一个元素开始截取至满足新数组长度为 
               止。
    fromIndex:开始复制数组的索引位置。必须0至整个数组的长度区间,新数组包括索引是fromIndex的元 
               素。
    toIndex:复制范围的最后索引位置。可大于arr的长度范围,新数组不包括索引是toIndex的元素。

5、数组查询

    Arrays类的binarySearch()方法,可使用二分搜索法来搜索指定数组,以获得指定对象。该方法返回要 
    搜索元素的索引值,

    binarySearch(Object[] arr, Object key)
    binarySearch(Object[] arr, int fromIndex, int toIndex, Object key)

    arr:要搜索的数组
    key:要搜索的值
    fromInde:指定范围的开始处索引
    toIndex:指定范围内结束出索引

    binarySearch()方法的返回值
    1、如果找到关键字,则返回值为关键字在数组中的位置索引,且索引从0开始
    2、如果没有找到关键字,返回值为负的插入点值,所谓插入点值就是第一个比关键字大的元素在数组中的         
       位置索引,而且这个位置索引从1开始。

    注意:调用binarySearch()方法前要先调用sort方法对数组进行排序,否则得出的返回值不定,这时二分 
          搜索算法决定的。

数组排序算法

  数组的排序有:冒泡排序、直接选则排序、反转排序

1、冒泡排序:对比相邻的元素值,如果满足条件就交换元素值,把小的元素移到数组前面,把大的元素移到数组后面(也就是两个元素互换位置),这样小的元素就像气泡一样从底部上升到顶部。

实现方式:冒泡排序由双层循环实现,其中外层循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要进行对比同时数组已经进行完排序了。而内循环主要用于对比数组中每个临近元素的大小,以确定是否交换位置,对比和交换次数随配许轮数减少而减少。

int[] arr = {65,23,1,2,5,3,9};

for(int i = 1; i < arr.length; i++){
    for(int j = 0; j < arr.length-i; j++){
        if(arr[j] > arr[j+1]){
            int temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
        }
    }
}

2、直接选择排序:是选择排序的一种,排序速度要比冒泡排序快一些。

实现方式:将指定排序位置与其他数组元素分别对比,如果满足条件就进行元素交换,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定元素位置交换。就是说,每一趟从待排序的数据元素中选出最小(最大)的元素,顺序放在待排序的数列最前,直到全部待排序的数据元素全部排完。与冒泡排序相比,直接选中排序的交换次数要少,所以速度更快。

int[] arr = {63,4,24,1,3,5,2};

for(int i = 1; i <arr.length; i++){
    int index = 0;
    for(int j = 1; j <= arr.length - i; j++){
        if(arr[j] > arr[index]){
            index = j;
        }
    }

    int temp = arr[arr.length - i];
    arr[arr.length - i] = arr[index];
    arr[index] = temp;
}

反转排序:以相反的顺序把原有的数组的内容重新排序。

实现方式:就是把数组最后一个元素与第一个元素替换,到数第二个元素与第二个元素替换,依此类推。在循环时,只需要循环数组长度的半数。

int arr = {10, 20, 30, 40, 50, 60};

for(int i = 0; i < arr.length/2 -1; i++){
    int temp = arr[i];
    arr[i] = arr[arr.length - i];
    arr[arr.length - i] = temp;
}

类和对象

对象:是描述事物存在的实体。

类:同一类事物的统称。类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的实体被称为类。

权限修饰符

当前类同包子类其他类 
public
protected×
default××
private×××

成员变量和局部变量

通常将类的属性称为类的全局变量(成员变量),将方法中的属性称为局部变量。全局变量声明在类体中,局部变量声明在方法体中。全局变量和局部变量都有各自的应用范围。

成员方法

权限修饰符 返回值类型 方法名(参数类型 参数名...){
    // 方法体
    return 返回值;
}

Java中成员方法无返回值时,用void修饰符修饰

this关键字

this.属性名称                
    指的是访问类中的成员变量,用来区分成员变量和局部变量(重名问题)

this.方法名称              
    用来访问本类的成员方法

this()                        
    访问本类的构造方法,()中可以有参数的,如果有参数就是调用指定的有参构造

    注意事项:
         1、this() 不能使用在普通方法中,只能写在构造方法中
         2、必须是构造方法中的第一条语句

类的构造方法

构造方法就是与类名相同的方法,对象的创建就是通过构造方法完成的,每当类实例化一个对象时,类都会自动调用构造方法。

注意:

  1. 只有当类中没有定义任何构造方法时,编译器会自动创建一个无参的构造方法。否则,只能调用当前类中的构造方法初始化。
  2. 构造方法无返回值项。如果存在返回值项,该方法则不是构造方法。 
  3. 构造方法的名要与类名相同。

static 关键字

由 static 关键字修饰的变量、常量和方法被称为静态变量、常量和方法,也被称为静态成员。静态成员属于类所有,可以在本类和其他类使用 “类名.”调用静态成员。

注意:

  1. 在静态方法中不可以使用this关键字。
  2. 在静态方法中不可以直接调用非静态方法

类的主方法(入口)

Java编译器通过主方法来编译程序。

public static void main(String[] args){

}

注意:

主方法是静态的,所以如果要直接调用的方法也是静态的
主方法没有返回值
主方法的形参为数组

对象

对象的创建:使用new操作符调用构造方法创建对象。

对象的销毁:每个对象都有声命周期,当对象的声命周期结束时,分配给该对象的内存地址将会被回收。Java中有垃圾回收机制。

有两种情况,对象被视为垃圾

  1. 对象的引用超过其作用范围,这个对象将被视为垃圾
  2. 将对象赋值为null

虽然垃圾回收机制已经很完善,但垃圾回收器只能回收那些由new操作符创建的对象。如果某些对象不是通过new操作符在内存中获取一块内存区域,这种对象可能部内垃圾回收机制所识别,所以在Java中提供了一个finalize()方法。这个方法是Objectlei下的方法,它被声明proteccted,用户可以在自己的类中定义这个方法。如果用户在类中定义了finalize()方法,在垃圾回收时会首先调用该方法,在下一次垃圾回收动作发生时,才能真正回收被对象占用的内存。

注意:垃圾回收或finalize()方法不保证被调用时立即执行,如Java虚拟机内存损耗殆尽时,它是不会执行垃圾回收的。为此Java提供了System.gc()方法强制启动垃圾回收器。

包装类

包装类就是将基本类型数据转成对象。

Integer类,Long类和Short类,分别将基本类型int,long和short封装成一个类。由于这些类都是Number子类,区别就是封装不同的数据类型,其包含的方法基本相同,因此只以Integer为例。

Integer的构造方法有两种

    1、Integer(int num)
    2、Integer(String str)  .. 此时str为数字字符串,否则会报转换异常(NumberFormatException)

常用方法

   byteValue()                    以byte类型返回该数值。 

   compareTo(int otherInteger)    在数字上比较俩个Integer对象,相等返回0,小于other返回复数,大            
                                  于other返回正数。

   equals(Object IntegerObj)      比较此对象与指定对象是否相等

   intValue()                     以int型返回当前对象

   shortValue()                   以short型返回当前对象

   toString()                     返回一个表示该Integer值的String对象


   valueOf(String str)            返回保存指定的str值的Integer对象

   parseInt(String str)           返回包含在由str指定的字符串中的数字的等价整数值

常量

    MAX_VALUE    表示int类型可取的最大值,2的32次幂-1
    MIN_VALUE    表示int类型可取的最小值,-2的32次幂
    SIZE         用来以二进制补码形式表示int值的位数
    TYPE         表示基本类型int的Class实例

Integer类的toString()方法,可将Integer对象转换为十进制字符的表示。toBinaryString()方法转换为二进制字符串,toHexString()方法转换为十六进制字符串,toOctalString()转换为八进制字符串。

Boolean类

Boolean类将boolean的值包装在一个对象中。

1、构造方法

    Boolean(boolean value)

    Boolean(String str)  // 说明:如果String类型不为空且忽略大小写时为true,否则为false

2、常用方法

    booleanValue()             将Boolean对象的值以对应的boolean值返回

    equals(Obj obj)            用于对象比较

    parseBoolean(String s)     将字符串参数解析为boolean值

    toString()                 返回表示该boolean值的String对象

    valueOf(String s)          返回一个用指定的字符串表示值的boolean值

3、常量

    TRUE      对应基值true的Boolean对象
    FALSE     对应基值false的Boolean对象
    TYPE      基本类型boolean的Class对象

Byte类

Byte类将基本类型byte的值包装在一个对象中。

1、构造方法

    
    Byte(byte value)

    Byte(String str)  // 必须使用数值型变量,否则会抛出NumberFormatException

2、常用方法

    byteValue()                以一个byte值返回Byte对象

    compareTo(Byte anOther)    在数字上比较两个Byte对象

    doubleValue()              以一个double值返回此Byte的值

    intValue()                 以一个int值返回此Byte的值

    paresByte(String s)        将String型参数解析成等价的字节byte形式

    toString()                 返回b表示此Byted的值的String对象

    valueOf(String str)        返回一个保持指定String所给出的的值的Byte对象

    equals(Object obj)         用于对象比较

3、常量

    MIN_VALUE     byte类型可取最小值
    MAX_VALUE     byte类型可取最大值
    SIZE          用于以二进制补码形式表示byte值的位数
    TYPE          表示基本类型byte的Class实例
    

Character类

Character类在对象中包装一个基本类型为char的值。

1、构造方法

    Character(char value)

2、常用方法

    charvalue()                   返回此Charcter对象的值

    compareTo(Character other)    比较两个Character对象,相等返回0

    equals(Object obj)            用于对象比较

    toUpperCase(char ch)          将字符参数转换为大写

    toLowerCase(char ch)          将字符参数转换为小写

    toString()                    返回一个表示指定char值的String对象

    charValue()                   返回此Character对象的值

    isUpperCase(char ch)          判断指定字符是否为大写字符

    isLowerCase(char ch)          判断指定字符是否为小写字符
    

Double类,Float类是对基本数据double、float基本类型的封装,它们都是Number类的子类又是对小数进行的操作,用法基本相同。此以Double类做介绍。

1、构造方法

    Double(double value)

    Double(String str)    // 参数仅为数值型字符串,否则会报NumberFormatException异常

2、常用方法

    byteValue()                以byte形式返回Double对象值(通过强制转换)

    compareTo(Double other)    对两个Double类型进行数值比较,相等返回0,如果大于other返回正    
                                  值,反之,返回复数

    equals(Object obj)         用于对象比较

    intValue()                 以int值返回double值

    isNan()                    如果此double值是非数字(NaN)值,返回true,否则返回false

    toString()                 返回此Double对象的字符串表示形式

    valueOf(String str)        返回保存用参数字符串str表示的double值的Double对象

    doubleValue()              以double形式返回此Double值

    longValue()                以long形式返回此Double值(通过强制转换)

3、常量

    MAX_EXPONENT            返回int值,表示有无限double变量可能具有的最大指数
    MIN_EXPONENT            返回int值,表示标准化double变量可能具有的最小指数
    NEGATIVE_INFINITY       返回double,表示保存double类型的负无穷大值的常量
    POSITIVE_INFINITY       返回double,表示保存double类型的正无穷大值的常量

Number类

抽象类Number是BigDecimal、BigInteger、Byte、Double、Float、Integer、Long和Short的父类,Number的子类必须提供将表示的数值转换为byte、short、int、long、double、float的方法。

Number类的方法

    byteValue()        以byte形式返回指定的数值

    intValue()         以int形式返回指定的数值

    floatValue()       以float形式返回指定的数值

    shortVlaue()       以short形式返回指定的数值

    longValue()        以long形式返回指定的数值

    doubleValue()      以double形式返回指定的数值

数字格式化

在Java中没有格式化的数据遵循以下原则

1、如果数据绝对值大于0.001并且小于10000000,Java将以常规小数表示。

2、如果数据绝对值小于0.001或者大于10000000,Java将以科学计数法表示。

由于上述输出的格式不能满足解决实际问题的要求,通常将结果格式化为指定形式后输出。在Java中使用DecimalFormat类进行格式化操作。DecimalFormat是NumberFormat的一个子类,用于格式化十进制数字。

DecimalFormat类中特殊符号说明
字符说明
0代表阿拉伯数字,使用特殊符号“0”表示数字的一位阿拉伯数字,如果该位不存在数字,则显示0
#代表阿拉伯数字,使用特殊符号“#”表示数字的一位阿拉伯数字,如果该位存在数字,则显示符号;如果该位不存在数字,则不显示
.小数分隔符或货币小数分隔符
-负号
,分组分隔符
E分割科学计数法中的尾数和指数
%本符号放置在数字的前缀或后缀,将数字乘以100显示为百分数
\u2030本符号放置在数字的前缀或后缀,将数字乘以1000显示为千分数
\u00A4本符号放置在数字的前缀或后缀,作为货币记号
'本符号为单引号,当上述特殊字符出现在数字中时,应为特殊符号添加单引号,系统会将此符号视为普通符号处理

数学运算(Math类)

在Java中提供了一个执行数学基本运算的Math类,该类包含常用的数学运算方法,如三角函数法、指数函数法、对数函数法、平方根函数法等一些常用的数学函数。此外还提供了一些常用的数学常量,如PI、E等。

1、三角函数方法

Math类中包含的三角函数方法如下:

public static double sin(double a):返回角的三角正弦
public static double cos(double a):返回角的三角余弦
public static double tan(double a):返回角的三角正切
public static double asin(double a):返回角的三角反正弦
public static double acos(double a):返回角的三角反余弦
public static double atan(double a):返回角的三角反正切
public static double toRadians(double angdeg):将角度转换为弧度
public static double toDegrees(double angdeg):将弧度转换为角度

注意:角度和弧度的转换通常不精确

2、指数函数方法

Math类中与指数相关的函数方法如下:

public static double exp(double a):用于获取e的a次方
public static double log(double a):用于取自然对数,即取lna的值
public static double log10(double a):用于取底数为10的对数
public static double sqrt(double a):用于取a的平方根,其中a的值不能为负值
public static double cbrt(double a):用于取a的立方根
public static double pow(double a,double b):用于取a的b次方

3、取整函数

Math类中与数字取整相关的函数方法如下:

public static double ceil(double a):返回大于等于参数的最小整数
public static double floor(double a):返回小于等于参数的最大整数
public static double rint(double a):返回与参数最接近的整数,如果两个同为整数且同样接近,则取偶数
public static int round(float a):将参数加上0.5后返回与参数最近的整数
public static long round(double a):将参数加上0.5后返回与参数最近的整数,然后强制转换长整型

4、最大值、最小值、绝对值函数

Math类中取最大值、最小值、绝对值相关的函数方法如下:

public static double max(double a,double b):取a与b之间的最大值
public static int min(int a,int b):取a与b之间的最小值,参数类型为整数
public static long min(long a,long b):取a与b之间的最小值,参数类型为长整型
public static float min(float a,float b):取a与b之间的最小值,参数类型为浮点型
public static double min(double a,double b):取a与b之间的最小值,参数类型为双精度型
public static int abs(int a):返回整数参数的绝对值
public static long abs(long a):返回长整型参数的绝对值
public static float abs(float a):返回浮点型参数的绝对值
public static double abs(double a):返回双精度型参数的绝对值

随机数(Math)

1、在Math类中存在一个Random()方法,用于产生随机数字,这个方法默认生成大于等于0.0且小于1.0的double型随机数。但只要稍加处理,就可以产生任意范围的随机数。

例:

  1. 返回大于0且小于n的随机数:(int)(Math.Random() * n)
  2. 返回大于等于m且小于m+n(不包括m+n)的随机数:m+(int)(Math.Random() * n)
  3. 生成a-z之间的随机字符:(char)('a'+Mtah.Random()*('z'-'a'+1))
  4. 生成任意字符之间的随机字符:(char)(char1+Mtah.Random()*(char2-char1+1))

 注意:Random()方法返回值实际上是伪随机数,他通过复杂的运算而得到一系列的数。该方法时通过当前时间作为随机数生成器的参数,所有每次执行程序都会产生不同的随机数。

2、除了Random()方法外,Java还提供 java.util.Random类来获取随机数。

语法:Random r = new Random();

Random类常用语法

public int nextInt():返回一个随机整数
public int nextInt(int n):返回大于0且小于n的随机整数
public long nextLong():返回一个随机长整型值
public boolean nextBoolean():返回一个随机布尔型值
public float nextFloat():返回一个随机浮点型值
public double nextDouble():返回一个随机双精度值
public double nextGaussian():返回一个概率密度为高斯分布的双精度值

大数处理

BigInteger针对大数处理的Java工具类

构造方法:public BigInteger(String val) ,其中参数为String类型 

BigInteger常用方法

public BigInteger add(BigInteger val):加法运算
public BigInteger subtract(BigInteger val):减肥运算
public BigInteger multiply(BigInteger val):乘法运算
public BigInteger divide(BigInteger val):除法运算
public BigInteger remainder(BigInteger val):取余运算
public BigInteger pow(int exponent):进行取参数的exponent次方操作
public BigInteger negate():取相反数
public BigInteger shiftLeft(int n):将数字左移n位,如果n位负数,做右移操作
public BigInteger shiftRight(int n):将数字右移n位,如果n位负数,做左移操作
public BigInteger and(BigInteger val):与操作
public BigInteger or(BigInteger val):或操作
public BigInteger compareTo(BigInteger val):比较操作
public boolean equals(Object x):当参数是BigInteger类型的数字并且数值相等时,返回true
public BigInteger min(BigInteger val):返回较小的数值
public BigInteger max(BigInteger val):返回较大的数值
public BigInteger divideAndRemainder(BigInteger val):用数组返回余数和商,数组中第一个值为商,第二个值为余数

BigDecimal针对大的小数处理的Java工具类

构造方法:

  1. public BigDecimal(double val):实例化时,将双精度型转换为BigDecimal类型。
  2. public BigDecimal(String val):实例化时,将字符串形式转换为BigDecimal类型。
BigDecimal的加减乘除方法

public BigDecimal add(BigDecimal augend):加法运算
public BigDecimal subtract(BigDecimal subtract):减肥运算
public BigDecimal multiply(BigDecimal multiply):乘法运算
public BigDecimal divide(BigDecimal divide,int scale,int roundingMode):除法运算

注意:除法操作的3个参数分别代表除数、商的小数点位数、近似处理模式
BigDecimal类中divide()方法的多种处理模式
模式含义
BigDecimal.ROUND_UP商的最后一位如果大于0,则向前进位,正负数都如此
BigDecimal.ROUND_DOWN商的最后一位无论是什么数字都省略
BigDecimal.ROUND_CEILING商如果是正数,则按照ROUND_UP模式处理;如果是负数,按照OUND_DOWN模式处理。这种模式的处理都会使近似值大于等于实际值
BigDecimal.ROUND_FLOOR商如果是正数,则按照ROUND_DOWN模式处理;如果是负数,按照OUND_UP模式处理。这种模式的处理都会使近似值小于等于实际值
BigDecimal.ROUND_HALF_DOWN对商进行四舍五入操作。如果商的最后一位小于等于5则做舍弃操作;如果最后一位大于5,则做进位操作
BigDecimal.ROUND_HALF_UP对商进行四舍五入操作。如果商的最后一位小于5则做舍弃操作;如果最后一位大于等于5,则做进位操作
BigDecimal.ROUND_HALF_EVEN如果商的到数第二位为奇数,则按照ROUND_HALF_UP处理;如果为偶数,则按ROUND_HALF_DOWN处理

  • 253
    点赞
  • 884
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值