JAVA开发之旅(十一)###常用类###

###常用类###

1. Java中的字符串

   1) 认识java中的字符串

   在程序开发中字符串无处不在,如用户登陆时输入的用户名、密码等使用的就是字符串。

   其实,在前面的章节中我们就已经使用了字符串,例如我们在控制台中输出的 "Hello World" 、 "Silvia" 、"Andrew"等。

   在 Java 中,字符串被作为 String 类型的对象处理。 String 类位于 java.lang 包中。默认情况下,该包被自动导入所有的程序。

创建 String 对象的方法:

    String s1 = "Andrew";      //创建一个字符串对象Andrew,名为s1

    String s2 = new String;    //chua创建一个空字符串名为s2

    String s3 = new String("Andrew")   //chu'创建一个字符串对象Andrew,名为s3

例:

package ex.class1;

public class Ex1 {

	public static void main(String[] args) {
		String s1 = "Andrew";
		String s2 = "Silvia";
		System.out.println("s1 "+s1+"  s2 "+s2);
	}
}

   2)Java中字符串的不变性

        String 对象创建后则不能被修改,是不可变的,所谓的修改其实是创建了新的对象,所指向的内存空间不同。

       如:

public class Ex1 {

	public static void main(String[] args) {
		String s1 = "Andrew";
		String s2 = "Andrew";
		String s3 = new String("Andrew");
		String s4 = new String("Andrew");
		
		System.out.println(s1 == s2);//多次出现的字符常量,Java编译程序只创建一个,所以返回true
		System.out.println(s1 == s3);//s1和s3是不同的对象,所以返回值为false
		System.out.println(s3 == s4);//s3和s4是不同的对象,所以返回值是false
		
		s1 = "Love "+ s1;//字符串s1被修改,指向新的内存空间
		System.out.println(s1);

	}
}

  结合上述代码,关于字符串我们必须需要了解:

     <1> 通过String s1 = "Andrew";   声明了一个字符串对象,s1存放了到字符串对象的引用,在内存中的存放引用关系如图

        然后通过 s1="欢迎来到:"+s1; 改变了字符串 s1 ,其实质是创建了新的字符串对象,变量 s1 指向了新创建的字符串对象,如图

     <2> 一旦一个字符串在内存中创建,则这个字符串将不可改变。如果需要一个可以改变的字符串,我们可以使用StringBuffer或者StringBuilder。

     <3>  每次 new 一个字符串就是产生一个新的对象,即便两个字符串的内容相同,使用 ”==” 比较时也为 ”false” ,如果只需比较内容是否相同,应使用 ”equals()” 方法

例:

public class Ex1 {

    public static void main(String[] args) {
		String s1 = "Andrew";
		String s2 = "Andrew";
        String s3 = "Love "+ s1;
        //定义字符串s3,保存“love”和s1拼接后的内容
		 
        // 比较字符串s1和s2
		// Andrew为常量字符串,多次出现时会被编译器优化,只创建一个对象
		System.out.println("s1和s2内存地址相同吗?" + (s1 == s2));
        
        //比较字符串s1和s3
		System.out.println("s1和s3内存地址相同吗?" + (s1 == s3));

		String s4 = "love " + s1;
         //比较字符串s4和s3
		// s1是变量,s4在运行时才知道具体值,所以s3和s4是不同的对象
		System.out.println("s3和s4内存地址相同吗?" + (s4 == s3));
	}
}

   3)String类的常用方法

        <1>  String 类提供了许多用来处理字符串的方法,例如,获取字符串长度、对字符串进行截取、将字符串转换为大写或小写、字符串 分割等。

String 类的常用方法:

结合代码来熟悉一下方法的使用:

package ex.class1;

import java.util.Arrays;

public class Ex2 {

	public static void main(String[] args) {
		String s1 = "And rew"; 
		//定义一个字符串"And rew"
		System.out.println("字符串长度:"+s1.length());
		//打印出字符串长度
		char c = 'd';
		System.out.println("字符‘d’的位置:"+s1.indexOf(c));
		
		System.out.println("字符‘And’的位置:"+s1.indexOf("And"));
		//查找字符串'And'的位置
		System.out.println("字符‘Sil’的位置"+s1.indexOf("Sil"));
		//查找字符串'Sil'的位置,如果找不到返回-1
		String[] arr = s1.split(" ");
		//按空格把字符串拆分成一个数组,并输出数组元素
		System.out.println("按空格拆分成数组:"+Arrays.toString(arr));
		System.out.println("获取位置[2,5)之间的字串:"+s1.substring(2,5));
		//获取索引[2,5)之间的字串
	}
}

ps:

1. 字符串 s1 中字符的索引从0开始,范围为 0 到 str.length()-1

2. 使用 indexOf 进行字符或字符串查找时,如果匹配返回位置索引;如果没有匹配结果,返回 -1

3. 使用 substring(beginIndex , endIndex) 进行字符串截取时,包括 beginIndex 位置的字符,不包括 endIndex 位置的字符

例题:判断 Java 文件名是否正确,判断邮箱格式是否正确。其中:合法的文件名应该以 .java 结尾;合法的邮箱名中至少要包含 “@” , 并要求 “@” 在 “.” 之前

package ex.class1;

public class Ex3 {

	public static void main(String[] args) {
	        // Java文件名
			String fileName = "HelloWorld.java"; 
	        // 邮箱
			String email = "[email protected]";
			
			// 判断.java文件名是否正确:合法的文件名应该以.java结尾
	        /*
	                         参考步骤:
	        1、获取文件名中最后一次出现"."号的位置
	        2、根据"."号的位置,获取文件的后缀
	        3、判断"."号位置及文件后缀名
	        */
	        //获取文件名中最后一次出现"."号的位置
			int index = fileName.lastIndexOf(".");
	        
	        // 获取文件的后缀
			String prefix = fileName.substring(index + 1, fileName.length());
	        
			// 判断必须包含"."号,且不能出现在首位,同时后缀名为"java"
			if (index != -1 && index !=0 && prefix.equals("java")) {
				System.out.println("Java文件名正确");
			} else {
				System.out.println("Java文件名无效");
			}

	        // 判断邮箱格式是否正确:合法的邮箱名中至少要包含"@", 并且"@"是在"."之前
	         /*
	                        参考步骤:
	        1、获取文件名中"@"符号的位置
	        2、获取邮箱中"."号的位置
	        3、判断必须包含"@"符号,且"@"必须在"."之前
	        */
		    // 获取邮箱中"@"符号的位置
			int index2 = email.indexOf('@');
	        // 获取邮箱中"."号的位置
			int index3 = email.indexOf('.');
	        
			// 判断必须包含"@"符号,且"@"必须在"."之前
			if (index2 != -1 && index3 > index2) {
				System.out.println("邮箱格式正确");
			} else {
				System.out.println("邮箱格式无效");
			}
	}
}

        <2> “==” 和 equals() 的区别

                ==: 判断两个字符串在内存中首地址是否相同,即判断是否是同一个字符串对象

                equals(): 比较存储在两个字符串对象中的内容是否一致

PS:字节是计算机存储信息的基本单位,1 个字节等于 8 位, gbk 编码中 1 个汉字字符存储需要 2 个字节,1 个英文字符存储需要 1 个字节。所以每个汉字对应两个字节值。同时,我们还发现汉字对应的字节值为负数,原因在于每个字节是 8 位,最大值不能超过 127,而汉字转换为字节后超过 127,如果超过就会溢出,以负数的形式显示。

例题:统计指定字符串中字符 ‘a’ 出现的次数

public class Ex4 {
	public static void main(String[] args) {
		// 定义一个字符串
		String s = "silvia love andrew and andrew love silvia too";
        
        // 出现次数
		int num = 0;
        
         // 循环遍历每个字符,判断是否是字符 a ,如果是,累加次数
		for (int i = 0 ; i< s.length(); i++)
		{
            // 获取每个字符,判断是否是字符a
			if (s.charAt(i) == 'a') {
                // 累加统计次数
				num++; 
			}
		}
		System.out.println("字符a出现的次数:" + num);
	}
}

   4)Java中的StringBuffer:线程安全的可变字符序列(线程安全--->同步---->执行效率低)

        StringBuffer(容器)和String的区别?

        前者是线程安全的类,可变的字符序列,内存中提供字符串缓冲区;后者是不可变的字符序列

        从内存角度考虑:前者优于后者:    String类型:在方法区中开辟空间--->占内存

        StringBuffer :里面存在初始容量,里面不断的追击字符串(append)


        StringBuffer的构造方法:

                 public StringBuffer()构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。 

                 public StringBuffer(int capacity):指定容量大小

                 public StringBuffer(String str):构造一个字符串缓冲区:里面的容量(字符串内容英文)大小:字符串长度+16初始容量

        获取功能:

                 public int capacity():初始容量

                 int length():返回字符串长度

例:

public class Ex5 {

	public static void main(String[] args) {
		StringBuffer sb = new StringBuffer();
		System.out.println(sb);
		System.out.println("length():"+sb.length());
		System.out.println("capacity():"+sb.capacity());
		
        System.out.println("--------------------------------");
		
		//public StringBuffer(int capacity):指定容量大小
		StringBuffer sb2 = new StringBuffer(50);
		System.out.println("length():"+sb2.length());
		System.out.println("capacity():"+sb2.capacity());
		
		System.out.println("--------------------------------");
		
		//StringBuffer类似于String类型的缓冲区
		StringBuffer sb3 = new StringBuffer("hello") ;
		System.out.println(sb3);
		System.out.println("length():"+sb3.length());
		System.out.println("capacity():"+sb3.capacity());
	}
}

        StringBuffer的添加功能:StringBuffer append(xxx x):将指定的内容追加(末尾追加)到字符串缓冲区中,返回StringBuffer本身

                                             public StringBuffer insert(int index,xxx x):在指定位置处,插入一个新的内容,返回StringBuffer本身

public static void main(String[] args) {
		
		//创建一个字符串缓冲区
		StringBuffer sb = new StringBuffer()	 ;
		System.out.println(sb);
				
		// 链式编程
		sb.append("Silvia").append(true).append('a').append(100).append(12.34) ;
		System.out.println("sb:"+sb);
		
		//public StringBuffer insert(int index,xxx x)
		sb.insert(5, "via") ;
		System.out.println("sb:"+sb);
        
}

        StringBuffer的删除功能:

                           StringBuffer deleteCharAt(int index)  :删除指定位置出的字符,返回字符串缓冲区本身

                           StringBuffer delete(int start, int end) :删除从指定位置开始到指定位置结束,返回值字符串缓冲区本身

public static void main(String[] args) {
		
		//创建字符串缓冲区
		StringBuffer sb = new StringBuffer() ;
		
		//添加内容
		sb.append("Silvia").append("Andrew") ;
		
		System.out.println(sb);
		
		//需求:要删除:e这个字符
		sb.deleteCharAt(1) ;
		System.out.println(sb);
		//需求:删除第一个l这个字符
		System.out.println(sb.deleteCharAt(1));
		
		//StringBuffer delete(int start, int end) 
		System.out.println(sb.delete(3, 5)); //包前不包后
}

        StringBuffer的替换功能:

                              public StringBuffer replace(int start,int end,String str)
                              从指定位置开始到指定位置结束,用给定的str字符串替换指定的字符内容

	public static void main(String[] args) {
		//构造一个字符串缓冲区
		StringBuffer sb = new StringBuffer() ;
		
		//追加
		sb.append("Silvia") ;
		sb.append(" Love ") ;
		sb.append("Andrew") ;
		
		System.out.println(sb);
		
		System.out.println(sb.replace(6, 11, " ☆  "));
	}

   

         StringBuffer的反转功能:

public static void main(String[] args) {
		
		StringBuffer s = new StringBuffer() ;
		
		s.append("我爱竹竹") ;
		System.out.println("s:"+s);
		
		s.reverse() ;
		System.out.println("s:"+s);
		
}

        StringBuffer的截取功能:

                       String substring(int start)  :从指定位置默认截取到末尾,返回一个新的字符串   

                       String substring(int start,int end):从指定位置开始截取到指定位置结束

	public static void main(String[] args) {		
		//创建缓冲区对象
		StringBuffer sb = new StringBuffer() ;
		sb.append("Silvia") ;
		sb.append("Love") ;
		sb.append("Andrew") ;						
		System.out.println(sb.substring(3, 8));
		System.out.println(sb);				
	}

        String与StringBuffer间的相互转换

public static void main(String[] args) {
		
		//String--->StringBuffer
		String s ="Silvia" ;
		StringBuffer sb  = new StringBuffer() ;
		sb.append(s) ;
		System.out.println(sb);
		
		System.out.println("-----------------------------");
		
		//StringBuffer--->String
		StringBuffer buffer = new StringBuffer("Andrew") ;
		// 方式1:String类型的构造方法   String(StringBuffer buffer) 
		//创建一个String
		String str = new String(buffer) ;
		System.out.println("str:"+str);
		
		//方式2:StringBuffer()里面toString():将StringBuffer--->String
		String str2 = buffer.toString() ;
		System.out.println("str2:"+str2);
		
}


   

例1:把数组拼接成一个字符串   int[] arr [11,22,33,44,55] 

       方法改进分别使用:String  和StringBuffer

public class Ex7 {

    public static void main(String[] args) {
		
		int[] arr = {11,22,33,44,55} ;
		
		//使用StringBuffer
		String result = arrayToString(arr) ;
		System.out.println("result:"+result);
	}
	
	public static String arrayToString(int[] arr) {
		//创建一个字符串缓冲区对象
		StringBuffer sb = new StringBuffer() ;
		
		//追加左中括号
		sb.append("[") ;
		//遍历数组
		for(int x = 0 ; x < arr.length ; x ++) {
			//判断是否最大值索引
			if(x==arr.length-1) {
				sb.append(arr[x]).append("]") ;
			}else {
				sb.append(arr[x]).append(", ") ;
			}
		}
		return sb.toString();
	}
}

例2:键盘录入字符串判断是否是对称字符串, 例如"abc"不是对称字符串,"aba"、"abba"、"aaa"、"mnanm"是对称字符串

         分析:
               1)键盘录入字符串
               2)字符数组
               3)拿0索引--->数组长度-1 ... ... ...  保证数组长度/2

public class Ex8 {

    public static void main(String[] args) {
		
		//创建键盘录入对象
		Scanner sc = new Scanner(System.in) ;
		
		//接收数据
		System.out.println("请输入一个字符串:");
		String line = sc.nextLine() ;
		
		boolean flag = isSame(line) ;
		System.out.println("flag:"+flag);
	}

StringBuffer的方法:

        public static boolean isSame2(String s) {
		
		//链式编程:
		//返回本身StringBuffer
		return new StringBuffer(s).reverse().toString().equals(s) ;
	}

传统方法:

    public static boolean isSame(String s) {
		//假设为true
		boolean flag = true ;
		//可以将字符串转换成字符数组
		char[] chs = s.toCharArray() ;
		//遍历数组
		for(int start = 0 , end = chs.length-1 ; start<=end ; start++,end--) {
			//判断
			if(chs[start]!=chs[end]) {
				//修改标记
				flag = false ;
				break ;
			}
		}
		return flag ;
		
	}

2. Java中的包装类:基本数据类型是不具备对象的特性的,比如基本类型不能调用方法、功能简单。为了让基本数据类型也具备对象的特性, Java 为每个基本数据类型都提供了一个包装类,这样我们就可以像操作对象那样来操作基本数据类型。 

    1)基本类型和包装类之间的对应关系:

                              

        包装类主要提供了两大类方法:

              1. 将本类型和其他基本类型进行转换的方法

              2. 将字符串和本类型及包装类互相转换的方法

        我们以 Integer 包装类为例,来看下包装类的特性。

        Integer 包装类的构造方法:

              

        Integer包装类的常用方法:

              

例:

    public static void main(String[] args) {
        
		// 定义int类型变量,值为86
		int score1 = 86; 
        
		// 创建Integer包装类对象,表示变量score1的值
		Integer score2=new Integer(score1);
        
		// 将Integer包装类转换为double类型
		double score3=score2.doubleValue();
        
		// 将Integer包装类转换为float类型
		float score4=score2.floatValue();
        
		// 将Integer包装类转换为int类型
		int score5 =score2.intValue();

		System.out.println("Integer包装类:" + score2);
		System.out.println("double类型:" + score3);
		System.out.println("float类型:" + score4);
		System.out.println("int类型:" + score5);
	}

    2)Java 中基本类型和包装类之间的转换

         基本类型和包装类之间经常需要互相转换,以 Integer 为例:

Integer a = new Integer(3);//定义Integer包装类对象,值为3
int b = a + 5; //将对象和基本类恶性进行运算

        在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更加轻松便利了。

        装箱:把基本类型转换成包装类,使其具有对象的性质,又可分为手动装箱和自动装箱  

int i = 10; //定义一个int基本类型值
Integer x = new Integer(i); //手动装箱
Integer y = i; //自动装箱

        拆箱:和装箱相反,把包装类对象转换成基本类型的值,又可分为手动拆箱和自动拆箱

Integer i = new Integer(8); //定义一个Integer包装类对象,值为8
Int m = i.intValue(); //手动拆箱为int类型
int n = i; //自动拆箱为int类型

例:

    public static void main(String[] args) {
        
        // 定义double类型变量
		double a = 91.5;
        
         // 手动装箱
		Double b = new Double(a);       
        
        // 自动装箱
		Double c = a;      

        System.out.println("装箱后的结果为:" + b + "和" + c);
        
        // 定义一个Double包装类对象,值为8
		Double d = new Double(87.0);
        
        // 手动拆箱
		double e = d.doubleValue();
        
        // 自动拆箱
		double f = d;
        
         System.out.println("拆箱后的结果为:" + e + "和" + f);
	}

    3)Java 中基本类型和字符串之间的转换    

         在程序开发中,我们经常需要在基本数据类型和字符串之间进行转换。

         其中,基本类型转换为字符串有三种方法:

             1. 使用包装类的 toString() 方法

             2. 使用String类的 valueOf() 方法

             3. 用一个空字符串加上基本类型,得到的就是基本类型数据对应的字符串  

//将基本类型转化为字符串
int a = 521;
String str1 = Integer.toString(a); //方法1
String str2 = String.valueOf(a); //方法2
String str3 = a + ""; //方法3

        将字符串转换成基本类型有两种方法:

            1. 调用包装类的 parseXxx 静态方法

            2. 调用包装类的 valueOf() 方法转换为基本类型的包装类,会自动拆箱

//将字符串类型转换为基本类型
String str = "521";
int a = Integer.parseInt(str); //方法1
int b = Integer.valueOf(str); //方法2

    4)使用Date和SimpleDateFormat类表示时间

         在程序开发中,经常需要处理日期和时间的相关数据,此时我们可以使用 java.util 包中的 Date 类。这个类最主要的作用就是获取当前时间,我们来看下 Date 类的使用:

Date d = new Date(); //使用默认的构造方法创建Date对象
System.out.println(d); //输出Date对象

使用 Date 类的默认的午餐构造方法创建出的对象就代表当前时间,我们可以直接输出 Date 对象显示当前的时间,显示的结果如下:

    其中,Thu 代表Thursday(星期四), Jun 代表August(八月), 02 代表 2 号, CST 代表 China Standard Time (中国标准时间,也就是北京时间,东八区)。

    从上面的输出结果中,我们发现,默认的时间格式不是很友好,与我们日常看到的日期格式不太一样,如果想要按指定的格式进行显示,如 2018-02-14 14:36:48 ,那该怎么做呢?

    此时就到了 java.text 包中的 SimpleDateFormat 类大显身手的时候了!!可以使用 SimpleDateFormat 来对日期时间进行格式化,如可以将日期转换为指定格式的文本,也可将文本转换为日期。

1. 使用 format() 方法将日期转换为指定格式的文本

//创建Date,表示当前时间
Date d = new Date();
//创建SimpleDateFormat对象,指定目标格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//调用format()方法,格式化时间,转换为制定格式字符串
String today = sdf.format(d);
//输出转换后字符串
System.out.printlin(today);

    代码中的 “yyyy-MM-dd HH:mm:ss” 为预定义字符串, yyyy 表示四位年, MM 表示两位月份, dd 表示两位日期, HH 表示小时(使用24小时制), mm 表示分钟, ss 表示秒,这样就指定了转换的目标格式,最后调用 format() 方法将时间转换为指定的格式的字符串。

运行结果: 2018-02-14 14:36:48    

2. 使用 parse() 方法将文本转换为日期

//创建日期格式的字符串
String day = "2018年08月02日 14:36:48"
//创建SimpleDateFormat对象,指定字符串格式
SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//调用format()方法,格式化时间,转换为制定格式字符串
Date date = df.parse(day);
//输出转换后时间
System.out.printlin("当前时间:"+day);

    代码中的 “yyyy年MM月dd日 HH:mm:ss” 指定了字符串的日期格式,调用 parse() 方法将文本转换为日期。

    运行结果: Thu Aug 02 14:36:48 CST

PS:

1、 调用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException ,因此需要进行异常处理

2、 使用 Date 类时需要导入 java.util 包,使用 SimpleDateFormat 时需要导入 java.text 包

    4)Calendar类的应用

       Date 类最主要的作用就是获得当前时间,同时这个类里面也具有设置时间以及一些其他的功能,但是由于本身设计的问题,这些方法却遭到众多批评,不建议使用,更推荐使用 Calendar 类进行时间和日期的处理。

       java.util.Calendar 类是一个抽象类,可以通过调用 getInstance() 静态方法获取一个 Calendar 对象,此对象已由当前日期时间初始化,即默认代表当前时间,如 Calendar c = Calendar.getInstance();

      那么如何使用 Calendar 获取年、月、日、时间等信息呢?我们来看下面的代码:   

import java.util.Calendar;

public class Ex11 {

	public static void main(String[] args) {
		
    Calendar c = Calendar.getInstance(); //创建Calendar对象
    int year = c.get(Calendar.YEAR); //获取年
    int month = c.get(Calendar.MONTH)+1; //获取月份,0表示1月
    int day = c.get(Calendar.DAY_OF_MONTH); //获取日期
    int hour = c.get(Calendar.HOUR_OF_DAY); //获取小时
    int minute = c.get(Calendar.MINUTE); //获取分钟
    int second = c.get(Calendar.SECOND); //获取秒
    System.out.println("当前时间:  "+year+"-"+month+"-"+day+"  "+hour+":"+minute+":"+second);
	}
}

    其中,调用 Calendar 类的 getInstance() 方法获取一个实例,然后通过调用 get() 方法获取日期时间信息,参数为需要获得的字段的值, Calendar.Year 等为 Calendar 类中定义的静态常量。

运行结果:    当前时间:  2018-8-2  15:0:5
 

    Calendar 类提供了 getTime() 方法,用来获取 Date 对象,完成 Calendar 和 Date 的转换,还可通过 getTimeInMillis() 方法,获取此 Calendar 的时间值,以毫秒为单位。如下所示:

import java.util.Calendar;

public class Ex11 {

    public static void main(String[] args) {
		
        Date d = c.getTime(); //将Calendar对象转换为Date对象
        Long time = c.getTimeInMillis(); //获取当前毫秒
        System.out.println("当前时间:  "+ d);
        System.out.println("当前毫秒数:  "+ time);
	}
}

运行结果:       当前时间:  Thu Aug 02 15:03:06 CST 2018
                     当前毫秒数:  1533193386182

    5)使用Math类操作数据

       Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如: Math.round();

       常用的方法:

            

例:

package ex.class2;

public class Ex12 {

	public static void main(String[] args) {
		double a = 15.38;
		int b = (int) a;
		System.out.println("强制类型转换:"+b);
		long c = Math.round(a);
		System.out.println("四舍五入:"+c);
		double d = Math.floor(a);
		System.out.println("floor:"+d); //调用floor方法,返回小于参数的最大整数
		double e = Math.ceil(a);
		System.out.println("ceil:"+e); //调用ceil方法,返回大于参数的最小整数
		double x = Math.random();
		System.out.println("随机数:"+x); //调用random方法,产生[0,1)之间的随机数浮点数
		int y = (int) (Math.random()*99); //产生[0,99)之间的随机数
		System.out.println("产生[0,99)之间的随机整数:"+ y);
		}
}

####END####

猜你喜欢

转载自blog.csdn.net/andrew0215/article/details/81353553
今日推荐