JAVA第七课:Eclipse常见使用与Java常用类

1. eclipse常见使用

1:基本使用
	A:选择一个工作空间
		D:\develop\eclipse-SDK-3.7.2-win64\workspace
	B:如何写一个HelloWorld案例(代码以项目为基本单位)
		a:创建项目(工程)
			File -- New -- Java Project
			在左边空白处,直接右键 -- New -- Java Project
			键入项目名称后直接Finish。
		b:所有的java文件必须写到src下面才有效
		c:创建一个包
			cn.test
		d:在包下创建一个类
			HelloWorld
			同时让它帮我们写好了main方法。
		e:在main方法中写内容即可
		f:编译程序
			自动编译,在保存的那一刻帮你做好了
		g:运行程序
			选择要运行的文件或者在要运行的文件内容中
			右键 -- Run as -- Java Application即可
		h:内容显示
			在Console控制台显示内容

2:Eclipse的基本设置
	A:程序的编译和运行的环境配置(如果你的Eclipse启动没有问题,就不要配置了)
	B:去掉默认注释(可以不用改)
	C:行号的显示和隐藏
		显示:在代码区域的最左边的空白区域,右键 -- Show Line Numbers即可。
		隐藏:把上面的动作再做一次。
	D:字体大小及颜色
		a:Java代码区域的字体大小和颜色:
			window -- Preferences -- General -- Appearance -->
			Colors And Fonts -- Java修改 -- Java Edit Text Font
		b:控制台
			window -- Preferences -- General -- Appearance -->
			Colors And Fonts -- Debug -- Console font
		c:其他文件
			window -- Preferences -- General -- Appearance -->
			Colors And Fonts -- Basic -- Text Font
	E:窗体给弄乱了,怎么办
		window -- Reset Perspective
	F:控制台找不到了
		Window--Show View—Console

3:快捷键的使用
	A:内容辅助键
		Alt+/ 起提示作用
		main+alt+/,syso+alt+/,给出其他提示
	B:快捷键
		格式化  ctrl+shift+f
		导入包  ctrl+shift+o
		注释	ctrl+/
			ctrl+shift+/,ctrl+shift+\
		代码上下移动 选中代码alt+上/下箭头
		查看源码  选中类名(F3或者Ctrl+鼠标点击)

4:Eclipse中如何提高开发效率
	A:自动生成构造方法
		a:无参构造方法 在代码区域右键--source--Generate Constructors from Superclass
		b:带参构造方法 在代码区域右键--source--Generate Constructors using fields.. -- finish
	B:自动生成get/set方法
		在代码区域右键--source--Generate Getters and Setters...

2. API等基础介绍

Java API在线参考手册 https://tool.oschina.net/apidocs/apidoc?api=jdk-zh

API(Application Programming Interface) 应用程序编程接口
常用类
Object类 / Scanner类
String类 / StringBuffer类 / StringBuilder类
数组高级和Arrays类
基本类型包装类(Integer , Character)
正则表达式(Pattern , Matcher)
Math类 / Random类 / System类
BigInteger类 / BigDecimal类
Date类 / DateFormat类 / Calendar类

3.Object类

(1)是类层次结构的根类,所有类都直接或者间接的继承自该类

(2)构造方法:	
	public Object()
	只有一个无参构造方法。
	这就可以帮助我们理解前面说过的:子类构造方法默认访问父类的无参构造方法

(3)成员方法:
Object类的成员方法
	public int hashCode():返回该对象的哈希码值。
	public final Class<?> getClass():返回此 Object 的运行时类。
	public String toString():返回该对象的字符串表示。
	public boolean equals(Object obj):比较对象是否相同。
	protected void finalize():被垃圾回收器对象调用,用于处理垃圾
	protected Object clone():克隆对象

详细讲解:
	public int hashCode()
		A:返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算。
		B:不同对象的,hashCode()一般来说不会相同。
		  但是,同一个对象的hashCode()值肯定相同。
		C:不是对象的实际地址值,可以理解为逻辑地址值。
			举例:物体和编号。	
	
	public final Class getClass()
		A:返回此 Object 的运行时类。
		B:可以通过Class类中的一个方法,获取对象的真实类的全名称。	
			public String getName()
	
	public String toString()
		A:返回该对象的字符串表示。
			底层源码。
			public static String valueOf(Object obj) {
       		    return (obj == null) ? "null" : obj.toString();
    		}
		B:它的值等于: 
			getClass().getName() + '@' + Integer.toHexString(hashCode()) 
		C:由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。
			a:手动重写
			b:自动生成
	
	public boolean equals(Object obj)
		A:指示其他某个对象是否与此对象“相等”。 
		B:默认情况下比较的是对象的引用是否相同。
		C:由于比较对象的引用没有意义,一般建议重写该方法。
			a:手动重写
			b:自动生成
		D:==和equals()的区别。(面试题)
	
	protected void finalize()
		A:当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
		B:垃圾回收器不会马上回收垃圾,但是我们可以建议它尽快回收垃圾。(System.gc()方法)
		C:主要针对堆内存。

	protected Object clone()
		创建并返回此对象的一个副本,这种克隆机制十分高效,而且二者之间完全隔离。
		自定义类实现克隆步骤:
			A:自定义类实现Cloneable接口,这是一个标记性接口,实现这个接口的类的对象可以实现自我克隆。
			B:自定义类中重写Object类的clone()方法。
			C:重写clone()方法时通过super.clone()调用Object类的clone()方法来得到该对象的副本,并返回该副本。

	注意:
		A:克隆和两个引用指向同一个对象的区别?
		B:Object类clone()方法虽然简单,易用,但仅仅是一种”浅克隆”,它只克隆该对象所有的Field值,不会
		  对引用类型的Field所引用的对象进行克隆。开发中,我们也可以实现对象的”深度克隆”。

(4)面试题:(掌握)
	==和equals()的区别?
	A:==
		基本类型:比较的是基本类型的值是否相同
		引用类型:比较的是引用类型的地址值是否相同
	B:equals()
		只能比较引用类型,默认比较的是对象的地址值是否相同。
		但是,可能被重写,一定要根据实际的情况来看。

3. Scanner类

概述:JDK5以后用于获取用户的键盘输入
构造方法:
	public Scanner(InputStream source)

如果数据间有空格,就应该把数据用""括起来。

Scanner类的成员方法
基本格式
	hasNextXxx()  
		判断是否还有下一个输入项,其中Xxx可以是Int,Double等。
		如果需要判断是否包含下一个字符串,则可以省略Xxx
	nextXxx()  
		获取下一个输入项。Xxx的含义和上个方法中的Xxx相同
	默认情况下,Scanner使用空格,回车等作为分隔符
常用方法
	public int nextInt()
	public String nextLine()
	
注意事项:
	先nextInt()然后nextLine()的问题。
解决方案:
	A:重新创建对象。
	B:都以字符串形式接收,然后把字符串转成int类型。
	Integer.parseInt(String s)将会返回int常量。
	Integer.valueOf(String s)将会返回Integer类型,如果存在缓存将会返回缓存中已有的对象。
import java.util.Scanner;

public class Test{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
//		int a = sc.nextInt();
		String a = sc.nextLine();	
		String b = sc.nextLine();
		
		System.out.println("String a = " + a);
		System.out.println("String b = " + b);

		int a_num = Integer.parseInt(a);
		int b_num = Integer.valueOf(b);

		System.out.println("int a = " + a_num);
		System.out.println("Integer b = " + b_num);
	}
}

4. String类

String类概述
	字符串是由多个字符组成的一串数据(字符序列)
	字符串可以看成是字符数组
构造方法
	public String():创建String对象
	public String(byte[] bytes):把字节数组转成字符串。
	public String(byte[] bytes,int offset,int length):把字节数组中的一部分转成字符串
	public String(char[] value):把字符数组转成字符串
	public String(char[] value,int offset,int count):把字符数组的一部分转成字符串
	public String(String original):把字符串转成字符串

Java没有内置的字符串类型,所以在Java类库中提供了一个类String 供我们来使用。
String 类代表字符串,Java 程序中的所有字符串字面值(如"abc")都作为此类的实例实现。

注意:
	String s = “helloworld”;
	s 也是一个对象。

String类的特点
	字符串是常量,它的值在创建之后不能更改
	String s = "hello";
	s += "world"; 
	问s的结果是多少? //helloworld
面试题
	String s = new String("hello");
	String s1 = "hello";
	s 和 s1的区别?
import java.util.Scanner;

public class Test{
	public static void main(String[] args) {

		String s1 = new String("hello");
		String s2 = new String("hello");
		String s3 = "hello";
		String s4 = "hello";
		String s5 = "world";
		String s6 = "helloworld";
		
		System.out.println(s1==s2);			//false
		System.out.println(s1.equals(s2));	//true

		System.out.println(s1==s3);			//false
		System.out.println(s1.equals(s3));	//true

		System.out.println(s3==s4);			//true
		System.out.println(s3.equals(s4));	//true
        
		System.out.println(s6==s4+s5);		 //false
		System.out.println(s6.equals(s4+s5));//true       
	}
}


​ String类的判断功能
​ boolean equals(Object obj):比较字符串的内容是否相同,严格区分大小写
​ boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,不考虑大小写
​ boolean contains(String str):判断是否包含指定的小串
​ boolean startsWith(String str):判断是否以指定的字符串开头
​ boolean endsWith(String str):判断是否以指定的字符串结尾
​ boolean isEmpty():判断字符串的内容是否为空

​ String类的获取功能
​ int length():返回字符串的长度。字符的个数。
​ char charAt(int index):返回字符串中指定位置的字符。
​ int indexOf(int ch):返回指定字符在字符串中第一次出现的位置
​ int indexOf(String str):返回指定字符串在字符串中第一次出现的位置
​ int indexOf(int ch,int fromIndex):返回指定字符从指定位置开始在字符串中第一次出现的位置
​ int indexOf(String str,int fromIndex):返回指定字符串从指定位置开始在字符串中第一次出现的位置
​ String substring(int start):返回从指定位置开始到末尾的子串
​ String substring(int start,int end):返回从指定位置开始到指定位置结束的子串----注意左包右不包
​ int lastIndexOf(int ch)
​ int lastIndexOf(int ch, int fromIndex)
​ int lastIndexOf(String str)
​ int lastIndexOf(String str, int fromIndex)

String类的转换功能
	byte[] getBytes():把字符串转换为字节数组
	char[] toCharArray():把字符串转换为字符数组
	static String valueOf(char[] chs):把字符数组转成字符串
	static String valueOf(int i):把int类型的数据转成字符串
	String toLowerCase():把字符串转小写
	String toUpperCase():把字符串转大写
	String concat(String str):字符串的连接
	
String类的其他功能
	替换功能
		String replace(char old,char new)
		String replace(String old,String new)
	去除字符串两空格	
		String trim()
	按字典顺序比较两个字符串  
		int compareTo(String str)
		int compareToIgnoreCase(String str) 

String,StringBuffer,StringBuilder的区别?
	A:String长度固定,StringBuffer和StringBuilder的长度可变。
	B:StringBuffer线程安全,效率低。StringBuilder线程不安全,效率高。

StringBuffer和数组的区别
	A:StringBuffer的长度可变,可以存储任意数据类型,最终结果其实是一个字符串。
	 B:数组长度固定,存储同一种数据类型的元素。

练习:
(1)遍历获取字符串中的每一个字符
(2)统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
(3)把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
(4)把数组中的数据按照指定个格式拼接成一个字符串
举例:int[] arr = {1,2,3};
输出结果:[1, 2, 3]
(5)字符串反转
举例:键盘录入”abc”
输出结果:”cba”
(6)统计大串中小串出现的次数
举例:在字符串"helloworldjavajavajavajavajava”中java出现了5次

(1)遍历获取字符串中的每一个字符

public class Test{
	public static void main(String[] args) {
		String str = "abcdefg";
		char[] arr = str.toCharArray();
		for(int i=0; i<arr.length; i++){
			System.out.print(arr[i]+" ");
		}    
	}
}

(2)统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。

public class Test{
	public static void main(String[] args) {
		String str = "ABCDabcde123456";
		int cap = 0 ;
		int low = 0;
		int num = 0;
		char[] arr = str.toCharArray();

		for(int i=0; i<arr.length; i++){
			if(arr[i]>='A' && arr[i]<='Z'){
				cap++;
			}else if(arr[i]>='a' && arr[i]<='z'){
				low++;
			}else if(arr[i]>='0' && arr[i]<='9'){
				num++;
			}
		}    
		System.out.println("cap = "+cap);
		System.out.println("low = "+low);
		System.out.println("num = "+num);
	}
}

(3)把一个字符串的首字母转成大写,其余为小写。

public class Test{
	public static void main(String[] args) {
		String str = "ABCDabcde123456";
		System.out.println("原字符串:"+str);
		char[] arr = str.toCharArray();
		str = "";
		//方式一
		System.out.print(" 方式一 :");
		for(int i=0; i<arr.length; i++){
			if(i==0){
				if(arr[i]>='a' && arr[i]<='z'){
					arr[i] -= 32;
				}
			}else{
				if(arr[i]>='A' && arr[i]<='Z'){
					arr[i] += 32;
				}
			}
			str += arr[i];
		}
		System.out.println(str);

		//方式二
		System.out.print(" 方式二 :");
		str = "ABCDabcde123456";
		String str_low = str.toLowerCase();
		char[] str_low_arr = str_low.toCharArray();
		str = "";
		if(str_low_arr[0]>='a' && str_low_arr[0]<='z'){
			str_low_arr[0] -= 32;
		}
		for(int i=0; i<str_low_arr.length; i++){
			str += str_low_arr[i];
		}
		System.out.println(str);
	}
}

(4)把数组中的数据按照指定个格式拼接成一个字符串

import java.util.Arrays;

public class Test{
	public static void main(String[] args) {
		int[] arr = {1,2,3,4,5,6};
		String str = Arrays.toString(arr);
		System.out.println(str);
	}
}

(5)字符串反转

import java.util.Arrays;

public class Test{
	public static void main(String[] args) {
		String str = "ABCDabcde123456";
		System.out.println(str);
		char[] arr = str.toCharArray();
		int length = arr.length;

		for(int i=0; i<length/2; i++){
			char temp = arr[i];
			arr[i] = arr[length-1-i];
			arr[length-1-i] = temp;
		}

		str = Arrays.toString(arr);
		System.out.println(str);

		str="";
		for(int i=0; i<length; i++){
			str += arr[i]; 
		}
		System.out.println(str);
	}
}

(6)统计大串中小串出现的次数

public class Test{
	public static void main(String[] args) {
		String maxStr = "hellojavajavajavajavajava";
		String minStr = "java";

		int count = getCount(maxStr,minStr);
		System.out.println(count);
	}

	public static int getCount(String maxStr,String minStr){
		int count = 0;
		int index;
		while((index=maxStr.indexOf(minStr))!=-1){
			count++;
			maxStr = maxStr.substring(index+minStr.length());
		}
		return count;
	}
}

5. StringBuffer类

我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间,而StringBuffer就可以解决这个问题,因为StringBuffer是线程安全的可变字符序列。

StringBuffer:线程安全的可变字符串。
通过查看API,我们知道了,它是可以改变内容和长度的

StringBuffer和String的区别?
  	A:StringBuffer的长度可变
	B:String的长度固定
构造方法
	StringBuffer(): 构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。
	StringBuffer(int capacity):构造一个不带字符,但具有指定初始容量的字符串缓冲区。
	StringBuffer(String str):构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。
  
成员方法:
  	public int length():返回长度(字符数)实际值
  	public int capacity():返回当前容量   理论值

StringBuffer类的成员方法
添加功能
	public StringBuffer append(String str):追加数据,往已有数据的后面。
	public StringBuffer insert(int offset,String str):插入数据,往指定位置添加数据。
删除功能
	public StringBuffer deleteCharAt(int index):删除指定位置的字符
	public StringBuffer delete(int start,int end):删除从指定位置开始到指定位置结束的内容
替换功能
	public StringBuffer replace(int start,int end,String str):用给定的字符串替换从指定位置开始到指定位置结束的数据
反转功能	 
	public StringBuffer reverse()

 截取功能:返回值类型是String类型,本身没有发生改变
	public String substring(int start):从指定位置开始到末尾
  	public String substring(int start,int end):从指定位置开始到指定位置结束
截取功能和前面几个功能的不同
返回值类型是String类型,本身没有发生改变

练习
(1)String和StringBuffer的相互转换
(2)把数组拼接成一个字符串
(3)把字符串反转
(4)判断一个字符串是否是对称字符串
例如"abc"不是对称字符串,“aba”、“abba”、“aaa”、"mnanm"是对称字符串

(1)String和StringBuffer的相互转换

String --> StringBuffer
方式一:构造方法
方式二:通过append方法
StringBuffer --> String
方式一:通过构造方法
方式二:通过toString方法

public class Test {
    public static void main(String[] args) {
        //String -> StringBuffer
        //创建一个String对象
        String str = "Hi Java!";
        System.out.println(str);

        //方式一:构造方法
        StringBuffer buffer = new StringBuffer(str);
        System.out.println(buffer);

        //方式二:通过append方法
        StringBuffer buffer2 = new StringBuffer();
        buffer2.append(str);
        System.out.println(buffer2);

        //StringBuffer -> String
        //创建一个StringBuffer对象
        StringBuffer buffer3 = new StringBuffer();
        buffer3.append("Happy birthday Java!");
        System.out.println(buffer3);

        //方式一:通过构造方法
        String str2 = new String(buffer3);
        System.out.println(str2);

        //方式二:通过toString方法
        String str3 = buffer3.toString();
        System.out.println(str3);
    }
}

(2)把数组拼接成一个字符串

public class Test {
	public static void main(String[] args) {
		int[] arr = {1,2,3,4,5,6};

		// 方式1:用String做拼接的方式
		String s1 = arrayToString(arr);
		System.out.println("s1:" + s1);

		// 方式2:用StringBuffer做拼接的方式
		String s2 = arrayToString2(arr);
		System.out.println("s2:" + s2);
	}

	// 用StringBuffer做拼接的方式
	public static String arrayToString2(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]);
			}else{
				sb.append(arr[x]).append(", ");
			}
		}
		sb.append("]");
		return sb.toString();
	}

	// 用String做拼接的方式
	public static String arrayToString(int[] arr) {
		String s = "";
		s += "[";
		for (int x = 0; x < arr.length; x++) {
			if (x == arr.length - 1) {
				s += arr[x];
			}else{
				s += arr[x];
				s += ", ";
			}
		}
		s += "]";
		return s;
	}
}

(3)把字符串反转

class Test{
	public static void main(String[] args) {
		String s = "abc123";

		for (int i = s.length() - 1; i >= 0; i--) {
			System.out.print(s.charAt(i));
		}

		System.out.println("变换前: " + s);
		System.out.println("变换后: " + reverse1(s));
		System.out.println("变换后: " + reverse2(s));
		System.out.println("变换后: " + reverse3(s));
	}

	//1.利用StringBuffer或StringBuilder的reverse
	public static String reverse1(String str) {
		return new StringBuilder(str).reverse().toString();
	}
	
	//2.利用String的toCharArray方法先将字符串转化为char类型数组,然后将各个字符进行重新拼接
	public static String reverse2(String str) {
		char[] chars = str.toCharArray();
		String reverse = "";
		for (int i = chars.length - 1; i >= 0; i--) {
			reverse += chars[i];
		}
		return reverse;
	}

	//3.利用String的CharAt方法取出字符串中的各个字符
	public static String reverse3(String str) {
		String reverse = "";
		int length = str.length();
		for (int i = 0; i < length; i++) {
			reverse = str.charAt(i) + reverse;
		}
		return reverse;
	}
}

(4)判断一个字符串是否是对称字符串

import java.util.Scanner;
 
public class Test {
	public static void main(String[] args) {
		String str = "1234554321";
		Scanner sc = new Scanner(System.in);
		str = sc.nextLine();
		for(int i=0; i<str.length()/2; i++){
			if(str.charAt(i) != str.charAt(str.length()-1-i)){
				System.out.println("不对称");
				return;
			}
		}
		System.out.println("对称");	
	}
}

面试
(1)通过查看API了解一下StringBuilder类
(2)String,StringBuffer,StringBuilder的区别
(3)StringBuffer和数组的区别

String,StringBuffer,StringBuilder主要区别在两个方面:运算速度(运算性能或执行效率)和线程安全性。

1、运算速度比较(通常情况下):StringBuilder > StringBuffer > String

String是final类不能被继承且为字符串常量,而StringBuilder和StringBuffer均为字符串变量。String对象一旦创建便不可更改,而后两者是可更改的,它们只能通过构造函数来建立对象,且对象被建立以后将在内存中分配内存空间,并初始保存一个null,通过append方法向StringBuffer和StringBuilder中赋值。

请看如下示例代码:

String str = “abc”;
System.out.println(str);
str = str + “de”;
System.out.println(str);

上述代码先创建一个String对象str,并赋值abc给str,然后运行到第三行,JVM会再创建一个新的str对象,并将原有str的值和de加起来再赋值给新的str。而第一个创建的str对象被JVM的垃圾回收机制(GC)回收掉。所以str实际上并没有被更改,即String对象一旦创建就不可更改。所以Java中对String对象进行的操作实际上是一个不断创建并回收对象的过程,因此在运行速度上很慢。

而StringBuilder和StringBuffer的对象是变量,对变量的操作是直接对该对象就行更改,因此不会进行反复的创建和回收。所以在运行速度上比较快。

String str = “abc” + “de”;
StringBuilder stringBuilder = new StringBuilder().append(“abc”).append(“de”);
System.out.println(str);
System.out.println(stringBuilder.toString());

上述代码中String的操作速度反而要比StringBuilder快,这是因为在JVM眼里,第1行的代码操作和下列代码是完全一样的,所以很快。

String str = “abcde”;

但如下的代码写法形式速度会很慢,JVM会不断地创建和回收对象来进行操作。

String str1 = “abc”;
String str2 = “de”;
String str = str1 + str2;

  1. 线程安全性

StringBuilder(非线程安全)

而StringBuilder的方法没有该关键字修饰,所以不能保证线程安全性。是JDK1.5新增的,该类提供一个与StringBuffer兼容的 API,但不能保证同步,所以在性能上较高。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

StringBuffer(线程安全的)

StringBuffer中大部分方法由synchronized关键字修饰,在必要时可对方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致,所以是线程安全的。类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

  1. 总结

String:适用于少量的字符串操作。

StringBuilder:适用于单线程下在字符串缓冲区进行大量操作。

StringBuffer:适用于多线程下在字符串缓冲区进行大量操作。

6. 数组高级(排序和查找)

排序
冒泡排序:相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
选择排序:从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处

查找
基本查找:对数组元素顺序无要求
二分查找:要求数组元素有序

练习:把字符串中的字符进行排序。
举例:“dacgebf”
结果:“abcdefg”

import java.util.Arrays;

class Test{
	public static void main(String[] args) {
		String str = "dabcefg";
		System.out.println("原字符串:"+str);
		
		//方式一
		char[] str_char = str.toCharArray();
		str_char = bubbleSort(str_char,0,str_char.length);
		str = "";
		for(int i=0;i<str_char.length;i++)
			str += str_char[i];
		System.out.println(str);

		//方式二
		str = "dabcefg";
		str = bubbleSort(str,0,str.length());
		System.out.println(str);

		//二分查找:数据已经排好序
		str = "dabcefg";
		str = bubbleSort(str,0,str.length());
		char s = 'b';
		int index = BinSearch(str,s);
		System.out.println(index);
	}

	//冒泡排序
	public static String bubbleSort(String str, int a, int b){
		char[] arr = str.toCharArray();
		for(int i=a; i<b; i++){
			for(int j=a; j<b-1-i; j++){
				if(arr[j] > arr[j+1]){
					char temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		return String.valueOf(arr);
	}

	//冒泡排序
	public static char[] bubbleSort(char[] arr, int a, int b){
		for(int i=a; i<b; i++){
			for(int j=a; j<b-1-i; j++){
				if(arr[j] > arr[j+1]){
					char temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		return arr;
	}

	//冒泡排序
	public static int[] bubbleSort(int[] arr, int a, int b){
		for(int i=a; i<b; i++){
			for(int j=a; j<b-1-i; j++){
				if(arr[j] > arr[j+1]){
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		return arr;
	}

	//选择排序
	public static int[] selectSort(int[] arr, int a, int b){
		for(int i=a; i<b; i++){
			for(int j=i+1; j<b; j++){
				if(arr[i] > arr[j]){
					int temp = arr[i];
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}
		}
		return arr;
	}

	//二分查找: str是已经排序好的
	public static int BinSearch(String str, int a){
		char[] arr = str.toCharArray();
		int low = 0;
		int hight = arr.length;
		int mid = 0;
		
		while(low <= hight){
			mid = (low+hight)/2;
			if(a < arr[mid]){
				hight = mid-1;
			}else if(a > arr[mid]){
				low = mid+1;
			}else{
				return mid;
			}
		}
		return 0;
	}

	//二分查找: arr是已经排序好的
	public static int BinSearch(int[] arr, int a){
		int low = 0;
		int hight = arr.length;
		int mid = 0;
		
		while(low <= hight){
			mid = (low+hight)/2;
			if(a < arr[mid]){
				hight = mid-1;
			}else if(a > arr[mid]){
				low = mid+1;
			}else{
				return mid;
			}
		}
		return 0;
	}
	
	// 普通查找
	 public static int getIndex(int[] arr, int value) {
		 int index = -1;	
		 for (int x = 0; x < arr.length; x++) {
			 if (arr[x] == value) {
				index = x;
				break;
			 }
		 }
		 return index;
	 }
}

7. Arrays类

Arrays类:针对数组进行操作的工具类,提供了排序,查找等功能。
成员方法
public static String toString(int[] a):把数组转成字符串
public static void sort(int[] a):排序(快速排序)
public static int binarySearch(int[] a,int key):二分查找

基本类型包装类
将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
常用的操作之一:用于基本数据类型与字符串之间的转换。

基本类型和包装类的对应:Byte,Short,Integer,Long,Float,Double,Character,Boolean

8. Integer类

Integer 类在对象中包装了一个基本类型 int 的值
该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法

构造方法
	Integer(int value): 把int类型的值包装成Integer类型
	Integer(String s) : 把数字类型的字符串转换成Integer类型

Integer类成员方法
	int类型和String类型的相互转换
	int --> String
		String.valueOf(int number)
		Integer.toString(int number)
	String --> int
		Integer.parseInt(String str);
	
	public int intValue()
	public static int parseInt(String s)
	public static String toString(int i)
	public static Integer valueOf(int i)
	public static Integer valueOf(String s)

常用的基本进制转换
	public static String toBinaryString(int i)
	public static String toOctalString(int i)
	public static String toHexString(int i)
十进制到其他进制
	public static String toString(int i,int radix)
		i 	 : 数字
		radix:进制
其他进制到十进制
	public static int parseInt(String s,int radix)

提问并测试:Java程序中的进制范围
	2-36

JDK5的新特性:
	自动装箱:int --> Integer
		底层方法:public static Integer valueOf(int i)
	自动拆箱:Integer --> int
		底层方法:public int intValue()
注意:
	在使用时,Integer  x = null;
	上面的代码就会出现NullPointerException,
开发原则:只要是对象,做操作,肯定先判断对象是否为null,如果不为null,才继续操作。

基本类型包装类
	byte		Byte
	short		Short
	int			Integer
	long		Long
	float		Float
	double		Double
	char		Character
	boolean		Boolean
特殊: void		Void
  • demo
import java.util.Arrays;

class Test{
	public static void main(String[] args) {
		// public static String toString(int i,int radix):
		// 通过简单的测试,我们知道了进制的范围是2-36
		System.out.println(Integer.toString(100, 2));
		System.out.println(Integer.toString(100, 8));
		System.out.println(Integer.toString(100, 16));
		System.out.println(Integer.toString(100, 1));
		System.out.println(Integer.toString(100, 100));
		System.out.println(Integer.toString(100, 50));
		System.out.println(Integer.toString(100, 25));
		System.out.println(Integer.toString(100, 37));
		System.out.println(Integer.toString(100, 32));
		System.out.println(Integer.toString(100, 35));
		System.out.println(Integer.toString(100, 36));
		System.out.println(Integer.toString(100, 7));
		System.out.println("----------------------");

		// 其他进制到十进制
		// public static int parseInt(String s,int radix)
		System.out.println(Integer.parseInt("100", 2));
		System.out.println(Integer.parseInt("100", 8));
		System.out.println(Integer.parseInt("100", 16));
		System.out.println(Integer.parseInt("300", 12));
	}
}

面试题目
Integer i = 1;
i += 1;
做了哪些事情
缓冲池(看程序写结果)
通过查看源码知道为什么

(1)代码解释

  1. Integer i = 1;
    这行代码声明了一个Integer类型的变量i,并通过自动装箱(autoboxing)机制将其初始化为整数值1对应的Integer对象。
    在Java中,当我们将一个基本数据类型(如int)赋值给其对应的包装类(如Integer)的变量时,Java会自动进行装箱操作,即调用Integer.valueOf(int)方法。
    对于-128到127之间的整数,Integer.valueOf(int)会返回一个缓存的Integer对象,以避免频繁创建和销毁小整数对象。但在这个例子中,虽然值是1,但关键点在于下一步的操作。
  2. i += 1;
    这行代码实际上是一个复合赋值操作,等同于i = i + 1;。
    因为i是一个Integer对象,这里会先执行i.intValue() + 1(即拆箱操作,将Integer对象转换为int基本类型),然后得到的结果(2)会再次通过自动装箱变为Integer对象,并赋值给i。
    由于2不在缓存范围内(即-128到127),这次自动装箱操作会创建一个新的Integer对象。
    问题扩展:2不在缓存范围内(即-128到127)?
    在Java的Integer类的缓存实现中,通常默认会缓存-128到127(包括这两个端点值)之间的整数。这个范围是基于性能和内存使用之间的权衡而选择的。对于这个范围内的整数,当你调用Integer.valueOf(int)或进行自动装箱(autoboxing)时,Java会返回缓存中的对象实例,而不是创建一个新的Integer对象。
    然而,当你尝试获取这个范围之外的整数(如2,虽然它本身是一个很小的正整数,但不在默认的缓存范围内)时,Java会创建一个新的Integer对象。这是因为缓存的目的是为了优化那些频繁出现的小整数的使用,而不是为了缓存所有可能的整数值。缓存所有整数会消耗大量的内存,并且对于大多数应用来说是不必要的。
    因此,尽管2是一个很小的正整数,但它并不在Java Integer类的默认缓存范围内。这意味着当你写Integer i = 2;时,Java会创建一个新的Integer对象来表示这个值,而不是从缓存中返回。
    需要注意的是,这个缓存范围是可以通过JVM参数-XX:AutoBoxCacheMax来调整的,但这通常只在特定性能敏感的应用中才需要这样做。默认情况下,你应该依赖Java的默认缓存行为

(2)缓冲池(Integer Cache)与通过查看源码了解原因

  1. Integer Cache 解释
    Java中的Integer类为了性能优化,维护了一个内部缓存,用于存储-128到127(包括两端)之间的Integer对象。
    当我们调用Integer.valueOf(int)或自动装箱时,如果值在这个范围内,就会返回缓存中的对象,而不是创建一个新的。这种做法可以减少内存占用和垃圾回收的频率,从而提高性能。
  2. 查看Integer类中的缓存实现,我们可以直接查看Java的官方源码。以下是Integer.valueOf(int i)方法的相关部分:
public static Integer valueOf(int i) {  
     if (i >= IntegerCache.low && i <= IntegerCache.high)  
        return IntegerCache.cache[i + (-IntegerCache.low)];  
    return new Integer(i); 
}

这里引用了IntegerCache类,它是一个静态内部类,定义了缓存的范围和存储结构。通常,缓存的范围是-128到127,但也可以通过JVM参数-XX:AutoBoxCacheMax来修改这个范围。
IntegerCache.cache是一个数组,用于存储缓存的Integer对象。当valueOf方法被调用时,它首先检查请求的值是否在缓存范围内,如果是,则直接返回缓存中的对象;否则,创建一个新的Integer对象并返回。

看以下程序写答案

import java.util.Arrays;

class Test{
	public static void main(String[] args) {
		
		Integer i1 = new Integer(127);
		Integer i2 = new Integer(127);
		System.out.println(i1 == i2);		//false
		System.out.println(i1.equals(i2));	//true
		
		Integer i3 = new Integer(128);
		Integer i4 = new Integer(128);
		System.out.println(i3 == i4);		//false
		System.out.println(i3.equals(i4));	//true
		
		Integer i5 = 127;
		Integer i6 = 127;
		System.out.println(i5 == i6);		//true
		System.out.println(i5.equals(i6));	//true
			
		Integer i7 = 128;
		Integer i8 = 128;
		System.out.println(i7 == i8);		//false 《== 注意点
		System.out.println(i7.equals(i8));	//true
		
		// 要想知道为什么,就必须看源码。
		// public static Integer valueOf(int i)
		//char ch = 127;
		//Integer i = Integer.valueOf(ch);
		// 通过查看源码我们知道如果数据在-128到127之间,是从一个缓存数组中返回的。
		// 如果不在这个范围内,就是重新创建的new出来的对象。
	}
}

9. Character类

Character 类在对象中包装一个基本类型 char 的值
此外,该类提供了几种方法,以确定字符的类别(小写字母,数字,等等),并将字符从大写转换成小写,反之亦然

构造方法
  public Character(char value)
	
Character类成员方法
  public static boolean isUpperCase(char ch):判断该字符是否是大写字母
  public static boolean isLowerCase(char ch):判断该字符是否是小写字母
  public static boolean isDigit(char ch):判断该字符是否是数字
  public static char toUpperCase(char ch):将该字符改写为大写字母
  public static char toLowerCase(char ch):将该字符改写为小写字母
  • demo
import java.util.Arrays;

class Test{
	public static void main(String[] args) {
		// public static boolean isUpperCase(char ch)
		System.out.println(Character.isUpperCase('a'));	//false
		System.out.println(Character.isUpperCase('A'));	//true
		System.out.println(Character.isUpperCase('0'));	//false
		// public static boolean isLowerCase(char ch)
		System.out.println(Character.isLowerCase('a'));	//true
		System.out.println(Character.isLowerCase('A'));	//false
		System.out.println(Character.isLowerCase('0'));	//false
		// public static boolean isDigit(char ch)
		System.out.println(Character.isDigit('a'));		//false
		System.out.println(Character.isDigit('A'));		//false
		System.out.println(Character.isDigit('0'));		//true
		// public static char toUpperCase(char ch)
		System.out.println(Character.toUpperCase('a'));	//A
		System.out.println(Character.toUpperCase('A'));	//A
		// public static char toLowerCase(char ch)
		System.out.println(Character.toLowerCase('a'));	//a
		System.out.println(Character.toLowerCase('A'));	//a
	}
}

10. Math类

Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
Math是用于数学操作的类。方法都是静态的

成员方法
  public static int abs(int a):绝对值
  public static double ceil(double a):大于等于参数的最小整数值
  public static double floor(double a):小于等于参数的最大整数值
  public static int max(int a,int b)	/ min
  public static double pow(double a,double b)
  public static double random() //  生成 [0,1) 的小数
  public static int round(float a) 	/ double
  public static double sqrt(double a):正平方根
  • 获取随机数:1-100之间
int number = (int)(Math.random()*100)+1;
  • 获取随机数:start到end之间
public static int getRandom(int start, int end) {
    return (int) (Math.random() * (end - start + 1)) + start;
}

11. Random类

Random类用于产生随机数
如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。

构造方法
  public Random():有默认种子
  public Random(long seed):指定种子
	
Random类成员方法
  public int nextInt():int范围内的数据
  public int nextInt(int n):[0,n)的数据

12. System类

System 类包含一些有用的类字段和方法。它不能被实例化。

成员方法
	public static void gc():运行垃圾回收器。 
	public static void exit(int status):终止当前正在运行的 Java 虚拟机。
	参数用作状态码;根据惯例,非 0 的状态码表示异常终止。
	
	public static long currentTimeMillis():返回以毫秒为单位的当前时间
	public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

System.gc()可用于垃圾回收。
当使用System.gc()回收某个对象所占用的内存之前,通过要求程序调用适当的方法来清理资源。在没有明确指定资源清理的情况下,Java提高了默认机制来清理该对象的资源,就是调用Object类的finalize()方法。

finalize()方法的作用是释放一个对象占用的内存空间时,会被JVM调用。而子类重写该方法,就可以清理对象占用的资源,该方法有没有链式调用,所以必须手动实现。

从程序的运行结果可以发现,执行System.gc()前,系统会自动调用finalize()方法清除对象占有的资源,通过super.finalize()方式可以实现从下到上的finalize()方法的调用,即先释放自己的资源,再去释放父类的资源。
但是,不要在程序中频繁的调用垃圾回收,因为每一次执行垃圾回收,jvm都会强制启动垃圾回收器运行,这会耗费更多的系统资源,会与正常的Java程序运行争抢资源,只有在执行大量的对象的释放,才调用垃圾回收最好

public class Test4 {
//	public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
//  System.arraycopy(拷贝数组, 起点, 目标数组, 起点, 拷贝数量);
	public static void main(String[] args) {
		int[] a = {1,2,3};
		for(int i=0; i<a.length; i++)
			System.out.print(a[i] + " ");
		System.out.println();
		
		int [] b = new int[10];
		System.arraycopy(a, 0, b, 1, a.length);
		
		for(int i=0; i<b.length; i++)
			System.out.print(b[i] + " ");
		System.out.println();
	}
}

13. BigInteger & BigDecimal类

概述
	可以让超过Integer范围内的数据进行运算
构造方法
	public BigInteger(String val)

BigInteger类成员方法
	public BigInteger add(BigInteger val)
	public BigInteger subtract(BigInteger val)
	public BigInteger multiply(BigInteger val)
	public BigInteger divide(BigInteger val)
	public BigInteger remainder(BigInteger val)
	public BigInteger[] divideAndRemainder(BigInteger val)
  • demo
import java.math.BigInteger;

public class App {
    public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE); // 2147483647

        // Integer x = new Integer("2147483648"); // NumberFormatException
        // System.out.println(x);
        // new Integer("2147483648"); JDK9中弃用,待删除
        Integer x = (1 << 31); // 推荐
        System.out.println(x);

        BigInteger a = new BigInteger("2147483648");
        BigInteger b = new BigInteger("1234");
        BigInteger c = a.add(b);
        System.out.println(a + "+" + b + "=" + c);

        c = a.subtract(b);
        System.out.println(a + "-" + b + "=" + c);

        c = a.multiply(b);
        System.out.println(a + "*" + b + "=" + c);

        c = a.divide(b);
        System.out.println(a + "/" + b + "=" + c);

        c = a.remainder(b);
        System.out.println(a + "%" + b + "=" + c);
        BigInteger[] d = a.divideAndRemainder(b);
        System.out.println(d[0] + " " + d[1]);
    }
}

由于在运算的时候,float类型和double很容易丢失精度,为了能精确的表示、计算浮点数,Java提供了BigDecimal 类。
public BigDecimal(String val)

import java.math.BigDecimal;

public class Test {
	public static void main(String[] args) {
		// System.out.println(0.09 + 0.01); // 0.1
		// System.out.println(1.0 - 0.32); // 0.68
		// System.out.println(1.015 * 100); // 101.5
		// System.out.println(1.301 / 100);// 0.01301

		// public BigDecimal add(BigDecimal augend)
		BigDecimal bd1 = new BigDecimal("0.09");
		BigDecimal bd2 = new BigDecimal("0.01");
		System.out.println("add:" + bd1.add(bd2));

		// public BigDecimal subtract(BigDecimal subtrahend)
		BigDecimal bd3 = new BigDecimal("1.0");
		BigDecimal bd4 = new BigDecimal("0.32");
		System.out.println("subtract:" + bd3.subtract(bd4));

		// public BigDecimal multiply(BigDecimal multiplicand)
		BigDecimal bd5 = new BigDecimal("1.015");
		BigDecimal bd6 = new BigDecimal("100");
		System.out.println("subtract:" + bd5.multiply(bd6));

		// public BigDecimal divide(BigDecimal divisor)
		BigDecimal bd7 = new BigDecimal("1.301");
		BigDecimal bd8 = new BigDecimal("100");
		System.out.println("divide:" + bd7.divide(bd8));
		// public BigDecimal divide(BigDecimal divisor,int scale,
		// int roundingMode)
		System.out.println(bd7.divide(bd8, 2, BigDecimal.ROUND_HALF_UP));
		System.out.println(bd7.divide(bd8, 3, BigDecimal.ROUND_HALF_UP));
		System.out.println(bd7.divide(bd8, 4, BigDecimal.ROUND_HALF_UP));
	}
}

14. Date & DateFormat类

类 Date 表示特定的瞬间,精确到毫秒。

构造方法
	public Date():默认就是当前时间
	public Date(long date):把给定的毫秒值赋值给日期对象
成员方法
	public long getTime():获取毫秒值
	public void setTime(long time):把毫秒值作为参数传递

DateFormat类
DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。
是抽象类,所以使用其子类SimpleDateFormat

SimpleDateFormat构造方法
	public SimpleDateFormat()
	public SimpleDateFormat(String pattern)
成员方法
	public final String format(Date date)
	public Date parse(String source)
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * DateFormat:是针对日期进行格式化和解析的抽象类。
 * 所以,我们学习其子类并使用。
 * SimpleDateForamt:
 * 格式化(日期 -> 文本)
 * 		Date	--	String
 * 				public final String format(Date date)
 * 				模式对象你想要什么就写什么。
 * 解析(文本 -> 日期)
 * 		String 	-- 	Date
 * 				public Date parse(String source)
 * 				模式对象必须和给定的字符串匹配。
 */
public class Test {
	public static void main(String[] args) throws ParseException {
		// Date -- String
		Date d = new Date();
		// public SimpleDateFormat()
		// SimpleDateFormat sdf = new SimpleDateFormat();
		// SimpleDateFormat(String pattern)
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		// public final String format(Date date)
		String result = sdf.format(d);
		System.out.println(result);
		System.out.println("-------------------------------------------------");

		String s = "2008-08-08 12:23:34";
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// public Date parse(String source)
		Date dd = sdf2.parse(s);
		System.out.println(dd);
	}
}

Date类及DateFormat类练习
制作一个工具类。DateUtil
(1)算一下你来到这个世界多少天?
(2)将你的出生日和今天都封装到字符串里
(3)将字符串转换成日期对象
(4)将日期对象转换成毫秒值
(5)让今天的毫秒值减去你出生那天的毫秒值
(6)将毫秒值转换成天数

15. Calendar类

Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等

日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

成员方法
	public static Calendar getInstance():由当前日期和时间初始化
	public int get(int field):返回给定日历字段的值。
	public void add(int field,int amount):根据给定的日历自动和值,改变时间
	public final void set(int year,int month,int date):设置年月日

import java.util.Calendar;

/*
 * Calendar:把时间分割成了一个个的年,月,日,时,分,秒等。
 * 如果我要得到一个完整的年月日时分秒,需要我们自己拼数据。
 * 日历对象	---	年,月,日,时,分,秒
 * public int get(int field):返回给定日历字段的值。
 */
public class CalendarDemo {
	public static void main(String[] args) {
		// 创建对象
		// 日历字段已由当前日期和时间初始化:
		Calendar rightNow = Calendar.getInstance(); // 多态

		// 获取年
		int year = rightNow.get(Calendar.YEAR);
		System.out.println(year);
		// 获取月
		int month = rightNow.get(Calendar.MONTH);
		System.out.println(month + 1);
		// 获取日
		int date = rightNow.get(Calendar.DATE);
		System.out.println(date);
		// 获取时
		int hour = rightNow.get(Calendar.HOUR);
		System.out.println(hour);
		// 获取分
		int minute = rightNow.get(Calendar.MINUTE);
		System.out.println(minute);
		// 获取秒
		int second = rightNow.get(Calendar.SECOND);
		System.out.println(second);
	}
}

练习
(1)算一下你来到这个世界多少天?
(2)获取任意一年的二月有多少天

16. 正则表达式

在Java中,正则表达式(Regular Expression,简称regex或regexp)是用于匹配、查找和替换字符串中字符序列的强大工具。正则表达式的组成规则主要包括以下几个方面:

  1. 元字符:
    .:匹配除换行符之外的任何单个字符。
    ^:匹配输入字符串的开始位置。
    $:匹配输入字符串的结束位置。
    *:匹配前面的子表达式零次或多次。
    +:匹配前面的子表达式一次或多次。
    ?:匹配前面的子表达式零次或一次。
    {n}:n 是一个非负整数。匹配确定的 n 次。
    {n,}:n 是一个非负整数。至少匹配n 次。
    {n,m}:m 和 n 均为非负整数,其中n≤m。最少匹配 n 次且最多匹配 m 次。
    ?:当该字符紧跟在任何一个其他限制符(*, +, ?, {n}, {n,}, {n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
    \:转义字符,用于转义其他字符或元字符。
  2. 字符类:
    [abc]:匹配方括号中的任意字符。
    [^abc]:匹配任何不在方括号中的字符。
    [a-z]:匹配任何一个小写字母。
    [A-Z]:匹配任何一个大写字母。
    [0-9]:匹配任何一个数字。
    [a-zA-Z0-9]:匹配任何字母或数字。
    \d:匹配一个数字字符。等价于 [0-9]
    \D:匹配一个非数字字符。等价于 [^0-9]
    \s:匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
    \S:匹配任何非空白字符。等价于[^ \f\n\r\t\v]
    \w:匹配包括下划线的任何单词字符。等价于[A-Za-z0-9_]
    \W:匹配任何非单词字符。等价于 [^A-Za-z0-9_]
  3. 边界匹配符:
    ^$:分别匹配字符串的开始和结束位置。
    \b:匹配一个单词边界,即字与空格间的位置。
    \B:非单词边界匹配。
  4. 分组与捕获:
    (...):将多个字符当作一个整体进行匹配,同时可以捕获匹配的文本。
    (?:...):非捕获分组,只进行匹配而不捕获文本。
    (?=...):正向前瞻断言,表示某个字符串之后应该匹配指定的内容。
    (?!...):负向前瞻断言,表示某个字符串之后不应该匹配指定的内容。
  5. 选择符:
    |:或,表示匹配多个模式中的一个。
  6. 反斜杠:
    在正则表达式中,许多字符都有特殊含义。如果要在正则表达式中匹配这些字符,需要使用反斜杠进行转义。例如,要匹配字符串中的 \.,正则表达式应写为 \\.。

正则表达式:是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字
符串。
其实就是一种规则,有自己特殊的应用。

举例:校验qq号码.

  1. 要求必须是5-15位数字
  2. 0不能开头

正则表达式的组成规则字符在java.util.regex Pattern类中

常见组成规则
1. 字符
	x 字符x
	\\ 反斜线字符
	\n 换行符
	\r 回车符
2. 字符类
	[abc] a、b 或 c
	[^abc] 任何字符,除了 a、b 或 c
	[a-zA-Z] a到 z或 A到 Z,两头的字母包括在内 
	[0-9] 包括数字字符0-9
3. 预定义字符类
	. 任何字符
	\d 数字:[0-9]
	\w 单词字符:[a-zA-Z_0-9]
4. 边界匹配器
	^ 行的开头 
	$ 行的结尾 
	\b 单词边界(不能是单词字符)
		hello?hao are you.
5. 数量词
	X? X,一次或一次也没有 
	X* X,零次或多次 
	X+ X,一次或多次 
	X{n} X,恰好 n 次 
	X{n,} X,至少 n 次 
	X{n,m} X,至少 n 次,但是不超过 m 次 
	
正则表达式的应用
	判断功能:public boolean matches(String regex)
	分割功能:public String[] split(String regex)
	替换功能:public String replaceAll(String regex,String replacement)
	获取功能:Pattern和Matcher类的使用
	
	判断功能:校验电话号码
	分割功能:	
		aa,bb,cc
		aa.bb.cc
		aa bb cc
		文件路径
	替换功能:
		把数用*替换
	获取功能:
		da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?

练习
(1)判断功能:校验邮箱
(2)分割功能:
有一个字符串:“91 27 46 38 50”
请写代码实现最终输出结果是:“27 38 46 50 91”
(3)替换功能:论坛中不能出现数字字符,用*替换
(4)获取功能:获取由三个字符组成的单词

(1)判断功能:校验邮箱

import java.util.Scanner;

/*
 * 校验邮箱
 * 
 * liuyi@163.com
 * linqingxia@126.com
 * 123456@qq.com
 * zhangsan123@sina.cn
 * zhang456@sina.com.cn
 * fqy@itcast.cn
 */
public class Test {
	public static void main(String[] args) {
		//定义规则
		//String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,8}(\\.[a-z]{2,3})+";
		String regex = "\\w+@\\w{2,8}(\\.[a-z]{2,3})+";
		
		//键盘录入邮箱
		Scanner sc=  new Scanner(System.in);
		System.out.println("请输入邮箱:");
		String email = sc.nextLine();
		
		//校验
		boolean flag = email.matches(regex);
		System.out.println(flag);
	}
}

(2)分割功能:
有一个字符串:“91 27 46 38 50”
请写代码实现最终输出结果是:“27 38 46 50 91”

import java.util.Arrays;

/*
 * 我有如下一个字符串:"91 27 46 38 50"
 * 请写代码实现最终输出结果是:"27 38 46 50 91"
 * 
 * 分析:
 * 		A:定义一个字符串
 * 		B:按照空格进行分割字符串,得到一个字符串数组
 * 		C:把字符串数组转换为整数数组
 * 		D:对整数数组进行排序
 * 		E:把排序后的整数数组转换成字符串
 */
public class Test {
	public static void main(String[] args) {
		// 定义一个字符串
		String s = "91 27 46 38 50";

		// 按照空格进行分割字符串,得到一个字符串数组
		String[] strArray = s.split(" ");

		// 把字符串数组转换为整数数组
		int[] arr = new int[strArray.length];
		for (int x = 0; x < arr.length; x++) {
			arr[x] = Integer.parseInt(strArray[x]);
		}

		// 对整数数组进行排序
		Arrays.sort(arr);

		// 把排序后的整数数组转换成字符串
		StringBuilder sb = new StringBuilder();
		for (int x = 0; x < arr.length; x++) {
			if (x == arr.length - 1) {
				sb.append(arr[x]);
			} else {
				sb.append(arr[x]).append(" ");
			}
		}
		String result = sb.toString();
		
		System.out.println(result);
	}
}

(3)替换功能:论坛中不能出现数字字符,用*替换

/*
 * 替换功能
 *		String类的功能:
 *			public String replaceAll(String regex,String replacement)
 */
public class Test {
	public static void main(String[] args) {
		// 需求:论坛中不能出现数字字符,用*替换
		String s = "helloworld1234567890";

		String s1 = s.replaceAll("\\d", "*");
		String s2 = s.replaceAll("\\d", "");
		String s3 = s.replaceAll("\\d+", "***");

		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
	}
}

(4)获取功能:获取由三个字符组成的单词

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) {
		String s = "da jia hao,wo men dou hen ai java.";
		String regex = "\\b[a-z]{3}\\b";// 定义规则

		//1.获取Pattern实例,按着\\b[a-z]{3}\\b 
		Pattern p = Pattern.compile(regex);
		//2.获取匹配器
		Matcher m = p.matcher(s);

		//3:根据匹配器,先判断是否有3个字符的构成的单词
		while (m.find()) {
			//4:获取3个字母构成的单词
			System.out.println(m.group());
		}
	}
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值