Java基础
类别关键字说明具体知识访问控制private私有的private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)私有访问修饰符-private私有访问修饰符是最严格的访问级别,所以被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问。Private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。protected受保护的protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。public公共的public : 对所有类可见。使用对象:类、接口、变量、方法default默认default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。类、方法和变量修饰符abstract声明抽象抽象类:抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。抽象类可以包含抽象方法和非抽象方法抽象方法抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。抽象方法不能被声明成 final 和 static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。{价值在于被继承后实现}。class类extends扩充、继承final最终值、不可改变的final 变量:final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。final 修饰符通常和 static 修饰符一起使用来创建类常量。final 方法父类中的 final 方法可以被子类继承,但是不能被子类重写。声明 final 方法的主要目的是防止该方法的内容被修改。final 类final 类不能被继承,没有类能够继承 final 类的任何特性。。implements实现(接口)interface接口native本地、原生方法(非 Java 实现)new创建static静态静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。(工具)strictfp严格浮点、精准浮点synchronized线程、同步transient短暂volatile易失程序控制语句break跳出循环case定义一个值以供 switch 选择continue继续do运行else否则for循环if如果instanceof实例return返回switch根据值选择执行while循环错误处理assert断言表达式是否为真异常处理异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出 java.lang.ArithmeticException 的异常。异常发生的原因有很多,通常包含以下几大类:用户输入了非法数据。要打开的文件不存在。网络通信时连接中断,或者JVM内存溢出。这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。-要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。Exception 类的层次所有的异常类是从 java.lang.Exception 类继承的子类。Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。Error 用来指示运行时环境发生的错误。例如,JVM 内存溢出。一般地,程序不会从错误中恢复。异常类有两个主要的子类:IOException 类和 RuntimeException 类。在 Java 内置类中(接下来会说明),有大部分常用检查性和非检查性异常。Java 内置异常类Java 语言定义了一些异常类在 java.lang 标准包中。标准运行时异常类的子类是最常见的异常类。由于 java.lang 包是默认加载到所有的 Java 程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用。Java 根据各个类库也定义了一些其他的异常,下面的表中列出了 Java 的非检查性异常。异常描述ArithmeticException当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。ArrayIndexOutOfBoundsException用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。ArrayStoreException试图将错误类型的对象存储到一个对象数组时抛出的异常。ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。IllegalArgumentException抛出的异常表明向方法传递了一个不合法或不正确的参数。IllegalMonitorStateException抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。IllegalStateException在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。IllegalThreadStateException线程没有处于请求操作所要求的适当状态时抛出的异常。IndexOutOfBoundsException指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。NegativeArraySizeException如果应用程序试图创建大小为负的数组,则抛出该异常。NullPointerException当应用程序试图在需要对象的地方使用null时,抛出该异常NumberFormatException当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。SecurityException由安全管理器抛出的异常,指示存在安全侵犯。StringIndexOutOfBoundsException此异常由String方法抛出,指示索引或者为负,或者超出字符串的大小。UnsupportedOperationException当不支持请求的操作时,抛出该异常。下面的表中列出了 Java 定义在 java.lang 包中的检查性异常类。异常描述ClassNotFoundException应用程序试图加载类时,找不到相应的类,抛出该异常。CloneNotSupportedException当调用Object类中的clone方法克隆对象,但该对象的类无法实现Cloneable接口时,抛出该异常。IllegalAccessException拒绝访问一个类的时候,抛出该异常。InstantiationException当试图使用Class类中的newInstance方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。InterruptedException一个线程被另一个线程中断,抛出该异常。NoSuchFieldException请求的变量不存在NoSuchMethodException请求的方法不存在异常方法下面的列表是 Throwable 类的主要方法:序号方法及说明1public String getMessage()返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。2public Throwable getCause()返回一个 Throwable 对象代表异常原因。3public String toString()返回此 Throwable 的简短描述。4public void printStackTrace()将此 Throwable 及其回溯打印到标准错误流。。5public StackTraceElement [] getStackTrace()返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。6public Throwable fillInStackTrace()用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。捕获异常使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:try{ // 程序代码}catch(ExceptionName e1){ //Catch 块}Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。实例下面的例子中声明有两个元素的一个数组,当代码试图访问数组的第四个元素的时候就会抛出一个异常。ExcepTest.java 文件代码:// 文件名 : ExcepTest.javaimport java.io.;public class ExcepTest{ public static void main(String args[]){ try{ int a[] = new int[2]; System.out.println("Access element three :" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Exception thrown :" + e); } System.out.println("Out of the block"); }}以上代码编译运行输出结果如下:Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3Out of the block多重捕获块一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。多重捕获块的语法如下所示:try{ // 程序代码}catch(异常类型1 异常的变量名1){ // 程序代码}catch(异常类型2 异常的变量名2){ // 程序代码}catch(异常类型3 异常的变量名3){ // 程序代码}上面的代码段包含了 3 个 catch块。可以在 try 语句后面添加任意数量的 catch 块。如果保护代码中发生异常,异常被抛给第一个 catch 块。如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。如果不匹配,它会被传递给第二个 catch 块。如此,直到异常被捕获或者通过所有的 catch 块。实例该实例展示了怎么使用多重 try/catch。try { file = new FileInputStream(fileName); x = (byte) file.read();} catch(FileNotFoundException f) { // Not valid! f.printStackTrace(); return -1;} catch(IOException i) { i.printStackTrace(); return -1;}throws/throw 关键字在Java中, throw 和 throws 关键字是用于处理异常的。throw 关键字用于在代码中抛出异常,而 throws 关键字用于在方法声明中指定可能会抛出的异常类型。throw 关键字throw 关键字用于在当前方法中抛出一个异常。通常情况下,当代码执行到某个条件下无法继续正常执行时,可以使用 throw 关键字抛出异常,以告知调用者当前代码的执行状态。例如,下面的代码中,在方法中判断 num 是否小于 0,如果是,则抛出一个 IllegalArgumentException 异常。实例public void checkNumber(int num) { if (num < 0) { throw new IllegalArgumentException("Number must be positive"); }}throws 关键字throws 关键字用于在方法声明中指定该方法可能抛出的异常。当方法内部抛出指定类型的异常时,该异常会被传递给调用该方法的代码,并在该代码中处理异常。例如,下面的代码中,当 readFile 方法内部发生 IOException 异常时,会将该异常传递给调用该方法的代码。在调用该方法的代码中,必须捕获或声明处理 IOException 异常。实例public void readFile(String filePath) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filePath)); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } reader.close();}一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。例如,下面的方法声明抛出 RemoteException 和 InsufficientFundsException:import java.io.;public class className{ public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } //Remainder of class definition}finally关键字finally 关键字用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。finally 代码块出现在 catch 代码块最后,语法如下:try{ // 程序代码}catch(异常类型1 异常的变量名1){ // 程序代码}catch(异常类型2 异常的变量名2){ // 程序代码}finally{ // 程序代码}实例ExcepTest.java 文件代码:public class ExcepTest{ public static void main(String args[]){ int a[] = new int[2]; try{ System.out.println("Access element three :" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Exception thrown :" + e); } finally{ a[0] = 6; System.out.println("First element value: " +a[0]); System.out.println("The finally statement is executed"); } }}以上实例编译运行结果如下:Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3First element value: 6The finally statement is executed注意下面事项:catch 不能独立于 try 存在。在 try/catch 后面添加 finally 块并非强制性要求的。try 代码后不能既没 catch 块也没 finally 块。try, catch, finally 块之间不能添加任何代码。try-with-resourcesJDK7 之后,Java 新增的 try-with-resource 语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭 。try-with-resources 是一种异常处理机制,它可以简化资源管理代码的编写。JDK7 之前所有被打开的系统资源,比如流、文件或者 Socket 连接等,都需要被开发者手动关闭,否则将会造成资源泄露。try (resource declaration) { // 使用的资源} catch (ExceptionType e1) { // 异常块}以上的语法中 try 用于声明和实例化资源,catch 用于处理关闭资源时可能引发的所有异常。注意:try-with-resources 语句关闭所有实现 AutoCloseable 接口的资源。实例import java.io.;public class RunoobTest { public static void main(String[] args) { String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { while ((line = br.readLine()) != null) { System.out.println("Line =>"+line); } } catch (IOException e) { System.out.println("IOException in try block =>" + e.getMessage()); } }}以上实例输出结果为:IOException in try block =>test.txt (No such file or directory)以上实例中,我们实例一个 BufferedReader 对象从 test.txt 文件中读取数据。在 try-with-resources 语句中声明和实例化 BufferedReader 对象,执行完毕后实例资源,不需要考虑 try 语句是正常执行还是抛出异常。如果发生异常,可以使用 catch 来处理异常。再看下不使用 try-with-resources 而改成 finally 来关闭资源,整体代码量多了很多,而且更复杂繁琐了:实例import java.io.;class RunoobTest { public static void main(String[] args) { BufferedReader br = null; String line; try { System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) { System.out.println("Line =>"+line); } } catch (IOException e) { System.out.println("IOException in try block =>" + e.getMessage()); } finally { System.out.println("Entering finally block"); try { if (br != null) { br.close(); } } catch (IOException e) { System.out.println("IOException in finally block =>"+e.getMessage()); } } }}以上实例输出结果为:Entering try blockIOException in try block =>test.txt (No such file or directory)Entering finally blocktry-with-resources 处理多个资源try-with-resources 语句中可以声明多个资源,方法是使用分号 ; 分隔各个资源:实例import java.io.;import java.util.;class RunoobTest { public static void main(String[] args) throws IOException{ try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { while (scanner.hasNext()) { writer.print(scanner.nextLine()); } } }}以上实例使用 Scanner 对象从 testRead.txt 文件中读取一行并将其写入新的 testWrite.txt 文件中。多个声明资源时,try-with-resources 语句以相反的顺序关闭这些资源。 在本例中,PrintWriter 对象先关闭,然后 Scanner 对象关闭。声明自定义异常在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。所有异常都必须是 Throwable 的子类。如果希望写一个检查性异常类,则需要继承 Exception 类。如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。可以像下面这样定义自己的异常类:class MyException extends Exception{}只继承Exception 类来创建的异常类是检查性异常类。下面的 InsufficientFundsException 类是用户定义的异常类,它继承自 Exception。一个异常类和其它任何类一样,包含有变量和方法。实例以下实例是一个银行账户的模拟,通过银行卡的号码完成识别,可以进行存钱和取钱的操作。InsufficientFundsException.java 文件代码:// 文件名InsufficientFundsException.javaimport java.io.; //自定义异常类,继承Exception类public class InsufficientFundsException extends Exception{ //此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱 private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; }}为了展示如何使用我们自定义的异常类,在下面的 CheckingAccount 类中包含一个 withdraw() 方法抛出一个 InsufficientFundsException 异常。CheckingAccount.java 文件代码:// 文件名称 CheckingAccount.javaimport java.io.; //此类模拟银行账户public class CheckingAccount{ //balance为余额,number为卡号 private double balance; private int number; public CheckingAccount(int number) { this.number = number; } //方法:存钱 public void deposit(double amount) { balance += amount; } //方法:取钱 public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; } else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } //方法:返回余额 public double getBalance() { return balance; } //方法:返回卡号 public int getNumber() { return number; }}下面的 BankDemo 程序示范了如何调用 CheckingAccount 类的 deposit() 和 withdraw() 方法。BankDemo.java 文件代码://文件名称 BankDemo.javapublic class BankDemo{ public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100..."); c.withdraw(100.00); System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); }catch(InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } }}编译上面三个文件,并运行程序 BankDemo,得到结果如下所示:Depositing $500...Withdrawing $100...Withdrawing $600...Sorry, but you are short $200.0InsufficientFundsException at CheckingAccount.withdraw(CheckingAccount.java:25) at BankDemo.main(BankDemo.java:13)catch捕捉异常finally有没有异常都执行throw抛出一个异常对象throws声明一个异常可能被抛出try捕获异常包相关import引入package包基本类型boolean布尔型boolean:boolean数据类型表示一位的信息;只有两个取值:true 和 false;这种类型只作为一种标志来记录 true/false 情况;默认值是 false;例子:boolean one = true。byte字节型byte:byte 数据类型是8位、有符号的,以二进制补码表示的整数;最小值是 -128(-2^7);最大值是 127(2^7-1);默认值是 0;byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;例子:byte a = 100,byte b = -50。char字符型char:char 类型是一个单一的 16 位 Unicode 字符;最小值是 \u0000(十进制等效值为 0);最大值是 \uffff(即为 65535);char 数据类型可以储存任何字符;例子:char letter = 'A';。double双精度浮点double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;浮点数的默认类型为 double 类型;double类型同样不能表示精确的值,如货币;默认值是 0.0d;float单精度浮点float:float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;float 在储存大型浮点数组的时候可节省内存空间;默认值是 0.0f;浮点数不能用来表示精确的值,如货币;例子:float f1 = 234.5f。int整型int:int 数据类型是32位、有符号的以二进制补码表示的整数;最小值是 -2,147,483,648(-2^31);最大值是 2,147,483,647(2^31 - 1);一般地整型变量默认为 int 类型;默认值是 0 ;例子:int a = 100000, int b = -200000。long长整型long:long 数据类型是 64 位、有符号的以二进制补码表示的整数;最小值是 -9,223,372,036,854,775,808(-2^63);最大值是 9,223,372,036,854,775,807(2^63 -1);这种类型主要使用在需要比较大整数的系统上;默认值是 0L;例子: long a = 100000L,long b = -200000L。"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。short短整型short:short 数据类型是 16 位、有符号的以二进制补码表示的整数最小值是 -32768(-2^15);最大值是 32767(2^15 - 1);Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;默认值是 0;例子:short s = 1000,short r = -20000。变量引用super父类、超类this本类void无返回值保留关键字goto是关键字,但不能使用const是关键字,但不能使用 Java的一些类与方法 Java Number & Math 类 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。 实例 int a = 5000; float b = 13.65f; byte c = 0x4a; 然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。 所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。 包装类基本数据类型BooleanbooleanBytebyteShortshortIntegerintLonglongCharactercharFloatfloatDoubledouble
这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。Number 类属于 java.lang 包。 下面是一个使用 Integer 对象的实例: Test.java 文件代码: public class Test{
Math 的 floor,round 和 ceil 方法实例比较
参数Math.floorMath.roundMath.ceil1.41121.51221.6122-1.4-2-1-1-1.5-2-1-1-1.6-2-2-1
floor,round 和 ceil 实例:
public class Main {
public static void main(String[] args) {
double[] nums = { 1.4, 1.5, 1.6, -1.4, -1.5, -1.6 };
for (double num : nums) {
test(num);
}
}
private static void test(double num) {
System.out.println("Math.floor(" + num + ")=" + Math.floor(num));
System.out.println("Math.round(" + num + ")=" + Math.round(num));
System.out.println("Math.ceil(" + num + ")=" + Math.ceil(num));
}
}
以上实例执行输出结果为:
Math.floor(1.4)=1.0
Math.round(1.4)=1
Math.ceil(1.4)=2.0
Math.floor(1.5)=1.0
Math.round(1.5)=2
Math.ceil(1.5)=2.0
Math.floor(1.6)=1.0
Math.round(1.6)=2
Math.ceil(1.6)=2.0
Math.floor(-1.4)=-2.0
Math.round(-1.4)=-1
Math.ceil(-1.4)=-1.0
Math.floor(-1.5)=-2.0
Math.round(-1.5)=-1
Math.ceil(-1.5)=-1.0
Math.floor(-1.6)=-2.0
Math.round(-1.6)=-2
Math.ceil(-1.6)=-1.0
Java Character 类
Character 类用于对单个字符进行操作。
Character 类在对象中包装一个基本类型 char 的值
实例
char ch = 'a';
// Unicode 字符表示形式
char uniChar = '\u039A';
// 字符数组
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' }; 然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情况。为了解决这个问题,Java语言为内置数据类型char提供了包装类Character类。 Character类提供了一系列方法来操纵字符。你可以使用Character的构造方法创建一个Character类对象,例如: Character ch = new Character('a'); 在某些情况下,Java编译器会自动创建一个Character对象。 例如,将一个char类型的参数传递给需要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。 这种特征称为装箱,反过来称为拆箱。 实例 // 原始字符 'a' 装箱到 Character 对象 ch 中
Character ch = 'a';
// 原始字符 'x' 用 test 方法装箱
// 返回拆箱的值到 'c'
转义序列 前面有反斜杠(\)的字符代表转义字符,它对编译器来说是有特殊含义的。 下面列表展示了Java的转义序列: 转义序列描述\t在文中该处插入一个tab键\b在文中该处插入一个后退键\n在文中该处换行\r在文中该处插入回车\f在文中该处插入换页符'在文中该处插入单引号"在文中该处插入双引号\在文中该处插入反斜杠 实例 当打印语句遇到一个转义序列时,编译器可以正确地对其进行解释。 以下实例转义双引号并输出: Test.java 文件代码: public class Test {
创建字符串 创建字符串最简单的方式如下: String str = "Runoob"; 在代码中遇到字符串常量时,这里的值是 "Runoob",编译器会使用该值创建一个 String 对象。 和其它对象一样,可以使用关键字和构造方法来创建 String 对象。 用构造函数创建字符串: String str2=new String("Runoob"); String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上: String s1 = "Runoob"; // String 直接创建
String s2 = "Runoob"; // String 直接创建
String s3 = s1; // 相同引用
String s4 = new String("Runoob"); // String 对象创建
String s5 = new String("Runoob"); // String 对象创建
String 类有 11 种构造方法,这些方法提供不同的参数来初始化字符串,比如提供一个字符数组参数:
StringDemo.java 文件代码:
public class StringDemo{
public static void main(String args[]){
char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'};
String helloString = new String(helloArray);
System.out.println( helloString );
}
}
以上实例编译运行结果如下:
runoob
字符串长度
用于获取有关对象的信息的方法称为访问器方法。 String 类的一个访问器方法是 length() 方法,它返回字符串对象包含的字符数。 下面的代码执行后,len 变量等于 14: StringDemo.java 文件代码: public class StringDemo { public static void main(String args[]) { String site = "www.runoob.com"; int len = site.length(); System.out.println( "菜鸟教程网址长度 : " + len ); } } 以上实例编译运行结果如下: 菜鸟教程网址长度 : 14
连接字符串
String 类提供了连接两个字符串的方法:
string1.concat(string2);
返回 string2 连接 string1 的新字符串。也可以对字符串常量使用 concat() 方法,如:
"我的名字是 ".concat("Runoob");
更常用的是使用'+'操作符来连接字符串,如:
"Hello," + " runoob" + "!"
结果如下:
"Hello, runoob!"
下面是一个例子:
StringDemo.java 文件代码:
public class StringDemo {
public static void main(String args[]) {
String string1 = "菜鸟教程网址:";
System.out.println("1、" + string1 + "www.runoob.com");
}
}
以上实例编译运行结果如下:
1、菜鸟教程网址:www.runoob.com
String 方法 下面是 String 类支持的方法,更多详细,参看 Java String API 文档: SN(序号)方法描述1char charAt(int index)返回指定索引处的 char 值。2int compareTo(Object o)把这个字符串和另一个对象比较。3int compareTo(String anotherString)按字典顺序比较两个字符串。4int compareToIgnoreCase(String str)按字典顺序比较两个字符串,不考虑大小写。5String concat(String str)将指定字符串连接到此字符串的结尾。6boolean contentEquals(StringBuffer sb)当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。7static String copyValueOf(char[] data)返回指定数组中表示该字符序列的 String。8static String copyValueOf(char[] data, int offset, int count)返回指定数组中表示该字符序列的 String。9boolean endsWith(String suffix)测试此字符串是否以指定的后缀结束。10boolean equals(Object anObject)将此字符串与指定的对象比较。11boolean equalsIgnoreCase(String anotherString)将此 String 与另一个 String 比较,不考虑大小写。12byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。13byte[] getBytes(String charsetName)使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。14void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)将字符从此字符串复制到目标字符数组。15int hashCode()返回此字符串的哈希码。16int indexOf(int ch)返回指定字符在此字符串中第一次出现处的索引。17int indexOf(int ch, int fromIndex)返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。18int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。19int indexOf(String str, int fromIndex)返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。20String intern() 返回字符串对象的规范化表示形式。21int lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。22int lastIndexOf(int ch, int fromIndex)返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。23int lastIndexOf(String str)返回指定子字符串在此字符串中最右边出现处的索引。24int lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。25int length()返回此字符串的长度。26boolean matches(String regex)告知此字符串是否匹配给定的正则表达式。27boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)测试两个字符串区域是否相等。28boolean regionMatches(int toffset, String other, int ooffset, int len)测试两个字符串区域是否相等。29String replace(char oldChar, char newChar)返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。30String replaceAll(String regex, String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。31String replaceFirst(String regex, String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。32String[] split(String regex)根据给定正则表达式的匹配拆分此字符串。33String[] split(String regex, int limit)根据匹配给定的正则表达式来拆分此字符串。34boolean startsWith(String prefix)测试此字符串是否以指定的前缀开始。35boolean startsWith(String prefix, int toffset)测试此字符串从指定索引开始的子字符串是否以指定前缀开始。36CharSequence subSequence(int beginIndex, int endIndex) 返回一个新的字符序列,它是此序列的一个子序列。37String substring(int beginIndex)返回一个新的字符串,它是此字符串的一个子字符串。38String substring(int beginIndex, int endIndex)返回一个新字符串,它是此字符串的一个子字符串。39char[] toCharArray()将此字符串转换为一个新的字符数组。40String toLowerCase()使用默认语言环境的规则将此 String 中的所有字符都转换为小写。41String toLowerCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。42String toString() 返回此对象本身(它已经是一个字符串!)。43String toUpperCase()使用默认语言环境的规则将此 String 中的所有字符都转换为大写。44String toUpperCase(Locale locale)使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。45String trim()返回字符串的副本,忽略前导空白和尾部空白。46static String valueOf(primitive data type x)返回给定data type类型x参数的字符串表示形式。47contains(CharSequence chars)判断是否包含指定的字符系列。48isEmpty() Java StringBuffer 和 StringBuilder 类
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
实例
public class RunoobTest{
public static void main(String args[]){
StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);
}
}
以上实例编译运行结果如下:
Runoob..
Runoob..!
Runoob..Java!
RunooJava!
然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
Test.java 文件代码:
public class Test{
public static void main(String args[]){
StringBuffer sBuffer = new StringBuffer("菜鸟教程官网:");
sBuffer.append("www");
sBuffer.append(".runoob");
sBuffer.append(".com");
System.out.println(sBuffer);
}
}
以上实例编译运行结果如下:
菜鸟教程官网:www.runoob.com
StringBuffer 方法
以下是 StringBuffer 类支持的主要方法:
序号方法描述1public StringBuffer append(String s)将指定的字符串追加到此字符序列。2public StringBuffer reverse() 将此字符序列用其反转形式取代。3public delete(int start, int end)移除此序列的子字符串中的字符。4public insert(int offset, int i)将int参数的字符串表示形式插入此序列中。5insert(int offset, String str)将str参数的字符串插入此序列中。6replace(int start, int end, String str)使用给定String中的字符替换此序列的子字符串中的字符。
以下列表列出了 StringBuffer 类的其他常用方法:
序号方法描述1int capacity()返回当前容量。2char charAt(int index)返回此序列中指定索引处的char值。3void ensureCapacity(int minimumCapacity)确保容量至少等于指定的最小值。4void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)将字符从此序列复制到目标字符数组dst。5int indexOf(String str)返回第一次出现的指定子字符串在该字符串中的索引。6int indexOf(String str, int fromIndex)从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。7int lastIndexOf(String str)返回最右边出现的指定子字符串在此字符串中的索引。8int lastIndexOf(String str, int fromIndex)返回 String 对象中子字符串最后出现的位置。9int length() 返回长度(字符数)。10void setCharAt(int index, char ch)将给定索引处的字符设置为ch。11void setLength(int newLength)设置字符序列的长度。12CharSequence subSequence(int start, int end)返回一个新的字符序列,该字符序列是此序列的子序列。13String substring(int start)返回一个新的String,它包含此字符序列当前所包含的字符子序列。14String substring(int start, int end)返回一个新的String,它包含此序列当前所包含的字符子序列。15String toString()返回此序列中数据的字符串表示形式。
三者的差别
tring、StringBuffer、StringBuilder的区别:
String StringBuffer StringBuilder
执行速度 最差 其次 最高
线程安全 线程安全 线程安全 线程不安全
使用场景 少量字符串操作 多线程环境下的大量操作 单线程环境下的大量操作
一、字符修改上的区别
String StringBuffer StringBulider
不可变字符串 可变字符串、效率低、线程安全 可变字符序列、效率高、线程不安全
1、String类型的字符串对象是不可变的,一旦String对象创建后,包含在这个对象中的字符系列是不可以改变的,直到这个对象被销毁。
2、StringBuilder和StringBuffer类型的字符串是可变的,不同的是StringBuffer类型的是线程安全的,而StringBuilder不是线程安全的
3、如果是多线程环境下涉及到共享变量的插入和删除操作,StringBuffer则是首选。如果是非多线程操作并且有大量的字符串拼接,插入,删除操作则StringBuilder是首选。
二、StringBuffer 和 StringBuilder区别
1、线程安全
StringBuffer和StringBuilder二者的功能和方法完全是等价的
StringBuffer线程安全,StringBuilder线程不安全
StringBuffer的公开方法都是被synchronized 修饰的,而 StringBuilder 并没有。
StringBuffer与StringBuilder都继承自AbstractStringBuilder。
StringBuffer从JDK1.0就有了,StringBuilder是JDK5.0才出现
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
2、缓冲区
StringBuffer 代码片段
private transient char[] toStringCache;
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
声明数组变量 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法: dataType[] arrayRefVar; // 首选的方法
或
dataType arrayRefVar[]; // 效果相同,但不是首选方法 注意: 建议使用 dataType[] arrayRefVar 的声明风格声明数组变量。 dataType arrayRefVar[] 风格是来自 C/C++ 语言 ,在Java中采用是为了让 C/C++ 程序员能够快速理解java语言。 实例 下面是这两种语法的代码示例: double[] myList; // 首选的方法
或
创建数组 Java语言使用new操作符来创建数组,语法如下: arrayRefVar = new dataType[arraySize]; 上面的语法语句做了两件事: 一、使用 dataType[arraySize] 创建了一个数组。 二、把新创建的数组的引用赋值给变量 arrayRefVar。 数组变量的声明,和创建数组可以用一条语句完成,如下所示: dataType[] arrayRefVar = new dataType[arraySize]; 另外,你还可以使用如下的方式创建数组。 dataType[] arrayRefVar = {value0, value1, ..., valuek}; 数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到 arrayRefVar.length-1。 实例 下面的语句首先声明了一个数组变量 myList,接着创建了一个包含 10 个 double 类型元素的数组,并且把它的引用赋值给 myList 变量。 TestArray.java 文件代码: public class TestArray { public static void main(String[] args) { // 数组大小
int size = 10;
// 定义数组
double[] myList = new double[size];
myList[0] = 5.6;
myList[1] = 4.5;
myList[2] = 3.3;
myList[3] = 13.2;
myList[4] = 4.0;
myList[5] = 34.33;
myList[6] = 34.0;
myList[7] = 45.45;
myList[8] = 99.993;
myList[9] = 11123;
// 计算所有元素的总和
double total = 0;
for (int i = 0; i < size; i++) {
total += myList[i];
}
System.out.println("总和为: " + total);
} } 以上实例输出结果为: 总和为: 11367.373 下面的图片描绘了数组 myList。这里 myList 数组里有 10 个 double 元素,它的下标从 0 到 9。
处理数组 数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环或者 For-Each 循环。 示例 该实例完整地展示了如何创建、初始化和操纵数组: TestArray.java 文件代码: public class TestArray { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5};
// 打印所有数组元素
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i] + " ");
}
// 计算所有元素的总和
double total = 0;
for (int i = 0; i < myList.length; i++) {
total += myList[i];
}
System.out.println("Total is " + total);
// 查找最大元素
double max = myList[0];
for (int i = 1; i < myList.length; i++) {
if (myList[i] > max) max = myList[i];
}
System.out.println("Max is " + max);
For-Each 循环 JDK 1.5 引进了一种新的循环类型,被称为 For-Each 循环或者加强型循环,它能在不使用下标的情况下遍历数组。 语法格式如下: for(type element: array) { System.out.println(element); } 实例 该实例用来显示数组 myList 中的所有元素: TestArray.java 文件代码: public class TestArray { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5};
// 打印所有数组元素
for (double element: myList) {
System.out.println(element);
}
数组作为函数的返回值 public static int[] reverse(int[] list) { int[] result = new int[list.length];
多维数组 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组,例如: String[][] str = new String[3][4]; 多维数组的动态初始化(以二维数组为例)
获取当前日期时间 Java中获取当前日期和时间很简单,使用 Date 对象的 toString() 方法来打印当前日期和时间,如下所示: 实例 import java.util.Date;
public class DateDemo { public static void main(String[] args) { // 初始化 Date 对象
Date date = new Date();
// 使用 toString() 函数显示日期时间
System.out.println(date.toString());
使用 SimpleDateFormat 格式化日期 SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。例如: 实例 import java.util.; import java.text.;
public class DateDemo { public static void main(String[] args) {
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
System.out.println("当前时间为: " + ft.format(dNow));
使用printf格式化日期 printf 方法可以很轻松地格式化时间和日期。使用两个字母格式,它以 %t 开头并且以下面表格中的一个字母结尾。 %tY:输出四位数的年份,例如:2023 %ty:输出两位数的年份,例如:23 %tm:输出两位数的月份,例如:02 %tB:输出月份的全名,例如:February %tb:输出月份的缩写,例如:Feb %tA:输出星期的全名,例如:Wednesday %ta:输出星期的缩写,例如:Wed %td:输出两位数的日期,例如:24 %te:输出一位或两位数的日期,例如:24 或 02 %tH:输出24小时制的小时数,例如:23 %tI:输出12小时制的小时数,例如:11 %tM:输出分钟数,例如:45 %tS:输出秒数,例如:30 %tp:输出上午还是下午,例如:AM 或 PM %tZ:输出时区,例如:GMT+08:00 转换符说明示例%tc包括全部日期和时间信息星期六 十月 27 14:21:20 CST 2007%tF"年-月-日"格式2007-10-27%tD"月/日/年"格式10/27/07%tr"HH:MM:SS PM"格式(12时制)02:25:51 下午%tT"HH:MM:SS"格式(24时制)14:28:16%tR"HH:MM"格式(24时制)14:28 更多 printf 解析可以参见:Java 格式化输出 printf 例子 实例 实例import java.util.Date; public class DateFormatExample { public static void main(String[] args) { Date date = new Date(); System.out.printf("%tY-%tm-%td %tH:%tM:%tS %tZ", date, date, date, date, date, date); } }
执行输出结果为: 2023-02-24 13:34:45 GMT+08:00 实例 import java.util.Date;
public class DateDemo {
public static void main(String[] args) { // 初始化 Date 对象
Date date = new Date();
//c的使用
System.out.printf("全部日期和时间信息:%tc%n",date);
//f的使用
System.out.printf("年-月-日格式:%tF%n",date);
//d的使用
System.out.printf("月/日/年格式:%tD%n",date);
//r的使用
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date);
//t的使用
System.out.printf("HH:MM:SS格式(24时制):%tT%n",date);
//R的使用
System.out.printf("HH:MM格式(24时制):%tR",date);
}
}
以上实例编译运行结果如下:
全部日期和时间信息:星期一 九月 10 10:43:36 CST 2012
年-月-日格式:2012-09-10
月/日/年格式:09/10/12
HH:MM:SS PM格式(12时制):10:43:36 上午
HH:MM:SS格式(24时制):10:43:36
HH:MM格式(24时制):10:43
如果你需要重复提供日期,那么利用这种方式来格式化它的每一部分就有点复杂了。因此,可以利用一个格式化字符串指出要被格式化的参数的索引。
索引必须紧跟在 % 后面,而且必须以 $ 结束。例如:
实例
import java.util.Date;
public class DateDemo {
public static void main(String[] args) { // 初始化 Date 对象
Date date = new Date();
// 使用toString()显示日期和时间
System.out.printf("%1$s %2$tB %2$td, %2$tY",
"Due date:", date);
} } 运行实例 » 以上实例编译运行结果如下: Due date: February 09, 2014 或者,你可以使用 < 标志。它表明先前被格式化的参数要被再次使用。例如: 实例 import java.util.Date;
public class DateDemo {
public static void main(String[] args) { // 初始化 Date 对象
Date date = new Date();
// 显示格式化时间
System.out.printf("%s %tB %<te, %<tY",
"Due date:", date);
} } 运行实例 » 以上实例编译运行结果如下: Due date: February 09, 2014 定义日期格式的转换符可以使日期通过指定的转换符生成新字符串。这些日期转换符如下所示: 实例 import java.util.*;
public class DateDemo {
public static void main(String[] args) {
Date date=new Date();
//b的使用,月份简称
String str=String.format(Locale.US,"英文月份简称:%tb",date);
System.out.println(str);
System.out.printf("本地月份简称:%tb%n",date);
//B的使用,月份全称
str=String.format(Locale.US,"英文月份全称:%tB",date);
System.out.println(str);
System.out.printf("本地月份全称:%tB%n",date);
//a的使用,星期简称
str=String.format(Locale.US,"英文星期的简称:%ta",date);
System.out.println(str);
//A的使用,星期全称
System.out.printf("本地星期的简称:%tA%n",date);
//C的使用,年前两位
System.out.printf("年的前两位数字(不足两位前面补0):%tC%n",date);
//y的使用,年后两位
System.out.printf("年的后两位数字(不足两位前面补0):%ty%n",date);
//j的使用,一年的天数
System.out.printf("一年中的天数(即年的第几天):%tj%n",date);
//m的使用,月份
System.out.printf("两位数字的月份(不足两位前面补0):%tm%n",date);
//d的使用,日(二位,不够补零)
System.out.printf("两位数字的日(不足两位前面补0):%td%n",date);
//e的使用,日(一位不补零)
System.out.printf("月份的日(前面不补0):%te",date);
解析字符串为时间 SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串。例如: 实例 import java.util.; import java.text.;
public class DateDemo {
public static void main(String[] args) { SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd");
String input = args.length == 0 ? "1818-11-11" : args[0];
System.out.print(input + " Parses as ");
Date t;
try {
t = ft.parse(input);
System.out.println(t);
} catch (ParseException e) {
System.out.println("Unparseable using " + ft);
}
Java 休眠(sleep) sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。 你可以让程序休眠一毫秒的时间或者到您的计算机的寿命长的任意段时间。例如,下面的程序会休眠3秒: 实例 import java.util.*;
public class SleepDemo { public static void main(String[] args) { try { System.out.println(new Date( ) + "\n"); Thread.sleep(1000*3); // 休眠3秒
System.out.println(new Date( ) + "\n");
} catch (Exception e) {
System.out.println("Got an exception!");
}
} } 运行实例 » 以上实例编译运行结果如下: Thu Sep 17 10:20:30 CST 2015
测量时间 下面的一个例子表明如何测量时间间隔(以毫秒为单位): 实例 import java.util.*;
public class DiffDemo {
public static void main(String[] args) { try { long start = System.currentTimeMillis( ); System.out.println(new Date( ) + "\n"); Thread.sleep(56010); System.out.println(new Date( ) + "\n"); long end = System.currentTimeMillis( ); long diff = end - start; System.out.println("Difference is : " + diff); } catch (Exception e) { System.out.println("Got an exception!"); } } } 运行实例 » 以上实例编译运行结果如下: Fri Jan 08 09:48:47 CST 2016
Fri Jan 08 09:48:50 CST 2016
Calendar类 我们现在已经能够格式化并创建一个日期对象了,但是我们如何才能设置和获取日期数据的特定部分呢,比如说小时,日,或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类。 Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。 Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。 创建一个代表系统当前日期的Calendar对象 Calendar c = Calendar.getInstance();//默认是当前日期 创建一个指定日期的Calendar对象 使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。 //创建一个代表2009年6月12日的Calendar对象 Calendar c1 = Calendar.getInstance(); c1.set(2009, 6 - 1, 12); Calendar类对象字段类型 Calendar类中用以下这些常量表示不同的意义,jdk内的很多类其实都是采用的这种思想 常量描述Calendar.YEAR年份Calendar.MONTH月份Calendar.DATE日期Calendar.DAY_OF_MONTH日期,和上面的字段意义完全相同Calendar.HOUR12小时制的小时Calendar.HOUR_OF_DAY24小时制的小时Calendar.MINUTE分钟Calendar.SECOND秒Calendar.DAY_OF_WEEK星期几 Calendar类对象信息的设置 Set设置 如: Calendar c1 = Calendar.getInstance(); 调用: public final void set(int year,int month,int date) c1.set(2009, 6, 12);//把Calendar对象c1的年月日分别设这为:2009、6、12 利用字段类型设置 如果只设定某个字段,例如日期的值,则可以使用如下set方法: public void set(int field,int value) 把 c1对象代表的日期设置为10号,其它所有的数值会被重新计算 c1.set(Calendar.DATE,10); 把c1对象代表的年份设置为2008年,其他的所有数值会被重新计算 c1.set(Calendar.YEAR,2008); 其他字段属性set的意义以此类推 Add设置 Calendar c1 = Calendar.getInstance(); 把c1对象的日期加上10,也就是c1也就表示为10天后的日期,其它所有的数值会被重新计算 c1.add(Calendar.DATE, 10); 把c1对象的日期减去10,也就是c1也就表示为10天前的日期,其它所有的数值会被重新计算 c1.add(Calendar.DATE, -10); 其他字段属性的add的意义以此类推 Calendar类对象信息的获得 Calendar c1 = Calendar.getInstance(); // 获得年份
int year = c1.get(Calendar.YEAR); // 获得月份
int month = c1.get(Calendar.MONTH) + 1; // 获得日期
int date = c1.get(Calendar.DATE); // 获得小时
int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得分钟
int minute = c1.get(Calendar.MINUTE); // 获得秒
int second = c1.get(Calendar.SECOND); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推)
GregorianCalendar类 Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。 Calendar 的getInstance()方法返回一个默认用当前的语言环境和时区初始化的GregorianCalendar对象。GregorianCalendar定义了两个字段:AD和BC。这是代表公历定义的两个时代。 下面列出GregorianCalendar对象的几个构造方法: 序号构造函数和说明1GregorianCalendar()在具有默认语言环境的默认时区内使用当前时间构造一个默认的 GregorianCalendar。2GregorianCalendar(int year, int month, int date)在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar3GregorianCalendar(int year, int month, int date, int hour, int minute)为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。4GregorianCalendar(int year, int month, int date, int hour, int minute, int second) 为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。5GregorianCalendar(Locale aLocale)在具有给定语言环境的默认时区内构造一个基于当前时间的 GregorianCalendar。6GregorianCalendar(TimeZone zone)在具有默认语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。7GregorianCalendar(TimeZone zone, Locale aLocale) 在具有给定语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。 这里是GregorianCalendar 类提供的一些有用的方法列表: 序号方法和说明1void add(int field, int amount)根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。2protected void computeFields()转换UTC毫秒值为时间域值3protected void computeTime()覆盖Calendar ,转换时间域值为UTC毫秒值4boolean equals(Object obj)比较此 GregorianCalendar 与指定的 Object。5int get(int field)获取指定字段的时间值6int getActualMaximum(int field)返回当前日期,给定字段的最大值7int getActualMinimum(int field)返回当前日期,给定字段的最小值8int getGreatestMinimum(int field) 返回此 GregorianCalendar 实例给定日历字段的最高的最小值。9Date getGregorianChange()获得格里高利历的更改日期。10int getLeastMaximum(int field)返回此 GregorianCalendar 实例给定日历字段的最低的最大值11int getMaximum(int field)返回此 GregorianCalendar 实例的给定日历字段的最大值。12Date getTime()获取日历当前时间。13long getTimeInMillis()获取用长整型表示的日历的当前时间14TimeZone getTimeZone()获取时区。15int getMinimum(int field)返回给定字段的最小值。16int hashCode()重写hashCode.17boolean isLeapYear(int year)确定给定的年份是否为闰年。18void roll(int field, boolean up)在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段。19void set(int field, int value)用给定的值设置时间字段。20void set(int year, int month, int date)设置年、月、日的值。21void set(int year, int month, int date, int hour, int minute)设置年、月、日、小时、分钟的值。22void set(int year, int month, int date, int hour, int minute, int second)设置年、月、日、小时、分钟、秒的值。23void setGregorianChange(Date date)设置 GregorianCalendar 的更改日期。24void setTime(Date date)用给定的日期设置Calendar的当前时间。25void setTimeInMillis(long millis)用给定的long型毫秒数设置Calendar的当前时间。26void setTimeZone(TimeZone value)用给定时区值设置当前时区。27String toString()返回代表日历的字符串。 实例 实例 import java.util.*;
public class GregorianCalendarDemo {
public static void main(String[] args) { String months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int year;
// 初始化 Gregorian 日历
// 使用当前时间和日期
// 默认为本地时间和时区
GregorianCalendar gcalendar = new GregorianCalendar();
// 显示当前时间和日期的信息
System.out.print("Date: ");
System.out.print(months[gcalendar.get(Calendar.MONTH)]);
System.out.print(" " + gcalendar.get(Calendar.DATE) + " ");
System.out.println(year = gcalendar.get(Calendar.YEAR));
System.out.print("Time: ");
System.out.print(gcalendar.get(Calendar.HOUR) + ":");
System.out.print(gcalendar.get(Calendar.MINUTE) + ":");
System.out.println(gcalendar.get(Calendar.SECOND));
// 测试当前年份是否为闰年
if(gcalendar.isLeapYear(year)) {
System.out.println("当前年份是闰年");
}
else {
System.out.println("当前年份不是闰年");
}
} } 运行实例 » 以上实例编译运行结果如下: Date: Apr 22 2009 Time: 11:25:27 当前年份不是闰年 关于 Calendar 类的完整列表,你可以参考标准的 Java文档。 Java 数组 Java 正则表达式 2 篇笔记 写笔记 妇芳单身骗
lhm***@126.com 344 Calendar 的月份是从 0 开始的,但日期和年份是从 1 开始的 示例代码: import java.util.Calendar;
public class Test { public static void main(String[] args) { Calendar c1 = Calendar.getInstance(); c1.set(2017, 1, 1); System.out.println(c1.get(Calendar.YEAR) +"-"+c1.get(Calendar.MONTH) +"-"+c1.get(Calendar.DATE)); c1.set(2017, 1, 0); System.out.println(c1.get(Calendar.YEAR) +"-"+c1.get(Calendar.MONTH) +"-"+c1.get(Calendar.DATE)); } } 运行结果: 2017-1-1 2017-0-31 可见,将日期设为0以后,月份变成了上个月,但月份可以为0 把月份改为2试试: import java.util.Calendar;
public class Test { public static void main(String[] args) { Calendar c1 = Calendar.getInstance(); c1.set(2017, 2, 1); System.out.println(c1.get(Calendar.YEAR) +"-"+c1.get(Calendar.MONTH) +"-"+c1.get(Calendar.DATE)); c1.set(2017, 2, 0); System.out.println(c1.get(Calendar.YEAR) +"-"+c1.get(Calendar.MONTH) +"-"+c1.get(Calendar.DATE)); } } 运行结果: 2017-2-1 2017-1-28 可以看到上个月的最后一天是28号,所以Calendar.MONTH为1的时候是2月 既然日期设为0表示上个月的最后一天,那是不是可以设为负数呢? import java.util.Calendar;
public class Test { public static void main(String[] args) { Calendar c1 = Calendar.getInstance(); c1.set(2017, 2, 1); System.out.println(c1.get(Calendar.YEAR) +"-"+c1.get(Calendar.MONTH) +"-"+c1.get(Calendar.DATE)); c1.set(2017, 2, -10); System.out.println(c1.get(Calendar.YEAR) +"-"+c1.get(Calendar.MONTH) +"-"+c1.get(Calendar.DATE)); } } 运行结果: 2017-2-1 2017-1-18 果然可以,所以日期才可以自由加减。 月份也可以是负数,规则与日期一样,就不上代码了。 实测将年份设为非正数时,会自动变为绝对值+1,不知其意义。妇芳单身骗 妇芳单身骗 lhm***@126.com6年前 (2017-11-22) 冲冲冲
173***2867@qq.com 95 import java.util.Date;
public class DateDemo {
public static void main(String[] args) { // 初始化 Date 对象 Date date = new Date();
//c的使用
System.out.printf("全部日期和时间信息:%tc%n",date);
//f的使用
System.out.printf("年-月-日格式:%tF%n",date);
//d的使用
System.out.printf("月/日/年格式:%tD%n",date);
//r的使用
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date);
//t的使用
System.out.printf("HH:MM:SS格式(24时制):%tT%n",date);
//R的使用
System.out.printf("HH:MM格式(24时制):%tR",date);
} } 输出结果为: 全部日期和时间信息:周六 8月 22 11:53:36 CST 2020 年-月-日格式:2020-08-22 月/日/年格式:08/22/20 HH:MM:SS PM格式(12时制):11:53:36 上午 HH:MM:SS格式(24时制):11:53:36 HH:MM格式(24时制):11:53 冲冲冲 冲冲冲 173**2867@qq.com3年前 (2020-08-22) Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。 正则表达式实例 一个字符串其实就是一个简单的正则表达式,例如 Hello World 正则表达式匹配 "Hello World" 字符串。 .(点号)也是一个正则表达式,它匹配任何一个字符如:"a" 或 "1"。 下表列出了一些正则表达式的实例及描述: 正则表达式描述this is text匹配字符串 "this is text"this\s+is\s+text注意字符串中的 \s+。匹配单词 "this" 后面的 \s+ 可以匹配多个空格,之后匹配 is 字符串,再之后 \s+ 匹配多个空格然后再跟上 text 字符串。可以匹配这个实例:this is text^\d+(.\d+)?^ 定义了以什么开始\d+ 匹配一个或多个数字? 设置括号内的选项是可选的. 匹配 "."可以匹配的实例:"5", "1.5" 和 "2.21"。 Java 正则表达式和 Perl 的是最为相似的。 java.util.regex 包主要包括以下三个类: Pattern 类: pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。 Matcher 类: Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。 PatternSyntaxException: PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。 以下实例中使用了正则表达式 .runoob. 用于查找字符串中是否包了 runoob 子串: 实例 import java.util.regex.;
class RegexExample1{ public static void main(String[] args){ String content = "I am noob " + "from runoob.com.";
String pattern = ".*runoob.*";
boolean isMatch = Pattern.matches(pattern, content);
System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch);
捕获组 捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。 例如,正则表达式 (dog) 创建了单一分组,组里包含"d","o",和"g"。 捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组: ((A)(B(C))) (A) (B(C)) (C) 可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。 还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。 实例 下面的例子说明如何从一个给定的字符串中找到数字串: RegexMatches.java 文件代码: import java.util.regex.Matcher; import java.util.regex.Pattern;
public class RegexMatches { public static void main( String[] args ){
// 按指定模式在字符串查找
String line = "This order was placed for QT3000! OK?";
String pattern = "(\\D*)(\\d+)(.*)";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
System.out.println("Found value: " + m.group(3) );
} else {
System.out.println("NO MATCH");
}
正则表达式语法
在其他语言中,\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。
在 Java 中,\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。
所以,在其他的语言中(如 Perl),一个反斜杠 \ 就足以具有转义的作用,而在 Java 中正则表达式中则需要有两个反斜杠才能被解析为其他语言中的转义作用。也可以简单的理解在 Java 的正则表达式中,两个 \ 代表其他语言中的一个 \,这也就是为什么表示一位数字的正则表达式是 \d,而表示一个普通的反斜杠是 \。
System.out.print("\"); // 输出为
System.out.print("\\"); // 输出为 \
Matcher 类的方法 索引方法 索引方法提供了有用的索引值,精确表明输入字符串中在哪能找到匹配: 序号方法及说明1public int start()返回以前匹配的初始索引。2public int start(int group) 返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引3public int end()返回最后匹配字符之后的偏移量。4public int end(int group)返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。 查找方法 查找方法用来检查输入字符串并返回一个布尔值,表示是否找到该模式: 序号方法及说明1public boolean lookingAt() 尝试将从区域开头开始的输入序列与该模式匹配。2public boolean find()尝试查找与该模式匹配的输入序列的下一个子序列。3public boolean find(int start)重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。4public boolean matches()尝试将整个区域与模式匹配。 替换方法 替换方法是替换输入字符串里文本的方法: 序号方法及说明1public Matcher appendReplacement(StringBuffer sb, String replacement)实现非终端添加和替换步骤。2public StringBuffer appendTail(StringBuffer sb)实现终端添加和替换步骤。3public String replaceAll(String replacement) 替换模式与给定替换字符串相匹配的输入序列的每个子序列。4public String replaceFirst(String replacement) 替换模式与给定替换字符串匹配的输入序列的第一个子序列。5public static String quoteReplacement(String s)返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement 方法一个字面字符串一样工作。 start 和 end 方法 下面是一个对单词 "cat" 出现在输入字符串中出现次数进行计数的例子: RegexMatches.java 文件代码: import java.util.regex.Matcher; import java.util.regex.Pattern;
public class RegexMatches { private static final String REGEX = "\bcat\b"; private static final String INPUT = "cat cat cat cattie cat";
public static void main( String[] args ){
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); // 获取 matcher 对象
int count = 0;
while(m.find()) {
count++;
System.out.println("Match number "+count);
System.out.println("start(): "+m.start());
System.out.println("end(): "+m.end());
}
} } 以上实例编译运行结果如下: Match number 1 start(): 0 end(): 3 Match number 2 start(): 4 end(): 7 Match number 3 start(): 8 end(): 11 Match number 4 start(): 19 end(): 22 可以看到这个例子是使用单词边界,以确保字母 "c" "a" "t" 并非仅是一个较长的词的子串。它也提供了一些关于输入字符串中匹配发生位置的有用信息。 Start 方法返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引,end 方法最后一个匹配字符的索引加 1。 matches 和 lookingAt 方法 matches 和 lookingAt 方法都用来尝试匹配一个输入序列模式。它们的不同是 matches 要求整个序列都匹配,而lookingAt 不要求。 lookingAt 方法虽然不需要整句都匹配,但是需要从第一个字符开始匹配。 这两个方法经常在输入字符串的开始使用。 我们通过下面这个例子,来解释这个功能: RegexMatches.java 文件代码: import java.util.regex.Matcher; import java.util.regex.Pattern;
public class RegexMatches { private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static final String INPUT2 = "ooooofoooooooooooo"; private static Pattern pattern; private static Matcher matcher; private static Matcher matcher2;
public static void main( String[] args ){
pattern = Pattern.compile(REGEX);
matcher = pattern.matcher(INPUT);
matcher2 = pattern.matcher(INPUT2);
System.out.println("Current REGEX is: "+REGEX);
System.out.println("Current INPUT is: "+INPUT);
System.out.println("Current INPUT2 is: "+INPUT2);
System.out.println("lookingAt(): "+matcher.lookingAt());
System.out.println("matches(): "+matcher.matches());
System.out.println("lookingAt(): "+matcher2.lookingAt());
} } 以上实例编译运行结果如下: Current REGEX is: foo Current INPUT is: fooooooooooooooooo Current INPUT2 is: ooooofoooooooooooo lookingAt(): true matches(): false lookingAt(): false replaceFirst 和 replaceAll 方法 replaceFirst 和 replaceAll 方法用来替换匹配正则表达式的文本。不同的是,replaceFirst 替换首次匹配,replaceAll 替换所有匹配。 下面的例子来解释这个功能: RegexMatches.java 文件代码: import java.util.regex.Matcher; import java.util.regex.Pattern;
public class RegexMatches { private static String REGEX = "dog"; private static String INPUT = "The dog says meow. " + "All dogs say meow."; private static String REPLACE = "cat";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
// get a matcher object
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
} } 以上实例编译运行结果如下: The cat says meow. All cats say meow. appendReplacement 和 appendTail 方法 Matcher 类也提供了appendReplacement 和 appendTail 方法用于文本替换: 看下面的例子来解释这个功能: RegexMatches.java 文件代码: import java.util.regex.Matcher; import java.util.regex.Pattern;
public class RegexMatches { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoobkkk"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // 获取 matcher 对象
Matcher m = p.matcher(INPUT);
StringBuffer sb = new StringBuffer();
while(m.find()){
m.appendReplacement(sb,REPLACE);
}
m.appendTail(sb);
System.out.println(sb.toString());
从控制台读取多字符输入 从 BufferedReader 对象读取一个字符要使用 read() 方法,它的语法如下: int read( ) throws IOException 每次调用 read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。 下面的程序示范了用 read() 方法从控制台不断读取字符直到用户输入 q。 BRRead.java 文件代码: //使用 BufferedReader 在控制台读取字符
import java.io.*;
public class BRRead { public static void main(String[] args) throws IOException { char c; // 使用 System.in 创建 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入字符, 按下 'q' 键退出。");
// 读取字符
do {
c = (char) br.read();
System.out.println(c);
} while (c != 'q');
}
} 以上实例编译运行结果如下: 输入字符, 按下 'q' 键退出。 runoob r u n o o b
从控制台读取字符串 从标准输入读取一个字符串需要使用 BufferedReader 的 readLine() 方法。 它的一般格式是: String readLine( ) throws IOException 下面的程序读取和显示字符行直到你输入了单词"end"。 BRReadLines.java 文件代码: //使用 BufferedReader 在控制台读取字符
import java.io.*;
public class BRReadLines { public static void main(String[] args) throws IOException { // 使用 System.in 创建 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
System.out.println("Enter lines of text.");
System.out.println("Enter 'end' to quit.");
do {
str = br.readLine();
System.out.println(str);
} while (!str.equals("end"));
}
} 以上实例编译运行结果如下: Enter lines of text. Enter 'end' to quit. This is line one This is line one This is line two This is line two end end JDK 5 后的版本我们也可以使用 Java Scanner 类来获取控制台的输入。 控制台输出 在此前已经介绍过,控制台的输出由 print( ) 和 println() 完成。这些方法都由类 PrintStream 定义,System.out 是该类对象的一个引用。 PrintStream 继承了 OutputStream类,并且实现了方法 write()。这样,write() 也可以用来往控制台写操作。 PrintStream 定义 write() 的最简单格式如下所示: void write(int byteval) 该方法将 byteval 的低八位字节写到流中。 实例 下面的例子用 write() 把字符 "A" 和紧跟着的换行符输出到屏幕: WriteDemo.java 文件代码: import java.io.*;
//演示 System.out.write().
读写文件 如前所述,一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。 下图是一个描述输入流和输出流的类层次图。
FileOutputStream 该类用来创建一个文件并向文件中写数据。 如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。 有两个构造方法可以用来创建 FileOutputStream 对象。 使用字符串类型的文件名来创建一个输出流对象: OutputStream f = new FileOutputStream("C:/java/hello") 也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象: File f = new File("C:/java/hello"); OutputStream fOut = new FileOutputStream(f); 创建OutputStream 对象完成后,就可以使用下面的方法来写入流或者进行其他的流操作。 序号方法及描述1public void close() throws IOException{}关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。2protected void finalize()throws IOException {}这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。3public void write(int w)throws IOException{}这个方法把指定的字节写到输出流中。4public void write(byte[] w)把指定数组中w.length长度的字节写到OutputStream中。 除了OutputStream外,还有一些其他的输出流,更多的细节参考下面链接: ByteArrayOutputStream DataOutputStream 实例 下面是一个演示 InputStream 和 OutputStream 用法的例子: fileStreamTest.java 文件代码: import java.io.*;
public class fileStreamTest { public static void main(String[] args) { try { byte bWrite[] = { 11, 21, 3, 40, 5 }; OutputStream os = new FileOutputStream("test.txt"); for (int x = 0; x < bWrite.length; x++) { os.write(bWrite[x]); // writes the bytes
}
os.close();
InputStream is = new FileInputStream("test.txt");
int size = is.available();
for (int i = 0; i < size; i++) {
System.out.print((char) is.read() + " ");
}
is.close();
} catch (IOException e) {
System.out.print("Exception");
}
}
} 上面的程序首先创建文件test.txt,并把给定的数字以二进制形式写进该文件,同时输出到控制台上。 以上代码由于是二进制写入,可能存在乱码,你可以使用以下代码实例来解决乱码问题: fileStreamTest2.java 文件代码: //文件名 :fileStreamTest2.java
import java.io.*;
public class fileStreamTest2 { public static void main(String[] args) throws IOException {
File f = new File("a.txt");
FileOutputStream fop = new FileOutputStream(f);
// 构建FileOutputStream对象,文件不存在会自动新建
OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
// 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
writer.append("中文输入");
// 写入到缓冲区
writer.append("\r\n");
// 换行
writer.append("English");
// 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
writer.close();
// 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
fop.close();
// 关闭输出流,释放系统资源
FileInputStream fip = new FileInputStream(f);
// 构建FileInputStream对象
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
// 构建InputStreamReader对象,编码与写入相同
StringBuffer sb = new StringBuffer();
while (reader.ready()) {
sb.append((char) reader.read());
// 转成char加到StringBuffer对象中
}
System.out.println(sb.toString());
reader.close();
// 关闭读取流
fip.close();
// 关闭输入流,释放系统资源
}
Java中的目录 创建目录: File类中有两个方法可以用来创建文件夹: mkdir( )方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。 mkdirs()方法创建一个文件夹和它的所有父文件夹。 下面的例子创建 "/tmp/user/java/bin"文件夹: CreateDir.java 文件代码: import java.io.File;
public class CreateDir { public static void main(String[] args) { String dirname = "/tmp/user/java/bin"; File d = new File(dirname); // 现在创建目录
d.mkdirs();
}
读取目录 一个目录其实就是一个 File 对象,它包含其他文件和文件夹。 如果创建一个 File 对象并且它是一个目录,那么调用 isDirectory() 方法会返回 true。 可以通过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表。 下面展示的例子说明如何使用 list() 方法来检查一个文件夹中包含的内容: DirList.java 文件代码: import java.io.File;
删除目录或文件 删除文件可以使用 java.io.File.delete() 方法。 以下代码会删除目录 /tmp/java/,需要注意的是当删除某一目录时,必须保证该目录下没有其他文件才能正确删除,否则将删除失败。 测试目录结构: /tmp/java/ |-- 1.log |-- test DeleteFileDemo.java 文件代码: import java.io.File;
public class DeleteFileDemo { public static void main(String[] args) { // 这里修改为自己的测试目录
File folder = new File("/tmp/java/");
deleteFolder(folder);
}
// 删除文件及目录
public static void deleteFolder(File folder) {
File[] files = folder.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
deleteFolder(f);
} else {
f.delete();
}
}
}
folder.delete();
}
} Java Scanner 类 java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。 下面是创建 Scanner 对象的基本语法: Scanner s = new Scanner(System.in); 接下来我们演示一个最简单的数据输入,并通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要 使用 hasNext 与 hasNextLine 判断是否还有输入的数据:
使用 next 方法: ScannerDemo.java 文件代码: import java.util.Scanner;
public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据
// next方式接收字符串
System.out.println("next方式接收:");
// 判断是否还有输入
if (scan.hasNext()) {
String str1 = scan.next();
System.out.println("输入的数据为:" + str1);
}
scan.close();
}
} 执行以上程序输出结果为: $ javac ScannerDemo.java $ java ScannerDemo next方式接收: runoob com 输入的数据为:runoob 可以看到 com 字符串并未输出,接下来我们看 nextLine。 使用 nextLine 方法: ScannerDemo.java 文件代码: import java.util.Scanner;
public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据
// nextLine方式接收字符串
System.out.println("nextLine方式接收:");
// 判断是否还有输入
if (scan.hasNextLine()) {
String str2 = scan.nextLine();
System.out.println("输入的数据为:" + str2);
}
scan.close();
}
} 执行以上程序输出结果为: $ javac ScannerDemo.java $ java ScannerDemo nextLine方式接收: runoob com 输入的数据为:runoob com 可以看到 com 字符串输出。 next() 与 nextLine() 区别 next(): 1、一定要读取到有效字符后才可以结束输入。 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。 next() 不能得到带有空格的字符串。 nextLine(): 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。 2、可以获得空白。 如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取: ScannerDemo.java 文件代码: import java.util.Scanner;
public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据
int i = 0;
float f = 0.0f;
System.out.print("输入整数:");
if (scan.hasNextInt()) {
// 判断输入的是否是整数
i = scan.nextInt();
// 接收整数
System.out.println("整数数据:" + i);
} else {
// 输入错误的信息
System.out.println("输入的不是整数!");
}
System.out.print("输入小数:");
if (scan.hasNextFloat()) {
// 判断输入的是否是小数
f = scan.nextFloat();
// 接收小数
System.out.println("小数数据:" + f);
} else {
// 输入错误的信息
System.out.println("输入的不是小数!");
}
scan.close();
}
} 执行以上程序输出结果为: $ javac ScannerDemo.java $ java ScannerDemo 输入整数:12 整数数据:12 输入小数:1.2 小数数据:1.2 以下实例我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果: ScannerDemo.java 文件代码: import java.util.Scanner;
class RunoobTest { public static void main(String[] args) { System.out.println("请输入数字:"); Scanner scan = new Scanner(System.in);
double sum = 0;
int m = 0;
while (scan.hasNextDouble()) {
double x = scan.nextDouble();
m = m + 1;
sum = sum + x;
}
System.out.println(m + "个数的和为" + sum);
System.out.println(m + "个数的平均值是" + (sum / m));
scan.close();
}
} 执行以上程序输出结果为(输入非数字来结束输入): $ javac ScannerDemo.java $ java ScannerDemo 请输入数字: 12 23 15 21.4 end 4个数的和为71.4 4个数的平均值是17.85
评论