目录
1.lambda表达式
lambda表达式本质上就是一个没有方法名的匿名方法,通常以“(argument)->{body}”这样的格式书写。
在lambda表达式中,参数可以是零个或多个;参数类型可指定,可省略,若省略,java编译器会根据表达式的上下文推导出参数的类型;表达式主体body可以是零条或多条语句。
lambda表达式的类型就是其返回值的类型,即与表达式主体返回类型一致。
1.1.函数式接口
lambda表达式经常被应用在 函数式接口 定义的抽象方法实现中。
函数式接口是只包含有一个抽象方法的接口,又称单例抽象类接口。
函数式接口中的抽象方法指明了接口的目标用途。定义了函数式接口后,就可以把lambda表达式赋值给该接口的一个引用,即赋值给一个接口变量,lambda表达式定义了函数式接口声明的抽象方法的行为。当通过 接口引用 调用接口的抽象方法时,就会自动创建 实现了函数式接口的一个类的实例,并执行lambda表达式所定义的类的行为。
lambda表达式的应用可以总结为:赋值、调用。
interface myInter{ //函数式接口
double compute(double x,double y);
}
class lambdaTest1{
public static void main(String[] args){
myInter add=(m,n)->m+n; //赋值
System.out.println(add.compute(90.0,5.0)); //调用
myInter substract=(m,n)->m-n;
System.out.println(substract.compute(90.0,5.0));
}
}
注意:使用lambda表达式时,函数式接口所定义的抽象方法的类型必须与lambda表达式的类型 兼容,否则会编译出错。
1.2.泛型函数式接口
当函数式接口是泛型时,lambda表达式的类型 由 声明 函数式接口引用 时指定的 实参类型 来决定。
interface myInter<T>{
T compute(T x,T y);
}
class lambdaTest2{
public static void main(String[] args){
myInter<Integer> add=(m,n)->m+n; //引用为int型,lambda表达式类型也是int型
System.out.println(add.compute(90,5));
myInter<double> substract=(m,n)->m-n;
System.out.println(substract.compute(90.0,5.0));
}
}
1.3.方法引用
方法引用:直接通过方法名称来引用方法,是一种更加简洁易懂的lambda表达式。
标准形式为:className::methodName。类名与方法名之间用::隔开。
不同方法的方法引用会有所不同:
1.3.1.静态方法的方法引用
因为是静态方法,形式是ContainClass::staticMethodName,即类名::静态方法。
interface myInter{
void test(int x,int y);
}
class myCompare{
static void compare(int m,int n){
···
}
static void isDivided(int m,int n){
···
}
}
class methodReferTest1{
static void compTest(myInter p,int op1,int op2){
p.test(op1,op2);
}
public static void main(String[] args){
compTest(myCompare::compare,16,8); //相当于myInter p=myCompare::compare,赋值
compTest(myCompare::isDivoded,16,8); //然后p.test(16,8);调用
}
}
1.3.2.实例方法的方法引用
实例方法的引用形式为:对象名::实例方法。
interface myInter{
void test(int x,int y);
}
class myCompare{
static void compare(int m,int n){
···
}
static void isDivided(int m,int n){
···
}
}
class methodReferTest2{
public static void main(String[] args){
myCompare compare1=new myCompare(); //实例化
myInter m1=compare1::compare; //赋值
m1.test(30,15); //调用
myCompare compare2=new myCompare();
myInter m2=compare2::isDivided;
m2.test(30,15);
}
}
1.3.3.某个类型的任意对象的实例方法的方法引用
引用形式为:类名::实例方法。有点迷糊,具体解释参考这里
interface myInter{
void test(myTest mt); //参数为对象
}
class myTest{
private int m,n;
myTest(int op1,int op2){
m=op1;
n=op2;
}
void compare(){
···
}
void isDivided(){
···
}
}
class methodReferTest3{
public static void main(String[] args){
myTest mt1=new myTest(30,15);
myInter m1=myTest::compare; //赋值
m1.test(mt1); //调用
myTest mt2=new myTest(20,6);
myInter m2=myTest::isDivided;
m2.test(mt2);
}
}
1.3.4.构造方法的方法引用
构造方法的引用形式为:类名::new。
interface myInter{
myTest test(int op1,int op2);
}
class myTest{
private int m,n;
myTest(int op1,int op2){
m=op1;
n=op2;
}
int getM(){return m;}
int getN(){return n;}
}
class methodReferTest4{
public static void main(String[] args){
myInter m1=myTest::new;
myTest m2=m1.test(20,6);
System.out.println(m2.getM());
System.out.println(m2.getN());
}
}
2.常用实用类
2.1.正则表达式基础
正则表达式是功能强且灵活的文本处理工具,它用某字符串集合中 各串的公共特征来描述这个字符串集。
具体来说,正则表达式是含有一些具有特殊意义字符的字符串。例如:(懵)
-?数字:表示这个数可能是负值。
\\d:表示一位数字。\\d+:表示一位数以上。
-|\\+:表示一个数前面可能有正号或负号。|为逻辑或。
(-|\\+)?\\d+:一位以上的数前面可能有正号或负号。
2.1.1. 正则表达式字符类
正则表达式中可以用方括号括起来若干字符表示一个字符类。
字符类 | 含义 |
---|---|
[abc] | a、b或c(简单类) |
[^abc] | 除了a、b或c外的任何字符(非) |
[a-zA-Z] | a~z或A~Z(含)(范围) |
[a-d[m-p]] | a~d或m~p |
[a-z&&[def]] | d、e或f(交) |
[a-z&&[^bc]] | a~z,除了b和c |
[a-z&&[^m-p]] | a~z交非m~p |
2.1.2.预定义字符集
预定义字符串 | 含义 |
---|---|
. | 任何字符 |
\d | 一位数字 |
\D | 一位非数字 |
\s | 一个空白字符 |
\S | 一个非空字符 |
\w | 一个词字符 |
\W | 一个非词字符 |
2.1.3.量词
直接举例:
a?:表示零个或一个a。
a*:表示零个或多个a。
ab+:表示一个a后面跟随一个或多个b。
a{2}:表示正好2个a。
a{2,}:表示至少2个a。
a{2,5}:表示至少2个a但不超过5个a。
(abc)+:表示一个或多个abc。
2.1.4.边界匹配符
边界匹配符 | 含义 |
---|---|
^ | 行的开头 |
$ | 一行的尾部 |
\b | 一个词的边界 |
\B | 一个非词的边界 |
\A | 输入的开头 |
\G | 前次匹配的尾部 |
\Z | 输入的尾部,但用于最后终止符 |
\z | 输入的尾部 |
2.2.正则表达式支持类
Java核心API中包含了java.util.regex程序包,包中包含有Pattern、Matcher、patternSyntaxException三个类支持正则表达式。
2.2.1.pattern类
一、compile()方法
public static Pattern compile(String regex,int flag)
1、静态方法,要用类名来调用,如Pattern.compile("\\d"),返回值是Pattern类实例。
2、参数regex表示输入的正则表达式,flag表示模式匹配的方式(可略)。
二、matcher()方法
public Matcher matcher(CharSequence input)
1、通过pattern类的对象调用,返回Matcher类实例,通过这个实例可以调用Matcher类的方法。
2、参数input表示输入的待处理字符串。
三、split()方法
public String[] split(CharSequence input)
1、该方法把 按正则表达式分界的 字符串分解为一个 子串数组。返回值是一个字符串数组。
2、参数input表示输入的待拆分字符串。
下例是把 以数字为界的字母子串 解析出来放进字符串数组letter中。
import java.unit.regex.Pattern;
public class Mysplit{
private static final String REGEX="\\d+";
private static final String INPUT="abc5defg64hijk";
public static void main(String[] args){
Patterm p=pattern.compile(REGEX);
String[] letter=p.split(INPUT);
for(String str:letter)
System.out.println(str);
}
}
//结果:
//abc
//defg
//hijk
2.2.2.Matcher类
一、matches()方法
public boolean matches()
对整个输入字符串按 编译好的正则表达式 进行模式匹配。
二、find()方法
public boolean find(int start)
从字符串的start位置处开始匹配正则表达式所表示的模式。
三、replaceAll()方法
public String replaceAll(String replacement)
字符串替换,用给定的replacement串替换符合模式匹配的部分。
import java.unit.regex.Pattern;
import java.unit.regex.Matcher;
public class Mymatch{
private static final String REGEX="abc";
private static final String INPUT="abcdaabcabbbcabcc";
public static void main(String[] args){
Pattern p=Pattern.compile(REGEX);
Matcher m=p.matcher(INPUT);
int i=0;
while(m.find()){
i++;
System.out.println("Match "+i);
System.out.println(": "+m.start());
System.out.println("-"+m.end());
}
}
}
//结果:
//Match 1: 0-3
//Match 2: 5-8
//Match 3: 13-16
2.2.3.patternSyntaxException类
这个类用于检查正则表达式模式中的语法错误。
2.3.字符串类
字符串常量又称串字面量,是用双引号包括起来的任意数量的字符。Java用String类存放字符串常量,不能修改;如果字符串要改动,则用StringBuilder类,若修改后不会再变,可用toSprint方法转换为String类。
2.3.1.String类
创建String类对象可以用串字面量,如:String s="Good morning";
等价于:String s=new String("Good morning");
String类常用方法:
1、pubilc int length()
该方法返回串中的字符数,例如:int len=s.length();
2、public char charAt(int index)
返回参数中指定的串中位置的字符,例如:char ch=s.charAt(2);
3、public int indexOf(String str)
返回串中首次出现str串的位置,返回-1表示串中无str串。例如:int ind=s.indexOf('.');
4、public String substring(int beginIndex,int endIndex)
返回起始位置和末尾位置间的子串。例如:String sub=s.substring(0,4);
补充:String类的getBytes()方法
该方法是得到一个 操作系统默认的编码格式 的字节数组。这表示在不同的操作系统中,返回的数组不一样。
1、str.getBytes():如果不带charset参数,则采用的是当前文件的编码方法。
2、str.getBytes("charset"):将底层存储的Unicode码解析成charset编码格式的字节数组。
String还有一种构造方法:String string=new String(byte[],charset)
经常搭配getByte方法使用:String s=new String(str.getBytes("utf-8"),"gb2312");
把从str按utf-8解析出来的字节数据 转换为 gb2312编码格式的字符串。
下面简单介绍下ISO-8859-1,GBK,Unicode,UTF-8编码格式:
1、 ISO-8859-1
又称为西欧语言,在ascll码的基础上增加了96个字符和符号,单字节编码,无法表示中文。
2、GB2312/GBK/GB18030
GB2312:我国国家标准简体中文字符集,双字节编码。
GBK:汉字内码扩展规范,不属于国家标准,但囊括范围更广,兼容GB2312。
GB18030:在GBK基础上再增加内容。(好像少见)
3、Unicode
计算机科学领域的业界标准,对世界上大部分的文字系统进行了整理、编码。
4、utf-8/utf-16
都是一种针对Unicode的可变长度字符编码。区别在于:
utf-8:对字符采用1到4字节编码。中文是3个字节。
utf-16:对字符采用2字节编码。(有说2或4的)
对于Java:详细回答见https://zhidao.baidu.com/question/494528739317154332.html
Java的class文件采用utf-8,JVM运行时采用utf-16,Java的字符串是采用Unicode编码的。
2.3.2.String类和正则表达式
在String类中也有支持正则表达式操作的方法,与前面提及的功能类似,但所属类不同。
1、public boolean matches()
执行字符串模式匹配。
2、public String replaceAll(String regex,String replacement)
执行字符串模式匹配替换。
3、public String[] split(String regex)
执行字符串模式匹配拆分。
public class Mystring{
public static void main(String[] args){
String str1="name;telephone";
String str2="word123text456";
String str3="2022/03/01";
String s[]=str1.split(";");
for(String stemp:s)
System.out.println(stemp);
str2=str2.replaceAll("\\d+"," ");
System.out.println(str2);
System.out.println(str3.matches(\\d{4}/\\d{2}/d{2}));
}
}
//结果:
//name
//telephone
//word text
//true
2.3.3.StringBuilder类
创建StringBuilder类对象格式:StringBuilder strb=new StringBuilder();
缓冲区初始容量是16字符单元,创建时可以带整形参数(即指定缓冲区大小),例如:
StringBuilder strb=new StringBuilder(int initCapacity);
创建时还可以带字符串作为参数,例如:
StringBuilder strb=new StringBuilder("Good morning");
StringBuilder类有许多方法,用于修改字符串,常用的有:
1、StringBuilder append(type variable)
将数据追加到StringBuilder的尾端,例如:
while((ch=System.in.read())!='\n')strb.append(ch);
2、StringBuilder insert(int offset type variable)
把数据插入到StringBuilder的指定位置,例如:
StringBuilder strb=new StringBuilder("A book");
strb.insert(2,"good");
记住位置从0开始,若要插入字符到串的前端,则位置参数为0.
3、StringBuilder setCharAt(int offset,char ch)
将指定位置的字符改为指定字符,例如:
strb.setCharAt(2,'B');
class ReverseStr{
public static String reverseIt(String source){
int i,len=source.length();
StringBuilder dest=new StringBuilder(len);
for(i=len-1;i>=0;i--)
dest.attend(source.charAt(i));
return dest.toString();
}
}
2.4.日期时间类
java的日期时间类主要有Data、Calendar、GregorianCalendar等,它们位于java.util包中。
2.4.1.Data
Data类提供了许多方法,但多数已经过时,不推荐使用。简单介绍Data类常用的两个方法:
1、Data():构造方法,使用当前日期和时间初始化一个对象。
2、long getTime():返回自标准基准时间(1970.1.1.00:00:00GMT)以来此Data对象表示的毫秒数。
2.4.2.Calendar类
Calendar类是一个抽象类,提供了一组方法,可以实现特定瞬间与YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换。
不能直接使用Calendar类来创建对象,但可以使用该类提供的静态方法getInstance()获得代表当前日期的日历对象。例如:Calendar cal=Calendar.getInstance();
Calendar类常用方法:
一、int get(int field);
1、通过实例对象调用该方法就可以知道年月日星期等消息。
2、参数field的值为Calendar类的静态常量,如YEAR、MONTH等。
例如:cal.get(Calendar.Mouth);
如果返回值为0,代表当前月份是一月,返回1表示二月,如此类推。
二、set()方法
声明格式有多种:
void set(int year,int month,int day);
void set(int year,int month,int day,int hour,int minute,int second);
void set(int field,int value);
例如:
cal.set(2022,3-1,9); //设定当前日期为2022.3.9
cal.set(2022,3-1,9,10,13,25);
cal.set(Calendar.YEAR,2022); //设定当前日期为2022年
2.4.3.GregorianCalendar类
GregorianCalendar是Calendar类的子类,提供了Calendar类中所有的抽象方法的实现,同时还提供一些附加的方法。Calendar类的getInstance方法返回一个GregorianCalendar,它被初始化为默认的地域和时区下的日期和时间。
import java.util.*;
public class myGreCalendar{
public static void main(String[] args){
Calendar cal=new GregorianCalendar(); //上转
cal.setTime(new Data()); //获取当前时间
System.out.println((cal.get(Calendar.MONTH)+1)+"月");
System.out.println("星期"+(cal.get(Calendar.DAY_OF_WEEK)-1));
}
}
//结果:
//3月星期4
Calendar类中周日用1表示,周一用2表示,以此类推。