SCJP笔记_章六_字符串、I/O、格式化与解析

第六章 字符串、I/O、格式化与解析 

 

 

6.1 String、StringBuilder和StringBuffer

考试目标3.1 探讨String、StringBuiler、StringBuffer类之间的区别。

 

 

6.1.1 String类

 

字符串是不可变的对象,但是可以改变引用。

所以对String的修改其实是在堆中新建了一个对象,然后改变原来对象的引用。

如果将String引用重定向到新的String,则旧的String可能丢失。

 

 

6.1.2 关于String和内存的重要事实

 

JVM留出一块特殊的内存区域,称为“String常量池”。

当JVM发现新的String字面值时,就将它添加到String常量池中,供String对象引用。

String类是最终类——其方法不能被重写。

 

 

6.1.3 String类的重要方法

 

public char charAt(int index)

该方法返回位于字符串指定索引处的字符。字符串索引值从0开始计算。

 

public String concat(String s)

该方法返回一个String,其值为将传递给该方法的String追加到用于调用该方法的String的尾部。(也可以用“+”)。

 

public boolean equalsIgnoreCase(String s)

判断两个字符串的相等性,忽略大小写。

 

public int length()

返回字符串中字符的个数。

 

public String replace(char old,char new)

用新字符代替指定的字符。

 

public String substring(int begin),public String substring(int begin,int end)

返回字符串的一部分。

 

public String toLowerCase()

将字符串中的大写字符转换成小写字符返回。

 

public String toString()

返回字符串的值。

 

public String toUpperCase()

将字符串中的小写字符转换成大写字符返回。

 

public String trim()

删除字符串前后部的空格。

 

 

6.1.4 StringBuffer类和StringBuilder类

 

StringBuffer的API与Java5中新增的StringBuilder的API相同,但是StringBuilder的方法并未针对线程安全进行同步。

StringBuilder的方法应该运行比StringBufferBuffer的方法更快。

 

 

6.1.5 StringBuffer类和StringBuilder类的重要方法

 

public synchronized StringBuffer append(String s)

public StringBuilder delete(int start,int end)

public StringBuilder insert(int offset,String s)

public synchronized StringBuffer reverse()      颠倒字符串中字符的顺序。

public String toString()

 

 

6.2 文件导航和I/O

考试目标3.2 给定一种涉及导航文件系统、读取文件或写入文件的场景,利用如下来自于java.io的类(有时会组合它们)设计正确的解决方案:BufferedReader、BufferedWriter、File、FileReader、FileWriter、PrintWriter和Console。 

 

File 文件和目录路径名的抽象表示

createNewFile()

delete()                 删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则此目录必须为空才能删除。

exists()

isDirectory()

isFile()

list()                      返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组

mkdir()

renameTo()

Java代码
  1. class testFile {    
  2.     public static void main(String[] args) {    
  3.         //在内存中建立file对象,文件名为file.txt,   
  4.         //路径的格式为d:\\file.txt或者d:/file.txt,路径必须为实际存在的路径    
  5.         File file = new File("d:/file.txt");     
  6.         Boolean flag = false;   
  7.         try {    
  8.             //在默认路径建立file对象的文件,建立成功flag为true   
  9.             //如果已有同名文件什么都不做,flag返回false   
  10.             flag = file.createNewFile();     
  11.         } catch (IOException e) {   
  12.             e.printStackTrace();      
  13.         }   
  14.         System.out.println(flag);          
  15.     }   
  16. }   

 

 

Java代码
  1. class testFile {   
  2.     public static void main(String[] args) {   
  3.         File file = new File("d:/");   
  4.         String[] lists = file.list();   
  5.         for (String list : lists) {   
  6.             System.out.println(list.toString());   
  7.         }   
  8.     }   
  9. }   
Java代码
  1. class testFile {    
  2.     public static void main(String[] args) throws IOException {    
  3.         File file = new File("d:/test1"); // 新建一个目录   
  4.         file.mkdir();   
  5.     }   
  6. }   

FileWriter

下面三个方法其实都是FIleWriter继承其父类java.io.OutputStreamWriter的

close() 关闭IO流

flush()  刷新该流的缓冲。通过该方法,可以保证你认为你所写数据的最后部分确实会从文件中取出。

write()

 

FileReader

read()

 

Java代码
  1. public class TestFileWriter {   
  2.     public static void main(String[] args) throws IOException {   
  3.         String str = "It's better to burn out,\nthan fade away.";   
  4.         int size = str.length();   
  5.         File file = new File("file.txt");   
  6.         if (file.exists()) {   
  7.             FileWriter fw = new FileWriter(file);   
  8.             fw.write(str);   
  9.             fw.flush();   
  10.             fw.close();   
  11.             FileReader fr = new FileReader(file);   
  12.             char[] in = new char[size];   
  13.             fr.read(in);   
  14.             for (char c : in) {   
  15.                 System.out.print(c);   
  16.             }   
  17.         }   
  18.     }   
  19. }   

 

如上代码,当把数据写入文件时,我们要手工地将行分隔符(\n)插入到数据中。当读数据时,我们将它放入一个字符数组中,必须事先声明其大小,然后再用read()方法来读这个数组。

由于这些限制,我们通常将高级I/O类与FileWriter或FileReader组合使用,如 BufferedWriter 和 BufferedReader 。  

 

PrintWriter 构造器的变元可以是文件名(String类型),可以是File对象,可以是OutputStream对象,可以是Writer对象。 

close()

flush()

format()

printf()

print()

println()

write()

 

 

Java代码

  1. public class TestPrintWriter {   
  2.     public static void main(String[] args) throws IOException{   

 

 

  1.            
  2.         //m1:   
  3.         //File file = new File("file.txt");   
  4.         //FileWriter fw = new FileWriter(file);   
  5.         //PrintWriter pw = new PrintWriter(fw);   
  6.                
  7.         //m2:   
  8.         //File file = new File("file.txt");   
  9.         //PrintWriter pw = new PrintWriter(file);   
  10.            
  11.         //m3:   
  12.         PrintWriter pw = new PrintWriter("file.txt");   
  13.            
  14.         pw.println("It's better to burn out,");   
  15.         pw.write("than fade away.");   
  16.         pw.flush();   
  17.         pw.close();   
  18.        
  19.     }   
  20. }  

BufferedWriter 构造器的变元只能是Writer对象。

close()

flush()

newLine()

write()

 

BufferedReader

read()

readLine()

Java代码
  1. public class TestBufferedWriter {   
  2.     public static void main(String[] args) throws IOException{   
  3.         File file = new File("file.txt");   
  4.         FileWriter fw = new FileWriter(file);   
  5.         BufferedWriter bw = new BufferedWriter(fw);   
  6.         bw.write("It's better to burn out,");   
  7.         bw.newLine();   
  8.         bw.write("than fade away.");   
  9.         bw.flush();   
  10.         bw.close();   
  11.            
  12.         FileReader fr = new FileReader(file);   
  13.         BufferedReader br = new BufferedReader(fr);   
  14.         System.out.println(br.readLine());   
  15.         System.out.println(br.readLine());   
  16.         br.close();   
  17.     }   
  18. }  

  

Console 操作控制台的IO

Console对象的获得

Console c = System.console();

 

6.3 序列化

考试目标3.3 编写代码,利用来自于java.io的下列API序列化和/或反序列化对象:DataInputStream、

DataOutputStream、FileInputStream、FileOutputStream、ObjectInputStream、ObjectOutputStream以及Serializable。

 

对象的序列化是指把对象写到一个输出流中,对象的反序列化是指从一个输入流中读取一个对象。

只有实现了java.io.Serializable接口的类的对象才能被序列化或反序列化。

序列化不适用于静态变量

 

 

6.4 日期、数字和货币

考试目标3.4 使用java.text包中的标准J2SE API,为特定的地区正确地格式化或解析日期、数字和货币值。给定一个场景,如果希望使用默认的地区或特定的地区,确定要采用的合适方法。描述java.util.Locale类的目的和用法。

 

6.4.1 处理日期、数字和货币

 

协同使用与日期和数字相关的类

 

Date类

java.util.Date类实质上就是个long型毫秒数,从1970年1月1日00:00:00到现在的毫秒数,通常Date对象被用作Calendar类和DateFormat类之间的桥梁。

public class TestDate {
	public static void main(String[] args){
		Date date = new Date();		//获得当前时间的Date对象
		System.out.println(date.toString());
		//结果类似:Wed Jul 29 12:02:02 CST 2009
		
		
		Date date2 = new Date(1000000);      //获得指定毫秒数的Date对象
		System.out.println(date2.getTime());
	}
}

  

 

Calendar类

java.util.Calendar类提供了大量方法,用以帮助转换和操作日期或时间。

Calendar ca = Calendar.getInstance();
Calendar ca2 = Calendar.getInstance(Locale.CANADA_FRENCH);
Calendar ca3 = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));

  

DateFormat类

java.text.DateFormat类用于格式化日期。

public class TestDateFormat {

	public static void main(String[] args) {
		Date d1 = new Date();
		DateFormat[] dfa = new DateFormat[6];
		dfa[0] = DateFormat.getInstance();
		dfa[1] = DateFormat.getDateInstance();
		dfa[2] = DateFormat.getDateInstance(DateFormat.SHORT);
		dfa[3] = DateFormat.getDateInstance(DateFormat.MEDIUM);
		dfa[4] = DateFormat.getDateInstance(DateFormat.LONG);
		dfa[5] = DateFormat.getDateInstance(DateFormat.FULL);
		
		for(DateFormat df:dfa){
			System.out.println(df.format(d1));
		}		
	}
}

//运行结果:
//09-7-29 下午2:33
//2009-7-29
//09-7-29
//2009-7-29
//2009年7月29日
//2009年7月29日 星期三

 

NumberFormat类

java.text.NumberFormat类用于格式化全世界各个地区的数字和货币。

public class TestNumberFormat {
	public static void main(String[] args){
		float f1 = 123.4567f;
		Locale locFR = new Locale("fr");
		NumberFormat[] nfa = new NumberFormat[4];
		nfa[0] = NumberFormat.getInstance();
		nfa[1] = NumberFormat.getInstance(locFR);
		nfa[2] = NumberFormat.getCurrencyInstance();
		nfa[3] = NumberFormat.getCurrencyInstance(locFR);
		
		for(NumberFormat nf : nfa){
			System.out.println(nf.format(f1));
		}
	}
}
//运行结果:
//123.457
//123,457
//¥123.46
//123,46 ¤

 

Locale类

java.util.Locale类与DateFormat和NumberFormat结合,用于格式化特定地区的日期,数字和货币。

 Locale(String lang)

 Locale(String lang, String country)

 

6.5 解析、分解和格式化

考试目标3.5 编写代码,利用位于java.util包和java.util.regex包中的标准J2SE API,格式化或解析字符串或流。对于字符串,编写利用Pattern类、Matcher类以及String.split方法的代码。识别并使用正则表达式模式用于匹配,模式限于. * + ? \d \s \w []以及()。* + 和?的使用仅限于贪婪量词,圆括号运算符只用作一种分组机制,不用于在匹配期间捕获内容。对于流,编写利用Formatter类、Scanner类以及PrintWriter.format()/printf()方法的代码。识别并使用格式字符串中的格式化参数,限于%b、%c、%d、%f 以及 %s 。

 

6.5.1 查找指南

 

简单查找

public static void main(String[] args) {
	Pattern p = Pattern.compile("ab");
	Matcher m = p.matcher("abaaaba");
	while(m.find()){
		System.out.print(m.start() + " ");
	}
}

 

使用元字符查找

\d  数字

\s  空格符

\w 字字符(字母、数字或下划线)

[abc] 只查找字符abc

[a-f]  只查找字符abcdef

[a-fA-F]查找abcdef和ABCDEF

 

使用量词查找(后缀)

*  0次或多次匹配

?  0次或1次匹配

+ 1次或多次匹配

^ 除了。。。

 

预定义的点

.  表示这里可以是任意字符

 

贪婪量词

贪婪(greedy)和勉强(reluctant)的工作方式不同

贪婪是先整个吃掉,比对,不匹配,然后从右边一个一个往出吐,再比对

勉强是从左边一个一个吃,吃一个比对一次,不匹配,再吃一个再比对

见:http://blog.csdn.net/zidasine/archive/2008/11/05/3229848.aspx

 

字符与字符串发生冲突时

Stirng pattern = " \ \d ";

考试中还会出现\n 换行符

 

 

6.5.2 通过模式匹配定位数据

 

使用Scanner类执行查找

Scanner类:一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器

 

6.5.3 分解  

 

标记和定界符

标记(token)是实际的数据部分,定界符(delimiter)是将标记相互隔离开的表达式。

 

利用String.split()进行分解

public class SplitTest {

	public static void main(String[] args) {
		String source = "as f23 fa 313";
		String regex = "\\s";
		String[] tokens = source.split(regex);
		for(String token : tokens){
			System.out.println(">"+token+"<");
		}
	}
}
//result:
//>as<
//>f23<
//>fa<
//>313<

 

利用Scanner进行分解

Scanner类是执行分解操作的首选类

除了String.split()提供的基本分解能力外,Scanner类还提供:

  • 可以将文件、流或字符串用作源来构造Scanner。默认由空格来做定界符,可以用useDelimiter(Pattern pattern) 方法来指定定界符。
  • 分解操作在循环内执行,使得可以随时退出这一过程。
  • 可以将标记自动转换为相应的基本类型。
boolean b2,b;
int i;
String s,hits = " ";
String source = "1 true 34 hi";

Scanner s1 = new Scanner(source);
Scanner s2 = new Scanner(source);
while(b = s1.hasNext()){
	s = s1.next();  
	hits+="s";
}
while(b = s2.hasNext()){
	if(s2.hasNextInt()){
		i = s2.nextInt();
		hits+="i";
	}else if(s2.hasNextBoolean()){
		b2 = s2.nextBoolean();
		hits+="b";
	}else{
		s2.next();
		hits+="s2";
	}
}
System.out.println("hits "+hits);

 

 

6.5.4 利用printf()和format()进行格式化

可以参考java.util.Formatter API

System.out.printf("format string",argument(s));

 

"format string"格式字符串通常为形如“%2$d + %1$d”,它的构造为:

%[arg_index$][flags][width][.precision]conversion char

方括号的值是可选的,只有%和转换字符是必须的。

 

arg_index

一个整数,后面跟一个$,表示这个位置输出第几个变元。

 

flags标志(可以同时用多个)

-   左对齐变元(默认右对齐)

+  让变元包含符号(+或-)

0  用0填充变元

,   用特定于地区的分组分隔符(比如“123,456”中的逗号)

(   将负数包含在括号内

 

width

这个值指定要输出的最少字符数。

 

precision

精度。指定了要在小数点后输出的位数。前面有一个"."不要忘记。

 

conversion

将进行格式化的变元的类型

b  布尔型

c  字符型

d  整数型

f  浮点型

s  字符串

 

public class TestPrintf {
	public static void main(String[] args) {
		int i1 = -123;
		int i2 = 12345;
		float f = -322.23f;
		System.out.printf(">%d< \n",i1);//最简
		System.out.printf(">%1$+15.2f< \n",f);//完整
		System.out.printf(">%1$(7d< \n", i1);
		System.out.printf(">%0,7d< \n", i2);
		System.out.format(">%+-7d< \n", i2);
		System.out.printf(">%2$b + %1$5d< \n", i1,false);
	}
}
//result:
//>-123< 
//>        -322.23< 
//>  (123)< 
//>012,345< 
//>+12345 < 
//>false +  -123<

 

转载于:https://my.oschina.net/u/184747/blog/297791

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值