java基础学习笔记一

咱是初哥,贴段自己的学习笔记,方便以后查看。

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(); // 默认的拷贝
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值