java基础(四)

You got a dream, you gotta protect it. People can’t do something themselves,they wanna tell you you can’t do it.If you want something, go get it.

Day14正则表达式
一、集合的由来
Java的正则表达式讲解:(为了能看清,本文正则表达式用中文的句号代替英文句点)
1 英文句点符号:匹配单个任意字符。
eg:
表达式”t。o 可以匹配:tno,t#o,teo等等。不可以匹配:tnno,to,Tno,t正o等。
2 方括号:只有方括号里面指定的字符才参与匹配,也只能匹配单个字符。
eg:
表达式:t[abcd]n 只可以匹配:tan,tbn,tcn,tdn。不可以匹配:thn,tabn,tn等。
3 | 符号。相当与“或”,可以匹配指定的字符,但是也只能选择其中一项进行匹配。
eg:
表达式:t(a|b|c|dd)n 只可以匹配:tan,tbn,tcn,tddn。不可以匹配taan,tn,tabcn
4 表示匹配次数的符号

     {n, }表示至少N次。

eg:
表达式:[0—9]{ 3 } \— [0-9]{ 2 } \— [0-9]{ 3 } 的匹配格式为:999—99—999
因为“—”符号在正则表达式中有特殊的含义,它表示一个范围,所以在前面加转义字符“\”。
5 ^符号:表示否
^符号被称为“否”符号,如果用在方括号内,“^“表示不想匹配的字符。
eg:
表达式:[^x] 第一个字符不能是x
6:圆括号,和空白符号
“\s”是空白符号,只可以匹配一个空格、制表符、回车符、换页符,不可以匹配自己输入的多个空格。
()是分组号,可以用ORO API提取处出值,后面将详细讨论。
7:正则表达式的一些快捷符号:
\d表示[0—9],
\D表示[^0—9],
\w表示[0—9A—Z_a—z],
\W表示[^0—9A—Z_a—z],
\s表示[\t\n\r\f],
\S表示[^\t\n\r\f]
8 一些常用的正则表达式:
Java:(([a-z]|_)(\w*)){6,20}匹配以字母或下划线开头,字母数字下划线结尾的字符串
JavaScript:/^(-?)(\d+) //\w+ / 匹 配 数 字 。 / \w + /匹配字母数字下划线。
.+ 一个或多个字符
/0 第一次匹配的字符串
9 java类中使用正则表达式:
eg1:
Pattern p = Pattern.compile(“t.n”);
Matcher m = p.matcher(“ton”);
if(m.matches()){
return true;
}
eg2:boolean bool=Pattern.matches (“t.n”,”ton”);
如果一个正则表达式要重复利用,用第一种,如果只匹配一次,第二种是最佳选择。
10 反斜线字符(‘\’)用于转义字符,同时还可以引用非转义字符(不包括非转义字母)
因此‘\’表示‘\’,‘{’表示{。 但是‘\y’就是错的,因为在不表示转义构造的 任何字母字符前 使用反斜线都是错误的。
根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 “\b” 与单个退格字符匹配,而 “\b” 与单词边界匹配。字符串字面值 “(hello)” 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 “\(hello\)”。 注意:‘\b’是一个字符而‘\b’是两个字符
11 Pattern类
(1) 8种模式:比如启用多行模式,启用unix模式等,eg int CASE_INSENSITIVE表示启用不区分大小写的模式。
(2) 4个静态方法
两个单例模式构造器:
Pattern compile(String regex);
Pattern compile(String regex,int flags)flags为八种模式的一种

eg2:
Pattern p=Pattern.compile(“[a-z]\s[a-z]”);
Matcher m=p.matcher(“b c”);
if(m.matches()) Sysout(1111);
else Sysout(2222); 输出结果为1111;
一个匹配方法,一个返回String的字面值模式方法:
boolean matches(String regex,CharSequence input);//input与regex匹配返回true。
String quote(String s);//返回指定String的字面值。
eg3:boolean bool=Pattern.matches(“[a-z] [a-z]”,”b c”); //结果为true
Sysout(Pattern.quote(“a_#/tb”)); //输出结果为 “\Qa_# b”\E
(3) 6个普通方法
返回此模式的匹配器: Matcher matcher(CharSequence input);
返回此模式的标志: int flags();
返回此模式的regex: String pattern();
两个字符串切割方法: String[] split(CharSequence input);
String[] split(CharSequence input,int limit);
limit为返回字符串的个数,如果等于0,返回所有 拆分的字符串,如果大于拆分字符串的实际个数,
返回实际个数。

二、常用正则表达式
(4) “^\d+$”  //非负整数(正整数 + 0)
(5) “^[0-9][1-9][0-9]   //6((\d+)|(0+)) ”     / / 正 整 数 ( 6 ) “ ( ( − \d + ) | ( 0 + ) ) ”  //非正整数(负整数 + 0)
(7) “^-[0-9][1-9][0-9]   //8?\d+ ”     / / 负 整 数 ( 8 ) “ − ? \d + ”    //整数
(9) “^\d+(.\d+)?$”  //非负浮点数(正浮点数 + 0)
(10) “^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))   //11((\d+(.\d+)?)|(0+(.0+)?)) ”     / / 正 浮 点 数 ( 11 ) “ ( ( − \d + ( . \d + ) ? ) | ( 0 + ( .0 + ) ? ) ) ”  //非正浮点数(负浮点数 + 0)
(12) “^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))   //13(?\d+)(.\d+)? ”     / / 负 浮 点 数 ( 13 ) “ ( − ? \d + ) ( . \d + ) ? ”  //浮点数
(14) “^[A-Za-z]+   //2615[AZ]+ ”     / / 由 26 个 英 文 字 母 组 成 的 字 符 串 ( 15 ) “ [ A − Z ] + ”  //由26个英文字母的大写组成的字符串
(16) “^[a-z]+   //2617[AZaz09]+ ”     / / 由 26 个 英 文 字 母 的 小 写 组 成 的 字 符 串 ( 17 ) “ [ A − Z a − z 0 − 9 ] + ”  //由数字和26个英文字母组成的字符串
(18) “^\w+   //26线19[\w]+(.[\w]+)@[\w]+(.[\w]+)+ ”     / / 由 数 字 、 26 个 英 文 字 母 或 者 下 划 线 组 成 的 字 符 串 ( 19 ) “ [ \w − ] + ( . [ \w − ] + ) ∗ @ [ \w − ] + ( . [ \w − ] + ) + ”    //email地址
(20) “^[a-zA-z]+://(\w+(-\w+))(.(\w+(-\w+)))(\?\S)?$”  //url
(21) /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-((0-2)|(3[0|1]))$/ // 年-月-日
(22) /^((0([1-9]{1}))|(1[1|2]))/((0-2)|(3[0|1]))/(d{2}|d{4}) /////23([w.]+)@(([[09]1,3.[09]1,3.[09]1,3.)|(([w]+.)+))([azAZ]2,4|[09]1,3)(]?) / / / 月 / 日 / 年 ( 23 ) “ ( [ w − . ] + ) @ ( ( [ [ 0 − 9 ] 1 , 3 . [ 0 − 9 ] 1 , 3 . [ 0 − 9 ] 1 , 3 . ) | ( ( [ w − ] + . ) + ) ) ( [ a − z A − Z ] 2 , 4 | [ 0 − 9 ] 1 , 3 ) ( ] ? ) ” //Emil
(24) /^((+?[0-9]{2,4}-[0-9]{3,4}-)|([0-9]{3,4}-))?([0-9]{7,8})(-[0-9]+)? ///25(d1,2|1dd|2[04]d|25[05]).(d1,2|1dd|2[04]d|25[05]).(d1,2|1dd|2[04]d|25[05]).(d1,2|1dd|2[04]d|25[05]) / / / 电 话 号 码 ( 25 ) “ ( d 1 , 2 | 1 d d | 2 [ 0 − 4 ] d | 25 [ 0 − 5 ] ) . ( d 1 , 2 | 1 d d | 2 [ 0 − 4 ] d | 25 [ 0 − 5 ] ) . ( d 1 , 2 | 1 d d | 2 [ 0 − 4 ] d | 25 [ 0 − 5 ] ) . ( d 1 , 2 | 1 d d | 2 [ 0 − 4 ] d | 25 [ 0 − 5 ] ) ” //IP地址
(26)
(27) 匹配中文字符的正则表达式: [\u4e00-\u9fa5]
(28) 匹配双字节字符(包括汉字在内):[^\x00-\xff]
(29) 匹配空行的正则表达式:\n[\s| ]*\r
(30) 匹配HTML标记的正则表达式:/ (.)>. \/\1>| (.*) \/>/
(31) 匹配首尾空格的正则表达式:(^\s*)|(\s*$)
(32) 匹配Email地址的正则表达式:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
(33) 匹配网址URL的正则表达式:^[a-zA-z]+://(\w+(-\w+))(\.(\w+(-\w+)))(\?\S)? 34(516线)[azAZ][azAZ09]4,15 ( 34 ) 匹 配 帐 号 是 否 合 法 ( 字 母 开 头 , 允 许 5 − 16 字 节 , 允 许 字 母 数 字 下 划 线 ) : [ a − z A − Z ] [ a − z A − Z 0 − 9 ] 4 , 15
(35) 匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})?
(36) 匹配腾讯QQ号:^[1-9][1-9][0-9] 3738 39RegExpMultiline\n\r40 ( 37 ) 元 字 符 及 其 在 正 则 表 达 式 上 下 文 中 的 行 为 : ( 38 )   将 下 一 个 字 符 标 记 为 一 个 特 殊 字 符 、 或 一 个 原 义 字 符 、 或 一 个 后 向 引 用 、 或 一 个 八 进 制 转 义 符 。 ( 39 ) 匹 配 输 入 字 符 串 的 开 始 位 置 。 如 果 设 置 了 R e g E x p 对 象 的 M u l t i l i n e 属 性 , 也 匹 配 ′ \n ′ 或 ′ \r ′ 之 后 的 位 置 。 ( 40 ) 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性,$ 也匹配 ’\n’ 或 ’\r’ 之前的位置。
(41) * 匹配前面的子表达式零次或多次。
(42) + 匹配前面的子表达式一次或多次。+ 等价于 {1,}。
(43) ? 匹配前面的子表达式零次或一次。? 等价于 {0,1}。
(44) {n} n 是一个非负整数,匹配确定的n 次。
(45) {n,} n 是一个非负整数,至少匹配n 次。
(46) {n,m} m 和 n 均为非负整数,其中n = m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。
(47) ? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
(48) . 匹配除 “\n” 之外的任何单个字符。要匹配包括 ’\n’ 在内的任何字符,请使用象 ’[.\n]’ 的模式。
(49) (pattern) 匹配pattern 并获取这一匹配。
(50) (?:pattern) 匹配pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。
(51) (?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
(52) (?!pattern) 负向预查,与(?=pattern)作用相反
(53) x|y 匹配 x 或 y。
(54) [xyz] 字符集合。
(55) [^xyz] 负值字符集合。
(56) [a-z] 字符范围,匹配指定范围内的任意字符。
(57) [^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符。
(58) \b 匹配一个单词边界,也就是指单词和空格间的位置。
(59) \B 匹配非单词边界。
(60) \cx 匹配由x指明的控制字符。
(61) \d 匹配一个数字字符。等价于 [0-9]。
(62) \D 匹配一个非数字字符。等价于 [^0-9]。
(63) \f 匹配一个换页符。等价于 \x0c 和 \cL。
(64) \n 匹配一个换行符。等价于 \x0a 和 \cJ。
(65) \r 匹配一个回车符。等价于 \x0d 和 \cM。
(66) \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
(67) \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
(68) \t 匹配一个制表符。等价于 \x09 和 \cI。
(69) \v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
(70) \w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
(71) \W 匹配任何非单词字符。等价于 ’[^A-Za-z0-9_]’。
(72) \xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。
(73) \num 匹配 num,其中num是一个正整数。对所获取的匹配的引用。
(74) \n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
(75) \nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
(76) \nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
(77) \un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。
(78) 匹配中文字符的正则表达式: [u4e00-u9fa5]
(79) 匹配双字节字符(包括汉字在内):[^x00-xff]
(80) 匹配空行的正则表达式:n[s| ]*r
(81) 匹配HTML标记的正则表达式:/ (.)>. /1>| (.*) />/
(82) 匹配首尾空格的正则表达式:(^s*)|(s*$)
(83) 匹配Email地址的正则表达式:w+([-+.]w+)@w+([-.]w+).w+([-.]w+)*
(84) 匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?
(85) 利用正则表达式限制网页表单里的文本框输入内容:
(86) 用正则表达式限制只能输入中文:οnkeyup=”value=value.replace(/[^u4E00-u9FA5]/g,”)” onbeforepaste=”clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^u4E00-u9FA5]/g,”))”
(87) 用正则表达式限制只能输入全角字符: οnkeyup=”value=value.replace(/[^uFF00-uFFFF]/g,”)” onbeforepaste=”clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^uFF00-uFFFF]/g,”))”
(88) 用正则表达式限制只能输入数字:οnkeyup=”value=value.replace(/[^d]/g,”) “onbeforepaste=”clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^d]/g,”))”
(89) 用正则表达式限制只能输入数字和英文:οnkeyup=”value=value.replace(/[W]/g,”) “onbeforepaste=”clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^d]/g,”))”
(90)
(91)
(92) 整理:
(93)
(94) 匹配中文字符的正则表达式: [\u4e00-\u9fa5]
(95) 匹配双字节字符(包括汉字在内):[^\x00-\xff]
(96) 匹配空行的正则表达式:\n[\s| ]*\r
(97) 匹配HTML标记的正则表达式:/ (.)>. \/\1>| (.*) \/>/
(98) 匹配首尾空格的正则表达式:(^\s*)|(\s*$)
(99) 匹配IP地址的正则表达式:/(\d+).(\d+).(\d+).(\d+)/g //
(100) 匹配Email地址的正则表达式:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
(101) 匹配网址URL的正则表达式:http://(/[\w-]+.)+[\w-]+(/[\w- ./?%&=]*)?
(102) sql语句:^(select|drop|delete|create|update|insert).* 1031\d+ ( 103 ) 1 、 非 负 整 数 : \d +
(104) 2、正整数:^[0-9][1-9][0-9] 1053((\d+)|(0+)) ( 105 ) 3 、 非 正 整 数 : ( ( − \d + ) | ( 0 + ) )
(106) 4、负整数:^-[0-9][1-9][0-9] 1071085?\d+ ( 107 ) ( 108 ) 5 、 整 数 : − ? \d +
(109)
(110) 6、非负浮点数:^\d+(.\d+)?$
(111)
(112) 7、正浮点数:^((0-9)+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])) 1131148((\d+.\d+)?)|(0+(.0+)?)) ( 113 ) ( 114 ) 8 、 非 正 浮 点 数 : ( ( − \d + . \d + ) ? ) | ( 0 + ( .0 + ) ? ) )
(115)
(116) 9、负浮点数:^(-((正浮点数正则式))) 11711810[AZaz]+ ( 117 ) ( 118 ) 10 、 英 文 字 符 串 : [ A − Z a − z ] +
(119)
(120) 11、英文大写串:^[A-Z]+ 12112212[az]+ ( 121 ) ( 122 ) 12 、 英 文 小 写 串 : [ a − z ] +
(123)
(124) 13、英文字符数字串:^[A-Za-z0-9]+ 12512614线\w+ ( 125 ) ( 126 ) 14 、 英 数 字 加 下 划 线 串 : \w +
(127)
(128) 15、E-mail地址:^[\w-]+(.[\w-]+)*@[\w-]+(.[\w-]+)+$
(129)
(130) 16、URL:^[a-zA-Z]+://(\w+(-\w+))(.(\w+(-\w+)))(\?\s)?$
(131) 或:^http:\/\/[A-Za-z0-9]+.[A-Za-z0-9]+[\/=\?%-&_~`@[]\’:+!]([^ >\”\”]) 13213317[19]\d5 ( 132 ) ( 133 ) 17 、 邮 政 编 码 : [ 1 − 9 ] \d 5
(134)
(135) 18、中文:^[\u0391-\uFFE5]+ 13613719(((\d2,3))|(\d3))?((0\d2,3)|0\d2,3)?[19]\d6,7(\d1,4)? ( 136 ) ( 137 ) 19 、 电 话 号 码 : ( ( ( \d 2 , 3 ) ) | ( \d 3 − ) ) ? ( ( 0 \d 2 , 3 ) | 0 \d 2 , 3 − ) ? [ 1 − 9 ] \d 6 , 7 ( − \d 1 , 4 ) ?
(138)
(139) 20、手机号码:^(((\d{2,3}))|(\d{3}-))?13\d{9} 14014121()\x00\xff14214322(\s)|(\s ( 140 ) ( 141 ) 21 、 双 字 节 字 符 ( 包 括 汉 字 在 内 ) : \x 00 − \xff ( 142 ) ( 143 ) 22 、 匹 配 首 尾 空 格 : ( \s ∗ ) | ( \s ∗ )(像vbscript那样的trim函数)
(144)
(145) 23、匹配HTML标记: (.)>. \/\1>| (.*) \/>
(146)
(147) 24、匹配空行:\n[\s| ]*\r
(148)
(149) 25、提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) = (‘|”)?(\w|\|\/|.)+(‘|”| *|>)?
(150)
(151) 26、提取信息中的邮件地址:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
(152)
(153) 27、提取信息中的图片链接:(s|S)(r|R)(c|C) = (‘|”)?(\w|\|\/|.)+(‘|”| *|>)?
(154)
(155) 28、提取信息中的IP地址:(\d+).(\d+).(\d+).(\d+)
(156)
(157) 29、提取信息中的中国手机号码:(86)*0*13\d{9}
(158)
(159) 30、提取信息中的中国固定电话号码:((\d{3,4})|\d{3,4}-|\s)?\d{8}
(160)
(161) 31、提取信息中的中国电话号码(包括移动和固定电话):((\d{3,4})|\d{3,4}-|\s)?\d{7,14}
(162)
(163) 32、提取信息中的中国邮政编码:[1-9]{1}(\d+){5}
(164)
(165) 33、提取信息中的浮点数(即小数):(-?\d*).?\d+
(166)
(167) 34、提取信息中的任何数字 :(-?\d*)(.\d+)?
(168)
(169) 35、IP:(\d+).(\d+).(\d+).(\d+)
(170)
(171) 36、电话区号:/^0\d{2,3}$/
(172)
(173) 37、腾讯QQ号:^[1-9][1-9][0-9] 17417538(516线)[azAZ][azAZ09]4,15 ( 174 ) ( 175 ) 38 、 帐 号 ( 字 母 开 头 , 允 许 5 − 16 字 节 , 允 许 字 母 数 字 下 划 线 ) : [ a − z A − Z ] [ a − z A − Z 0 − 9 ] 4 , 15
(176)
(177) 39、中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$

Day15集合框架
一、集合的由来
如果我们要操作很多对象,我们就要把很多对象进行存储。这个时候,我们会想到了我们前面学过数组,那么我们可以把自定义对象放到数组中。
为什么我们不采用数组存对象呢?因为数组长度是固定,而我们很多时候对对象的个数是不确定的。所以,我们产生了集合框架,它是用于存储对象的。
1、集合和数组的区别
A:集合长度是可变的,集合中不能存储基本数据类型值,只能存储对象。
B:数组的长度是固定的,可以存储对象,也可以存储基本数据类型。
什么时候用哪个?
长度不固定,用集合。
长度固定,可以集合,可用数组。
2、集合的体系结构
由于每种容器的数据结构不同,所以我们集合框架中有很多种容器。这个时候,我们把容器进行不断的向上抽取,最终形成了集合的体系结构。
Collection
|–List
|–ArrayList
|–Vector
|–LinkedList
|–Set
|–HashSet
|–TreeSet
|–LinkedHashSet
按照我们学习体系的习惯:先学习顶层对象,后使用底层对象。
二、collection接口
1、添加
Boolean add(E e):在集合中添加一个对象,如果添加成功,返回true,如果失败,返回false
Boolean addAll(Collection?extend E> e):在集合中添加另一个集合,成功true,失败false;
2、删除
Boolean remove(object obj):删除一个对象,会改变集合的长度
Boolean removeAll(Colleciton con);删除一个集合,还有两个集合中相同的元素
void clear():删除所有
3、判断
Boolean contains(object obj):在集合中是否包含指定的对象
Boolean containsAll(Collection con):在集合是否包含另一个集合
Boolean isEmpty( ):判断集合是否为空
4、获取
int size( ):得到集合的尺寸大小 数组:length 字符串:length( );
Iterator iterator( ):取出元素的方式。迭代器。该对象必须依赖于绝缘体容器,因为每一个容器的数据结构都不同。所以该迭代器对象是在容器中进行内部实现的,对于使用容器者而言,绝缘体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法,Iterator接口就是对所有的collection容器进行元素取出的公共接口。
将每一个容器中的取出方式进行了封装,并对外暴露,这样无论是什么容器或者数据结构,只要内部取出方式实现了Iterator接口,都可以通过该接口取出这些容器中的元素。
他的出现,将容器的取出方式和容器的数据结构相分离,降低了耦合性,而取出方式因为直接在访问容器的元素,并依赖具体的数据结构,所以被定义在了容器中。通过内部类来实现Iterator接口。
Collection c = new ArrayList();
c.add(“hello”);
Iteratot it = c.iterator();//返回的是Iteratot的子类对象
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
for(object obj:con)用于数组和集合(高级for循环)
注意:迭代要强转,只能有一个next( )方法,否则会有NoSuchElementException异常。
5、交集
boolean retainAll(Collection c):返回两个集合的交集元素,删除其他元素,功能和removeAll相反。有A,B两个集合,做完交集后,A集合中的元素发生变化,取得是A和B相同的元素,B不变化。boolean值的问题——–>只要A集合变化,那么返回true.否则false

6、集合转数组
Object[] toArray():把集合转换成对象。
三、List接口
有序(存入和取出的顺序一致,)元素都有索引(角标),元素可以重复。
特有的常见方法:有一个共性特点就是都可以操作角标,可以完成对元素的增删改查。
规律:凡是有索引的容器,都有增删改查的方法。
1、添加
void add(index,element):在指定位置增加元素
void add(index,collection):在指定位置添加集合
2、删除
Object remove(index):删除指定的元素—-获取并删除
3、修改
Object set(index,element):在指定位置改变元素,并返回被替换掉的元素。
4、获取
Object get(index):获取指定的元素
int subList(startindex,iendndex):获取子列表
int indexOf(object ):返回对象所在的位置
int lastIndexOf(object):返回对象最后出现的位置
ListIterator:拥有了对元素进行增删改查的方法——->list特有的!
Object previous() 返回前一个元素
Boolean hasPrevious() 判断是否有元素
注意:只有正向遍历,才能逆向遍历!!没什么卵用!
5、List接口的子类
LinkedList是一种链式存储方式,线程不安全,效率高,查询满
Vector:内部是数组数据结构,是线程安全的。增删查询都很慢!
ArrayList:内部是数组数据结构,是不同步的,代替了vector.,查询的速度快
内存原理:
在arrayList集合中,是一种线性表,每个对象存储都是有序的,用角标确定对象所存储的位置,查询时,直接通过角标进行查询,速度会很快,但是如果要进行增添、修改、删除操作的话,就要影响后面角标的对象,大部分对象都要移动,直接影响运行效率。
ListkedList:内部是链表数据结构,是不同步的,增删元素的速度很快。
内存原理:
LinkedList是一种链式存储方式,在每个对象中都存储有下一个对象的地址。所以要查询集合中的对象,必须通过地址值来逐个访问,首先从表头开始,逐一向下一个进行询问,直到找到为止,所以这样导致查询对象相对于arrayList来说非常慢,但是他有一个优点,增加、删除、修改就很快,如果要增加一个对象,直接把这个对象的地址赋给上一个对象,并存储下一个对象的地址。所以修改和删除也是对地址进行操作。大大提高运行效率。
四、Set接口
1、特点
元素不能重复,无序,Set接口中的方法和collection的方法一样
HashSet:内部实际结构是哈希表,是不同步的。
哈希表:将对象经过哈希算法计算成该对象的哈希值,并把哈希值存放在哈希表中,其实哈希值就相当于数组中的角标。所以在查找的时候直接根据哈希值查询,速度很快。
哈希表确定元素是否相同
 判断的是两个元素的哈希值是否相同,如果相同,再判断两个对象的内容是否相同
 判断哈希值相同,其实判断的是对象的hashcode的方法,判断内容相同,用的是equlas方法
注意:如果哈希值不同,是不用判断equals.
Hahset集合数据是哈希表,所以存储元素的时候,使用的元素的hashcode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。也就是通过对象的hashcode和equals方法来完成对象唯一性的,如果对象的hashcode值不同,那么不用判断equals方法,就直接存储到哈希表中,如果对象的hashcode值相同,那么要再次判断对象的equals 方法是否为true,如果为true,视为相同元素,不存,如果为false,那么视为不同元素,就进行存储。
记住:如果元素要存储到hashset集合中,必须覆盖hashcode方法和equals方法,一般情况下,如果定义的类会产生很多对象,比如人,学生,数,通常都需要覆盖equlas,hashcode方法。建立对象判断是否相同的依据。

TreeSet:可以对集合中的元素进行排序,是不不同步的,
判断元素唯一性的方式:即使根据比较方法的返回结果是否是0,是0,就是相同的元素,不存,
 Treeset对元素进行排序的方式一:
让元素自身具备比较功能,就需要实现comparable接口,覆盖comparaTo( )方法。如果不要按照对象中具备的自然顺序进行排序,如果对象中不具备自然顺序,怎么办?
 可以使用treeset集合第二种排序方式二:
让集合自身比较功能,定义一个类实现comparator接口,覆盖compare方法。将该类对象作为参数传递给treeset集合的构造函数。
2、集合的使用技巧
同步与非同步:
明确具体集合对象名称的后缀,如果后缀是List都所属于List体系,通常是非同步的,如果后缀是Set都所属set体系,通常是非同步的;这些体系的其他子类对象,后缀不是所属接口名的,一般都是同步的。如vector
数据结构:
前缀是数据结构,后缀是所属体系。
ArrayList:看到Array,明确是数组结构,查询快。
需要唯一吗?
需要:set
需要制定顺序吗:
需要:TreeSet
不需要:hashset
但是想要一个和存储一致的顺序(有序):linkedhashset
不需要:list
选要频繁增删吗:
需要:linkedlist
不需要:arraylist
如果记录每一个容器的结构和所属体系呢?
看名字!
List
Arraylist
Linkedlist
Set
Hashset
Treeset
后缀名就是该集合所属的体系。
前缀名就是该集合的数据结构。
看到array:就要想到数组,就要想到查询快,有角标。
看到link:就要想到链表,就要想到增删快,就要想到 add get remove+first last的方法。
看到hash:就要想到哈希表,就要想到唯一性,就要想到hashcode和equals
看到tree:就要想到排序,想到二叉树,就要想到comparable和comparator
通常这些常用的是线程不安全的。
五、泛型
Jdk1.5出现的安全机制。解决类型安全问题,只能用于编译时期,提高安全性
1、好处
 将运行时期的问题classCastExceptoin转到了编译时期。
 避免了强制转换的麻烦。
2、什么时候用
当操作的引用数据类型不确定的时候,就使用泛型,将要操作的引用数据类型传入即可,其实 >就是一个用于接收具体引用数据类型的参数范围。
在程序中,只要用到了带有 >的类或者接口,就要明确传入的引用数据类型。
泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全。运行时,会将泛型去掉。生成的class问题中是不带泛型的,这个叫泛型的擦除。为什么擦除呢?因为为了兼容运行的类加载器。
泛型的补偿:下运行时,通过获取元素的类型进行转换动作,不用使用者在强制转换了。
泛型类:什么时候用?当类中的操作的引用数据类型不确定时候,就可以使用泛型类来表示。
当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。写在返回值的前面。
泛型接口:将泛型定义在接口上。
泛型的通配符:?未知类型

泛型的限定:?extends E———>接收E类型或者E的子类型。
?extends E:接收E类型或者E的子类对象,上限
一般在存储元素的时候都是用上限,因为这样取出都是按照上限类型来运算的,不会出现类型安全隐患。
?super E:接收E类型或者E的父类对象,下限
什么时候用下限呢?通常对集合中的元素进行取出操作时。可以用下限。

六、Map
一次添加一对元素,conllection一次添加一个元素
Conllection是单列集合,map是双列集合。其实map集合中存储的就是键值对。
Map集合中必须保证键的唯一性。
1、常用的方法
 添加
value put(key,value):费前一个和Key关联的值,如果没有返回null
 删除
void clear():清空Map集合。
value remove(key):根据指定的Key翻出这个键值对。
 判断
Booelean containsKey(key):判断是否包含指定的建
Boolean containsValue(value):判断是否包含指定的值
Boolean isEmpty():判断是否为空
 获取
value get(key):通过键获取值,如果没有改建返回null,当然可以通过返回Null,来判断是否包含指定键。
int size():获取键值对的大小
2、从map中获取值的方法
@Test
public void show(){
Map Student,String> map = new HashMapStudent,String>();
map.put(new Student(“mm”,23),”湖北”);
map.put(new Student(“lisi”,27),”北京”);
map.put(new Student(“wangwu”,29),”山东”);
map.put(new Student(“zhaoliu”,43),”四川”);
map.put(new Student(“houqi”,33),”深圳”);
map.put(new Student(“maba”,53),”江苏”);
map.put(new Student(“wangcai”,13),”浙江”);
/*for (Integer i : map.keySet()) {
System.out.println(map.get(i));
}*/
for (Entry Student,String> it : map.entrySet()) {
Student s = it.getKey();
String str = map.get(it.getKey());
//System.out.println(it.getKey()+”\t”+map.get(it.getKey()));
System.out.println(s.getName()+”:\t”+s.getAge()+”\t”+str);
}
}
Map常用的子类;
Hashtable:内部结构是哈希表,是同步的,不允许Null作为建,null作为值,
Properties:用来存储简直对型对配置文件的信息,可以和IO技术相结合。
Hashmap:内部构造是哈希表,不是同步的。允许null键,null为null
Linkedhashmap:是map接口的哈希表和链接列表实现,存储和取出一致
Treemap:内部构造是二叉树,不是同步的,可以对map集合进行排序
3、Map和Collection的区别?
1.collection是用于存储单列对象的集合,可以是一组单个对象,而map是存储双列对象集合,也就是以键值对的形式存储。是两组对象,一组是用来存储键,一组是存储值。
2.collection增加的方法是add,map是put.
3.如果要取出集合中的元素,collection可以直接使用迭代器,但是map不能直接用迭代器,可以先把Map集合转换成set集合,再用迭代器取出元素。
4.如果没有映射关系,使用collection ,对象与对象之间产生映射关系就用map集合。
5、Collecitons中常见方法举例?
static T extends Comparable ? super T>> void sort(List T> list) :将集合进行排序,并可以指定集合参数的类型,要继承comparable接口,
static void swap(List ?> list, int i, int j) :根据指定的位置交换集合中的元素
static void shuffle(List ?> list) :对集合中元素位置随机发生变化
static T> int binarySearch(List ? extends Comparable ? super T>> list, T key) :使用二分查找给出指定的值在集合中的位置
static T> Tmax(collection ?> coll)最大值
static void reverse(List ?> list)反转
6、Collection和Collections的区别?
collection
collection是所有单列集合中的父接口,是以一组单个对象存储形式,根据需求,对象在内存中存储数据结构形式不同,collection就产生许多子接口,其中常用的是list接口和set接口,而List有ArrayList和linkedList两个常用的实现类,它是有序可重复的,set接口有hashset和treeset两个实现类,是无序不可重复的。
collections
他是对集合操作的一种工具类,类中的方法全部都是静态的,可以对集合的排序,交换位置,二分查找,元素顺序随机变化。等操作。
8、数组和集合转换,数组转集合为什么?集合转数组为什么?要注意什么?
数组转集合:可以对数组中的元素通过集合中的方法进行操作,只要不影响其长度,可以使用集合中的任意方法。
集合转数组:为了限制集合中元素操作,他只有一个length属性可以操作
注意:不管是集合转数组还是数组转集合,长度是不可以改变的,不能对其进行增删操作。
9、增强for循环和传统for循环的区别?foreach可以遍历map吗?什么时候使用map?
在循环多次的时候,传统的循环可以对其循环条件的控制,而增强for不能控制,增强for只能是简化书写,遍历集合或数组中的元素,
不能直接遍历map集合,但是可以通过把map集合转成set集合后,再根据set集合迭代出元素。
当分析问题时,发现存在着映射关系,这时可以考虑到数组和map。
10、可变参数的使用方式,和注意事项,并举例?
可变参数的使用格式:
1.int add(T… a):该函数可以添加多个同种类型的数据,相当于函数的参数是数组形式。
2.int add(T a,T… a1):在传参数是,除了第一个为a,其他全部都是属于可变参数。
注意:可变参数必须放在其他参数的最后边。
传入的实参必须是根据形参的同种类型的参数

Day16 IO
一、异常
1、概述
程序有可能出现问题,我们把出现的问题就称为异常.
2、主函数处理异常的方式
A:主函数手动处理方式的方式.(异常处理机制)
B:采用的是jvm的默认处理机制.
把异常的信息打印输出到控制台.
3、异常的体系结构
A:Throwable 异常的超类
**Error
我们不可解决的问题。面对此种问题,我们无能为力。
比如说:类不存在或者内存溢出。
**Exception
在运行时运行出现的一些不正常的状况,这个状况我们通过修改代码,是可以解决的。

4、异常的处理方式
A:try…catch…finally
**基本格式
try{
//有可能出现异常的代码
}catch(异常类 名字){
//处理异常的代码
}finally{
//一定会被执行的代码,如释放资源
}
**变形格式
try…catch
try…catch…catch…catch…
try…finally
try…catch…finally
try…catch…catch…finally
1、如果try语句中有return,就返回当前try中变量值,此后任意修改,都不影响try中return值
2、就算finally中有return,那么忽略try,catch中return,就算catch中有异常也不管
3、finally尽量不用return,且避免再次抛出异常,否则整个包含try语句方法块会抛出异常,并且会消化try,catch中异常。

**finally的特点
它永远都会被执行.
有一个特殊情况:如果在代码中jvm退出系统而来,那么finally就不会被执行.

    **面试题
        ***final,finally,finalize区别?

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用
*
try{
System.out.println(“aaa”);
System.out.println(10/0);//ArithmeticException
}catch(Exception e){
System.out.println(“bbb”);
return;
}finally{
System.out.println(“ccc”);
}
请问这个程序运行结果?
aaa
bbb
ccc
B:throws,throw 抛出
区别:——一旦执行throw语句,就结束功能!
throw:
在方法体中,后面跟的是异常对象名,并且只能是一个
throw抛出的是一个异常对象,说明这里肯定有一个异常产生了
throws:
在方法声明上,后面跟的是异常的类名,可以是多个
throws是声明方法有异常,是一种可能性,这个异常并不一定会产生 **联系
有throws不一定有throw
有throw一定有throws
C:两种处理方式用哪种呢? 何时使用try,何时使用throw呢?>
**自己能够处理的就自己处理.
**自己实在处理不了的交给调用者.
5、Exception的分类
A:Exception
这种类型的异常,如果抛出,在编译的时候就会检查.此类异常需要编写针对性的处 理代码进行处理。
B:RuntimeException
这种类型的异常,如果抛出,在编译的时候不检查,运行的时候直接处理.
这种异常必须通过修改代码才能解决.所以,一般针对这种异常,我们不处理,jvm处 理。
6、自定义异常
除数不能为负数.
1:继承自Exception或者RuntimeException.必须的!
2:在自定义异常里面,提供一个带参构造
class MyException extends Exception{
MyException(){}
MyExcepiton(String message){
super(message);
}
}
class Demo{
int div(int a,int b)throws RuntimeException{
if(b 0){
throw new MyException(“除数不能为负数!”);
}
}

7、异常使用细节
A:我们为什么要使用try…catch语句进行异常处理呢?只有在某个功能上可能出现某种隐患,并且在该功能的声明上进行了描述时,我们才能够使用此种针对性的处理方式。
B:如果一个功能抛出多个异常,那么在调用该功能时,需要有多个catch进行每一个异常的针对性处理,如果多个catch中有父类异常,一定要定义在最下面,否则编译失败。
C:函数内抛出异常,函数上一定要使用thows进行标识,调用者如果调用了该函数,就需要对其进行处理(try或者抛出),否则编译失败。
A:父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常
爸爸坏,儿子不能更坏
B:父的方法没有异常抛出,子的重写方法不能有异常抛出,如果有,只能try
C:父的方法抛出多个异常,子的重写方法必须比父少或者小
二、File类
1、IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件
2、构造方法
A:File file = new File(“e:\demo\a.txt”);
B:File file = new File(“e:\demo”,”a.txt”);
C:File file = new File(“e:\demo”);
File file2 = new File(file,”a.txt”);
3、File类的功能(自己补齐)
A:创建功能
public Boolean createNewFile() 创建文件(如果有就不创建了)
public Boolean mkdir() 创建文件夹(如果有就不创建了)
public Boolean mkdirs() 创建文件夹(如果父类没有就帮他创建)
B:删除功能
public Boolean delete()
C:重命名功能
public Boolean renameTo(File dest)
D:判断功能
public Boolean isDirectory() 是否是目录
public Boolean isFile() 是否是文件
public Boolean exists() 是否存在
public Boolean ranRead() 是否可读
public Boolean canWrite() 是否可写
public Boolean isHidden() 是否隐藏
E:获取功能
Public String getAbsolutePath() 获取绝对路径
Public String getpath() 获取相对 路径
Public String getName() 名称
Public long length() 长度,字节数
public long lastmolified 最后一次修改时间
public String[] list() 目录下的文件和目录的名称数组
public File[] listFiles()目录下的文件和目录的file数组
F:过滤器功能
FilenameFilter 用于过滤文件夹的接口
测试指定文件是否包含在某一文件的列表中
Boolean accept(File dir,String name)
(4)案例:
A:输出指定目录下指定后缀名的文件名称
a:先获取所有的,在遍历的时候判断,再输出
b:先判断,再获取,最后直接遍历输出即可
B:批量修改文件名称
三、IO流的特点及相关问题
 IO流用来处理设备之间的数据传输
设备:硬盘,内存,键盘录入
 Java对数据的操作是通过流的方式
 Java用于操作流的对象都在IO包中
 流按操作数据分为两种:字节流与字符流。
 流按流向分为:输入流,输出流。
1、输入流和输出流的流向的理解?
流就是处理数据的一种方式或者一种手段,或者理解为一种数据流。
从硬盘已有的数据读取出来放内存里面的这个过程就是输入流。
外部———>内存 输入流 读
把内存中的数据存储到硬盘中的这个过程就是输出流。
内存———>外部 输出流 写
简单理解就是:以内存为中心。
2、什么时候使用流对象?
操作设备上的数据或操作文件的时候可以使用。
四、字节流
字节流中的常见方法
构造方法:FileOutputStream(flie file);
字节流的输出步骤:
1、 创建字节输出流对象
2、 写数据(write())
3、 释放资源(close())
成员方法:
Public void write(int len)
Public void write(byte[] by)
Public void write(byte[] by,int off,int len)

构造方法:FileInputStream(String s)
成员方法:
Public void read(int len)
Public void read(byte[] by)
高效字节流
BufferedOutputStream(OutputStream out)
BufferedInputStream(InputStream out)

五、字符流
字符流的抽象基类:Reader &Writer
1、字符流的理解,由来和作用?
由于很多国家的文字融入进来,比如说中文在编码表中默认占2个字节。(在UTF-8中是3个字节)而为了按照文字的单位来处理,所以出现了字符流。
由来:后期编码表的不断出现,识别某一文字的码表不唯一。比如中文,GBK&unicode都可以识别,就出现了编码问题,为了处理文字数据,就需要通过早期的字节流+编码表结合完成。
作用:为了更便于操作文字数据。
结论:只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都是用字节流。
2、IO分类
按照功能进行分类———->读和写

IO体系中的子类名称后缀大部分都是父类名称,而前缀都是体现子类功能的名字。
Reader
InputStreamReader
FileReader 专门用于处理文件的
字符读取流对象
Writer
OutputStreamWriter
FileWriter 专门用于处理文件的
字符写入流对象
3、字符流继承体系图

4、解码编码中的问题
字符流 = 字节流 + 编码表
String(Byte[] bytes,String charestName) 解码
Byte[] getbytes(Byte[] bytes,String charestName) 编码

1、 默认编码 字节流——>字符流
OutputStreamWriter(OutputStream out)
2、 指定编码 字节流——>字符流
OutputStreamWriter(OutputStream out,String charestName)
3、 默认编码读取
InputStreamWriter(InputStream is)
4、 指定比编码读取
InputStreamWriter(InputStream is,String charestName)

5、Reader中的常见方法
 int read():读取一个字符。返回的是读到的那个字符(0-65535),如果读到流的末尾,返回-1
 int read(char[ ]):将读到的字符存入指定的数组中,返回的是读到的字符个数,也就是往数组里装元素的个数,如果读到流的末尾,返回-1。
 close( ):读取字符用的是windows系统的功能,就希望使用完毕后,进行资源的释放。
6、Writer中的常见方法
 void write(ch):将一个字符写入到流中。
 void write(char[ ]):将一个字符数组写入到流中。
 void write(String):将一个字符串写入到流中。
 void flush():刷新流,将流中的数据刷新到目的地中,流还存在。
 void close():关闭资源,在关闭前会先调用flush(),刷新流中的数据去目的地,然后关闭流。
7、FileWriter
该类没有特有的方法,只有自己的构造方法。
特点:
 用于处理文本文件;
 该类中有默认的编码表;
 该类中有临时缓冲。
构造方法:在写入流对象初始化时,必须有一个存储数据的目的地。
 FileWriter(String filename):该构造函数做了什么事情呢?
A:调用系统资源;
B:在指定位置创建一个文件,如果该文件已经存在,将会被覆盖。
 FileWriter(String filename,boolean true):该构造函数如果传入的boolean类型值为true时,会在指定文件末尾处进行数据的续写。
 换行:private static final String LINE_SEPARATOR = System.getProperties(“line.separator”);
fr.writer(“xi”+LINE_SEPARATOR+”xi”);
8、FileReader
用于读取文本文件的流对象,用于关联文本文件。
构造函数:在读取流对象初始化的时候,必须要指定一个被读取的文件,如果该文件不存在会发生FileNotFindException
FileReader fr = new FileReader(String filename)
基本的读写操作方式
因为数据通常都以文件的形式存在,所以就要找到IO体系中可以用于操作文件的流对象,通过名称可以更容易获取该对象。
9、完整的异常处理方式。
import java.io.FileWriter;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) {
FileWriter fw = null;//定义为全局,关闭的时候也要使用
try {
fw = new FileWriter(“E:\1.txt”);
fw.write(“abcd”);
fw.flush();
fw.write(“mn”);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {//防止空指针异常—–>运行时异常要做健壮性判断
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException(“关闭异常”);
}
}
}
}
}
小细节:当指定绝对路径时,定义目录分隔符有两种方式:
1,反斜线,但是一定要写两个。new FileWriter(“c:\1.txt”);
2,斜线,一个即可。new FileWriter(“c:/1.txt”);
10、复制文本文件的原理
首先用一个读取流对象和一个文件进行关联,然后用一个写入流对象作为目地的,为了把读取流中的文件传输到目的地流对象中,我们就提供了一个字符数组,为了关联这个数组,所以读取流对象有一个read()方法与这个字符数组进行关联,同理,写入流对象也有一个write()方法与这个字符数组进行关联,这样2个流对象就相连接了,而这个字符数组就相当于一个中转站。

将e盘的文件复制到i盘中
public class CopyFileTest {
public static void main(String[] args) {
File startfile = new File(“e:\a.txt”);
File endfile = new File(“i:\hello.txt”);
copyFile(startfile, endfile);
}
public static void copyFile(File startfile,File endfile){
FileReader fr = null;
FileWriter fw = null;
try {
//1,创建一个字符读取流读取与源数据相关联。
fr = new FileReader(startfile);
//2,创建一个存储数据的目的地。
fw = new FileWriter(endfile);
//3,创建一个字符数组将读取流对象和写入流对象相连接。
char[] buf = new char[1024];
//4,每次读取的长度不一样,所以定义一个变量.
int len = 0;
//5,用循环读取文件中的数据
while((len = fr.read(buf))!=-1){//判断是否读取完没
fw.write(buf,0,len); //为了只写入有效的数据
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(fr!=null){
try {
fr.close();
} catch (Exception e2) {
throw new RuntimeException(“读取流关闭失败”);
}
}
if(fw!=null){
try {
fw.close();
} catch (Exception e2) {
throw new RuntimeException(“写入流关闭失败”);
}
}
}
}
}
声明:为了减少代码的书写,以后出现的异常全使用抛出!
六、字符流缓冲区
1、字符缓冲区的原理
其实就是将数组进行封装。变成对象后,方便于对缓冲区的操作,提高效率。并提供了对文本便捷操作的方法。readLine( )&newLine( )。

缓冲区的基本思想就是对要处理的数据进行临时存储。譬如购物车以及篮子。
原理:减少频繁的操作,给读取流对象和写入流对象提供中转站,相对于来回跑的麻烦,利用缓冲区的容量,可以一边先存储,满了后再写入的方式,这样就提高了效率。
BufferedWriter的特有方法:newLine():跨平台的换行符。
BufferedReader的特有方法:readLine():一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。(返回的字符是不带回车符的)
在使用缓冲区对象时,要明确,缓冲的存在是为了增强流的功能而存在的,所以在建立缓冲区对象时,要先有流对象存在。其实缓冲内部就是在使用流对象的方法,只不过加入了数组对数据进行了临时存储,为了提高操作数据的效率。
2、代码上的体现
A:写入缓冲区对象——–>带缓冲区的写操作,一般都要进行刷新!
建立缓冲区对象必须把流对象作为参数传递给缓冲区的构造函数。
BufferedWriter bw = new BufferedWriter(new FileWriter(“a.txt”));
bw.write(“abcd”);//将数据写入缓冲区
bw.flush();//对缓冲区的数据进行刷新,将数据刷到目的地中
bw.close();//关闭缓冲区,其实关闭的是被包装在内部的流对象。
B:读取缓冲区对象
BufferedReader br = new BufferedReader(new FileReader(“b.txt”));
String line = null;
while((line= br.readLine)!=null){
System.out.println(line);
}
br.chose();
3、readLine( )方法的原理
其实缓冲区中的该方法,用的还是与缓冲区关联的流对象的read方法,只不过,每一次读到一个字符,先不进行具体操作,而是进行临时存储。当读到回车标记时,将临时容器中的数据一次性返回。—–>StringBuilder调用了buff.read()将缓冲区中的数据存储到了该容器中。
 缓冲区的read()和流对象的read()方法的区别?
流对象:从目的地一次读取一个字符
缓冲区:通过流对象的read([])将一批数据读取到缓冲数组,然后在数组中一次取一个字符,内存比硬盘操作要高效。
4、自定义缓冲区MyBufferedReader
/*
* 模拟一个缓冲区
* 基于已有的缓冲区思想,我们可以从源读取用read方法。
* 我们的缓冲区,应该是一个更高效的read读取方法。
*/
public class MyBufferedReader extends Reader{
private Reader r;
private char[] buf = new char[1024];
//用于记录缓冲区数据的个数
private int count = 0,pos = 0;
public MyBufferedReader(Reader r){
this.r = r;
}
/**
* 一次从缓冲区中取一个
* @return 返回一个缓冲区中的字符
* @throws IOException
*/
public int myRead() throws IOException {
//1,首先判断缓冲区中是否有数据,如果没有就从源中去拿。
if(count == 0){
//读取一批数据到缓冲数组buf中
count = r.read(buf);
pos = 0;
}
//2,当缓冲区中没数据了且源中也没有数据时,count自减1小于0时就返回-1结束.
if(count - 0)
return -1;
//3,如果以上都不满足,那么从缓冲区中写入一个字符到新的文件中。
char ch = buf[pos];
pos++;
count–;
return ch;
}
/**
* 按照文本特点,提供一个特有的操作文本的方法。
* 一次读取一行文本,只要是到行结束符之前的文本即可。
* @return 返回读取到的一行文本
* @throws IOException
* 原理:就是从缓冲区中取出数据,并存储到一个临时容器中。
* 如果取到了回车符,就将临时容器中的数据转成字符串返回。
*/
public String myReadLine() throws IOException{
//1,定义一个临时容器,进行临时存储
StringBuilder sb = new StringBuilder();
//2,定义一个变量,接收读取到的字符对应的二进制数(ASCII),0-65535
int ch = 0;
while((ch = myRead()) != -1){
//3,当读取到\r时,直接跳出本次循环,进行下次循环
if(ch == ‘\r’)
continue;
//4,当读取到\n时,直接跳出当前循环
if(ch == ‘\n’)
return sb.toString();
//5,当都没有读取到时,就将这些数据存储到临时容器中。
sb.append((char)ch);
}
//6,当临时容器中的长度不等于0时,就输出字符。
if(sb.length() != 0)
return sb.toString();
return null;
}
@Override
public void close() throws IOException {
}
@Override
public int read(char[] arg0, int arg1, int arg2) throws IOException {
return 0;
}
}
七、递归
1:递归(理解)
(1)方法定义中调用方法本身的现象
举例:老和尚给小和尚讲故事,我们学编程
(2)递归的注意事项;
A:要有出口,否则就是死递归
B:次数不能过多,否则内存溢出
C:构造方法不能递归使用
D:1、要写一个方法
2、出口条件
3、规律
(3)递归的案例:
A:递归求阶乘
B:兔子问题
C:递归输出指定目录下所有指定后缀名的文件绝对路径
D:递归删除带内容的目录(小心使用)
八、 其他流
1、数据操作流(操作基本类型数据的流)(理解)
(1)可以操作基本类型的数据
(2)流对象名称
DataInputStream
DataOutputStream

2、内存操作流(理解)
(1)有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。
(2)三种
A:ByteArrayInputStream,ByteArrayOutputStream
B:CharArrayReader,CharArrayWriter
C:StringReader,StringWriter

3、打印流(掌握)
(1)字节打印流,字符打印流
(2)特点:
A:只操作目的地,不操作数据源
B:可以操作任意类型的数据
C:如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
D:可以直接操作文件
问题:哪些流可以直接操作文件呢?
看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
(3)复制文本文件
BufferedReader br = new BufferedReader(new FileReader(“a.txt”));
PrintWriter pw = new PrintWriter(new FileWriter(“b.txt”),true);

    String line = null;
    while((line=br.readLine())!=null) {
        pw.println(line);
    }

    pw.close();
    br.close();

4、标准输入输出流(理解)
(1)System类下面有这样的两个字段
in 标准输入流
out 标准输出流
(2)三种键盘录入方式
A:main方法的args接收参数
B:System.in通过BufferedReader进行包装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
C:Scanner
Scanner sc = new Scanner(System.in);
(3)输出语句的原理和如何使用字符流输出数据
A:原理
System.out.println(“helloworld”);

        PrintStream ps = System.out;
        ps.println("helloworld");
    B:把System.out用字符缓冲流包装一下使用
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

6:随机访问流(理解)
(1)可以按照文件指针的位置写数据和读数据。
(2)案例:
A:写数据
B:读数据
C:获取和改变文件指针的位置

7:合并流(理解)
(1)把多个输入流的数据写到一个输出流中。
(2)构造方法:
A:SequenceInputStream(InputStream s1, InputStream s2)
B:SequenceInputStream(Enumeration ? extends InputStream> e)

8:序列化流(理解)
(1)可以把对象写入文本文件或者在网络中传输
(2)如何实现序列化呢?
让被序列化的对象所属类实现序列化接口。
该接口是一个标记接口。没有功能需要实现。
(3)注意问题:
把数据写到文件后,在去修改类会产生一个问题。
如何解决该问题呢?
在类文件中,给出一个固定的序列化id值。
而且,这样也可以解决黄色警告线问题
(4)面试题:
什么时候序列化?
如何实现序列化?
什么是反序列化?

9:Properties(理解)
(1)是一个集合类,Hashtable的子类
(2)特有功能
A:public Object setProperty(String key,String value)
B:public String getProperty(String key)
C:public Set String> stringPropertyNames()
(3)和IO流结合的方法
把键值对形式的文本文件内容加载到集合中
public void load(Reader reader)
public void load(InputStream inStream)

    把集合中的数据存储到文本文件中
    public void store(Writer writer,String comments)
    public void store(OutputStream out,String comments)
(4)案例:
    A:根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100
    B:写一个程序实现控制猜数字小游戏程序不能玩超过5次

10:NIO(了解)
(1)JDK4出现的NIO,对以前的IO操作进行了优化,提供了效率。但是大部分我们看到的还是以前的IO
(2)JDK7的NIO的使用
Path:路径
Paths:通过静态方法返回一个路径
Files:提供了常见的功能
复制文本文件
把集合中的数据写到文本文件

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值