咱是初哥,贴段自己的学习笔记,方便以后查看。
package com.icss.demo2; import java.awt.EventQueue; import java.math.BigDecimal; import java.util.Arrays; import java.util.Properties; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <strong>用于小测试的一个类,大杂烩,不放辣椒的,我不喜欢辣椒。</strong> * <p> * 测试的内容有:<br/> * 1、位运算符&在整数奇偶的判断上的应用<br/> * 2、位运算<<和>><br/> * 3、Scanner就用于控制台读取字符串<br/> * 4、大数值BingDecimal对浮点数精度的处理<br/> * 5、数组的拷贝与引用及其与基本类型数据的区别<br/> * 6、打印当前系统的属性<br/> * 7、类对象的浅克隆和深克隆<br/> * 8、程序的配置<br/> * 9、正则表达式的使用<br/> * 10、打印字符数组时需要注意的一些问题<br/> * </p> * * @author bing * @version 2011-01-08 * */ public class Test1 { public static void main(String[] args) throws CloneNotSupportedException{ Test1 test = new Test1(); ///////测试位运算符&在整数奇偶的判断上的应用////// /*int[] num = new int[10]; for(int i=0;i<num.length;i++){ num[i] = i-5; } for(int i : num){ System.out.println(i + " : " + test.isOdd(i)); }*/ ///////测试位运算<<和>>//////// ////输出,最后一个结果为负数是由于整数溢出 536870908 1073741816 2147483632 -32 /*int i; int num = 0xFFFFFFE; for (i = 0; i < 4; i++) { num = num << 1; System.out.println(num); }*/ ////////测试Scanner就用于控制台读取字符串///// // test.testScanner(); /*for(int i=0;i<3;i++){ test.testScanner(); }*/ ///////测试大数值BingDecimal对浮点数精度的处理//////// // test.testBigDecimal(); ///////测试数组的拷贝与引用及其与基本类型数据的区别///// // test.testArraysCopy(); //////打印当前系统的属性 // test.printProperties(); /////测试类对象的浅克隆和深克隆 // test.testFleetDeepClone(); ////////程序的配置////// // test.testProgramConfig(); ///////正则表达式///// // test.testRegex(); ///////打印字符数组时需要注意的一些问题////// test.testCharArrayPrint(); } /** * 判断一个数(正或负整数)是否为奇数 * [2011-01-08 14:33] * @param num * @return */ public boolean isOdd(int num){ return (num & 1) == 1; } /** * 使用Scanner读取字符串 */ public void testScanner(){ Scanner scan = new Scanner(System.in); System.out.print("Input a String:"); String str = scan.nextLine(); System.out.println("The String you input is \"" + str + "\"."); // 循环读取时关闭会抛出java.util.NoSuchElementException: No line found // 异常,无论是不是在每次循环中重新new一个Scanner对象。 // 相关的描述见http://lifeising.javaeye.com/blog/633505 // scan.close(); } /** * 测试大数值BigDecimal * 先看测试结果。 * java中的简单浮点数类型float和double不能进行数值精度的计算。使用float或double类型直接计算有时会出现精度丢失的问题, * 而大数值BigDecimal类提供无限大小的数值计算,但是BigDecimal不重载+、*等的运算符,需要调用其提供的方法。 * 有人提出这样一个原则:float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。 * 没做过实际的项目不发表意见,但是从这个测试中可以看出精度丢失带来的问题,特别是在金融业方面,这个数值计算带来的精度 * 的丢失最好是不要存在,否则..... * 这就不说了,我又不开银行,哪天被别人利用bug刷了点钱或是抗了别人的钱,老板被人伏击,也不干我事... * 不过要是我写出这种代码就不好了,咱做事都是兜着良心的... * [2011-01-08 14:33] */ public void testBigDecimal(){ float f1 = 0.05f; float f2 = 0.01f; double d1 = 0.05; double d2 = 0.01; System.out.println(f1+f2); // 由于BigDecimal的构造方法和静态方法valueOf中都没有处理float类型参数的,所以需要将float类型转换为String类型再构造BigDecimal System.out.println((new BigDecimal(String.valueOf(f1))).add((new BigDecimal(String.valueOf(f2))))); // 可使用构造函数,也可以使用静态方法valueOf(Double d) System.out.println(d1+d2); System.out.println(BigDecimal.valueOf(d1).add(BigDecimal.valueOf(d2))); } /** * 测试数组的拷贝与引用及其与基本类型数据的区别,测试int或String时把相应的变量增删注释即可。 * 拷贝与引用的区别,简单来说,如果A拷贝了B,则A不会因为B的改变而改变,如果A引用了B,则A会随着B的改变而改变,相当于是 * 一个物体的两个别名。 * 从测试中可以看出用一个数组直接通过“=”运算符赋值,是把两个数组变量指向同一块内存,相当于类的引用。拷贝一个数组到 * 另一个数组可以用void java.lang.System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) * 或者T[] java.util.Arrays.copyOf(T[] original, int newLength),Arrays.copyOf方法常用于重建不同长度的数组。 * 而基本数据类型用直接通过“=”运算符赋值,是拷贝一个数据到另一个数据中。 * * ps:数组的拷贝与引用类似于类对象的拷贝与引用,只是拷贝的方法有所不同,类对象的拷贝也叫克隆,使用clone方法实现,并且 * 需要该类实现Cloneable接口。不同的是,对象的克隆是对单个对象进行操作,数组的拷贝是对一组数据(包括对象)的拷贝。 * [2011-01-08 14:33] */ public void testArraysCopy(){ /////////测试数组的拷贝//////// // int[] array = new int[10]; // int[] copyArray = new int[10]; String[] array = new String[10]; String[] copyArray = new String[10]; for(int i=0;i<array.length;i++){ array[i] = i + ""; } // copyArray = array; // copyArray引用array。copyArray与array指向同一块内存 // System.arraycopy(array, 0, copyArray, 0, array.length);// 将array拷贝到copyArray中 copyArray = Arrays.copyOf(array, Math.min(array.length, copyArray.length));// 将array拷贝到copyArray中 System.out.print("原array:"); // for(int i : array){ for(String i : array){ System.out.print(i + " "); } System.out.print("\n原copyArray:"); // for(int i : copyArray){ for(String i : copyArray){ System.out.print(i + " "); } // array[5] = 19; // 修改array值 array[5] = 19 + "";// 修改array值 System.out.print("\n新array:"); // for(int i : array){ for(String i : array){ System.out.print(i + " "); } System.out.print("\n新copyArray:"); // for(int i : copyArray){ for(String i : copyArray){ System.out.print(i + " "); } ///////测试基本数据的拷贝//////// // int a = 5; // int b = a; String a = 5 + ""; String b = a; System.out.println("\na = " + a + "\tb = " + b); // a = 6; a = 6 + "";// 修改a值 System.out.println("a = " + a + "\tb = " + b); //////测试自定义类(用户类)数组的拷贝与引用///// Poker[] ps1 = new Poker[5]; Poker[] ps2 = new Poker[5]; for(int i=0;i<ps1.length;i++){ ps1[i] = new Poker("黑桃",(i%13)+1); } // ps2 = ps1; // 对象数组的引用,ps1和ps25指向同一块内存,是这块内存的两个别名 System.arraycopy(ps1, 0, ps2, 0, Math.min(ps1.length,ps2.length)); // 对象数组的拷贝 System.out.print("ps1原牌:"); for(Poker p : ps1){ System.out.print(p.toString()); } System.out.print("\nps2原牌:"); for(Poker p : ps2){ System.out.print(p.toString()); } // 修改ps1牌的花色 for(int i=0;i<ps1.length;i++){ ps1[i] = new Poker("梅花",(i%13)+1); } System.out.print("\nps1新牌:"); for(Poker p : ps1){ System.out.print(p.toString()); } System.out.print("\nps2新牌:"); for(Poker p : ps2){ System.out.print(p.toString()); } } /** * 打印当前系统的属性 */ public void printProperties(){ Properties ps = System.getProperties(); System.out.println("当前系统的属性(共" + ps.size() + "个属性):"); for(Object key: ps.keySet()){ String strKey = (String)key; System.out.println(strKey + " :\n " + ps.getProperty(strKey)); } } /** * 测试对象的浅拷贝与深拷贝,即对象的浅克隆与深克隆。测试浅克隆或深克隆时把相应的测试语句增删注释即可。 * 由测试得知,浅克隆与深克隆的区别在于,浅克隆不会克隆类对象中包含的子类的对象属性,而深克隆则会。默认的克隆,即使用 * 超类(Object)的克隆方法super.clone()进行克隆,是浅克隆,所以要实现深克隆,则必须覆盖父类的克隆方法(clone)。 */ public void testFleetDeepClone() throws CloneNotSupportedException{ ChildForTestClone child = new ChildForTestClone("child","I'm a child!"); ParentForTestClone parent1 = new ParentForTestClone("parent1","I'm parent1!",child); ParentForTestClone parent2 = parent1.fleetClone(); // 浅克隆测试 // ParentForTestClone parent2 = parent1.deepClone(); // 深克隆测试 System.out.println("克隆:\n" + parent1.toString() + " " + parent1.getChild().toString() + "\n" + parent2.toString() + " " + parent2.getChild().toString() ); parent1.setName("parent1NewName"); System.out.println("修改parent1的属性之后:\n" + parent1.toString() + " " + parent1.getChild().toString() + "\n" + parent2.toString() + " " + parent2.getChild().toString() ); parent1.getChild().setName("childNewName"); System.out.println("修改parent1里的child(子对象)的属性之后:\n" + parent1.toString() + " " + parent1.getChild().toString() + "\n" + parent2.toString() + " " + parent2.getChild().toString() ); } /** * 测试程序的配置 */ public void testProgramConfig(){ // 测试属性映射,利用属性文件(.properties)保存程序的配置 // EventQueue.invokeLater(new Runnable() // { // public void run() // { // PropertiesFrame frame = new PropertiesFrame(); // frame.setVisible(true); // } // }); // 测试Preferences API,利用操作系统提供的存储配置文件的中心知识库保存程序的配置 EventQueue.invokeLater(new Runnable() { public void run() { PreferencesFrame frame = new PreferencesFrame(); frame.setVisible(true); } }); /* System.out.println(new File("").getAbsolutePath()); System.out.println(System.getProperty("user.dir")); System.out.println(Test1.class.getResource("")); System.out.println(Test1.class.getResource("/"));*/ } /** * 正则表达式的使用 */ public void testRegex(){ // 验证电子邮件地址 String regex1 = "\\w+(@|\\W)\\w+\\.((com(\\.cn)?)|(net))"; String str1 = "fhief#awyy_fd0fdfqe.com.cn"; System.out.println(Pattern.matches(regex1, str1)); // 验证24小时制时间格式 String regex2 = "(([01][0-9])|(2[0-3])):[0-5][0-9]:[0-5][0-9]"; String str2 = "23:00:00"; System.out.println(Pattern.matches(regex2, str2)); // 验证一句话中的haha子串 String regex3 = ".*:\".*(ha){2}.*\"\\W*"; String str3 = "cheatcode is:\"My father is LiGang,haha\"! "; System.out.println(Pattern.matches(regex3, str3)); // 多次匹配(匹配的结果不尽人意) /* 注:Pattrern.matches(String regex,String str)和Matcher的find(int start)方法匹配的时候是 * 如果后面有匹配的子字符串则返回true,如quaqm,这显然不是想要的结果,所有的努力都是要出现qu时就返回false。 * 而他们的这种匹配是匹配了整个字符串,如quaqm则匹配得到了两个结果false和true,然后用“或”联系则最后的结果是true。 * 换句话说,只要是有一个true,结果就是true,而我所需要的是只要有一个false就返回false。丫的不给力啊!! * 丫的不给力,解决的方法只有把Matcher的find(int start)方法干掉,重写,用自己的规则实现自己的想法。 * 或者直接用String的子串操作来实现,直接查找“qu”,不过这种工作真的很无聊,把正则的匹配写成那样,也太那个了点。 */ String regex4 = ".*q[^u].*"; String str4 = "zaqqquaqm"; // System.out.println(Pattern.matches(regex4, str4)); Pattern pa = Pattern.compile(regex4); Matcher mat = pa.matcher(str4); int index = 0; // 记录验证开始位 boolean flag; // 记录验证结果 while(true){ // System.out.println("mat.find(index) = " + mat.find(index)); // 输出匹配的调试信息,调试用 if(mat.find(index)){ // 从字符串的index位开始匹配。问题:如果后面有匹配的子字符串则返回true,如quadfdqm index = str4.indexOf('q',index) + 1; // 下标后移1位,为下一次匹配做准备 flag = true; // System.out.println("sub of str4 = " + str4.substring(index)); // 输出下一次匹配的调试信息,调试用 // System.out.println("flag = " + flag); // System.out.println("index = " + index); if(str4.indexOf('q', index) == -1) // 如果后面的子串中没有'q'则不再匹配 break; continue; } flag = false; break; } System.out.println(flag); // 起始符与终止符 String regex5 = "^My$"; // String regex5 = "^$"; // String regex5 = "^"; String str5 = "Mfdfy"; System.out.println(Pattern.matches(regex5, str5)); } /** * 测试,打印字符数组时需要注意的一点,也就是数组与基本类型的不同。 * 数组对象是数组的一个引用,引用存放在内存的栈中,而实际数据(数组内容)存放在内存的堆中。 * 使用print((char[])+"")相当于调用print((new Char[]).toString+String),跟进查看源代码可知,最后调用的是print(String)方法, * 输出的是引用的内存地址,而不是数组的内容。 * 而使用print(char[])输出的则是数组的内容,跟进查看源代码可知,归后调用的是write(int c)方法。 * * 本测试中,cs是引用,c是基本数据类型,打印引用是会调用类的toString方法的,而打印基本数据类弄就不会如此做,""+基本数据类型, * 会调用String.valueOf(基本数据类型),将数据转换为字符串。要知道,基本数据类型不是对象,是不会有toString方法的,甚至是没有方法的。 * * [2011-01-22 14:46] */ public void testCharArrayPrint(){ String str = "abcdef"; char[] cs = str.toCharArray(); // 注意,数组对象(cs)是数组的一个引用 System.out.println(cs); // 调用println(String) System.out.println("" + cs.toString());// 调用println(char[]) 将字符数组转换成字符串输出时会输出字符数组的类型+哈希码 char c = 'a'; System.out.println(c); System.out.println(""+c); } }
ChildForTestClone 源代码
package com.icss.demo2; public class ChildForTestClone implements Cloneable{ private String name; private String info; public ChildForTestClone(){ } public ChildForTestClone(String name,String info){ this.name = name; this.info = info; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } /** * @retruns 子对象的名(子对象的描述) */ public String toString() { return this.name + "(" + this.info + ")"; } /** * 默认克隆(浅克隆) * @return * @throws CloneNotSupportedException */ public ChildForTestClone clone() throws CloneNotSupportedException{ return (ChildForTestClone)super.clone(); } }
ParentForTestClone 源代码
package com.icss.demo2; public class ParentForTestClone implements Cloneable{ private String name; private String info; private ChildForTestClone child; public ParentForTestClone(){ } public ParentForTestClone(String name,String info){ this.name = name; this.info = info; } public ParentForTestClone(String name,String info,ChildForTestClone child){ this.name = name; this.info = info; this.child = child; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public ChildForTestClone getChild() { return child; } public void setChild(ChildForTestClone child) { this.child = child; } /** * @retrun 父对象的名(父对象的描述)[父对象中包含的子对象的名] */ public String toString() { return this.name + "(" + this.info + ")[" + this.child.getName() + "]"; } /** * 深克隆(深拷贝) * @return 返回一个克隆对象,深克隆克隆类中包含的子类属性 */ protected ParentForTestClone deepClone() throws CloneNotSupportedException { ParentForTestClone cloneObject = (ParentForTestClone)super.clone(); // 克隆对象 cloneObject.setName(this.name); cloneObject.setInfo(this.info); cloneObject.setChild(this.child.clone());// 克隆子类属性 return cloneObject; } /** * 浅克隆(浅拷贝),默认的克隆时浅克隆,浅克隆不会克隆类中包含的子类属性,而是做引用处理 * @return * @throws CloneNotSupportedException */ protected ParentForTestClone fleetClone() throws CloneNotSupportedException { return (ParentForTestClone)super.clone(); // 默认的拷贝 } }