今天学习的东西比较多,其中在学习Java中的类库时需要不停翻阅API,今天主要学习了Java中一些常用的类库和lambda表达式,只有通过查阅API才能够真正知道各种类库之间的继承关系、常量、构造方法和其他的方法,并且这不能只通过学习书上写的东西,因为书上写的东西往往有很多地方不好表达出来,这一块只能通过自己动手写写才能记住和学会。后面继续学习了lambda表达式,这是jak1.5版本之后才有的,lambda表达式的出现更加体验了Java这门语言的优雅!好了,下面就是今天学习的笔记了。
一、Date、DateFormat、SimpleDateFormat类库
通过下面的例子可以清晰感受这些类是怎么实现的和有哪些方法。
import java.util.*;
import java.text.*;
class Demo2
{
public static void main(String[] args)throws ParseException
{
DateFormat dateFormat = DateFormat.getDateTimeInstance();//得到一个可以对时间进行格式化的对象
//String format(Date date)
String str = dateFormat.format(new Date()); //使用的是默认的格式对日期对象进行格式化
DateFormat dateFormat2 = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
String ss = dateFormat2.format(new Date());
System.out.println(ss);
//SimpleDateFormat 是DateFormat的子类 ****必须掌握
SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd E HH:mm:ss");//在参数中指定时间展示的格式
//把Date类型的转成字符串类型
String s1=simple.format(new Date());
System.out.println(s1);
//把字符串类型的日期转成Date类型 Date parse(String source)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//参数指定的是字符串的格式
Date d = sdf.parse("2019-12-20");
System.out.println(d);
}
}
二、Calender类库(实际生活中并不常用,一般开发都使用Date类)
下面利用Calender类实现计算两个日期相差多少天
import java.util.*;
import java.text.*;
class Demo3
{
public static void main(String[] args)throws ParseException
{
Calendar calendar = Calendar.getInstance();//了解
//System.out.println(calendar);
String[] months={"1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"};
String[] weeks={"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
int nian = calendar.get(Calendar.YEAR);
int month=calendar.get(Calendar.MONTH);
int day =calendar.get(Calendar.DAY_OF_MONTH);
int week = calendar.get(Calendar.DAY_OF_WEEK);
System.out.println(nian+"年"+months[month]+day+"号"+weeks[week]);
int days = days("2019-12-12","2020-12-12");
System.out.println(days);
}
//计算两个日期相差多少天
public static int days(String from,String to)throws ParseException
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date day1 = sdf.parse(from);
Date day2 = sdf.parse(to);
long shijian = day2.getTime()-day1.getTime();
return (int)(shijian/1000/60/60/24);
}
}
总结:常用用法
三、Math类库
Math包中常见的几种方法,如下:
import java.util.*;
class Demo4
{
public static void main(String[] args)
{
//Math
sop(Math.ceil(36.6));//返回大于这个数的最小整数
sop(Math.floor(36.6));//返回小于这个数的最大整数
sop(Math.round(36.8));//四舍五入取整
sop(Math.sqrt(4));
sop(Math.abs(-6));
sop(Math.pow(2,3));
for(int i=1;i<=5;i++)
{
sop(Math.random());// >=0.0 <1.0
}
//1--10
//Math.abs(Math.ceil(Math.random()*10));
Random r = new Random();
int num = r.nextInt(10)+1;//>=1 <11
sop(num);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
BigInteger
BigInteger包中需要掌握的add()、subtract()、multiply()、divide()、divideAndRemainder()方法的用法,如下:
import java.math.*;
class Demo5
{
public static void main(String[] args)
{
//掌握
BigInteger big1=new BigInteger("79837428348927492389387498379874594");
BigInteger big2=new BigInteger("49837428348927492389387498379874594");
System.out.println(big1.add(big2));
System.out.println(big1.subtract(big2));
System.out.println(big1.multiply(big2));
System.out.println(big1.divide(big2));
BigInteger[] arr= big1.divideAndRemainder(big2);//下标0中放的是商值,下标1中放的是余数值
System.out.println(arr[0]);
System.out.println(arr[1]);
}
}
四、枚举
实现一个类创建固定个数的对象 ---- 枚举的作用
jdk1.5之前只能像下面这样定义
class Season
{
public static final Season SPRING=new Season();
public static final Season SUMMER=new Season();
public static final Season AUTUMN=new Season();
public static final Season WINTER=new Season();
private Season(){}
}
class Demo6
{
public static void main(String[] args)
{
Season chunji =Season.SPRING;
sop(chunji);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
好的,下面来说说枚举。枚举类是final类型,其中的变量是private static final类型,且继承了java.lang.enum,因此枚举类不能有子类,不能再继承别的类
enum Week //定义一个枚举类,只要是枚举类,那么这个类的对象的个数就是有限的,枚举类实际就是个类
{
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
enum Season //extends Demo7 枚举类是不能继承其它类的,因为每个枚举类已经继承了Enum,枚举类不能有子类,因为是final的
{
SPRING,SUMMER,AUTUMN,WINTER
}
class Demo7
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
enum中的方法
首先来看看下面的代码
/*
Enum:
int ordinal() 返回的是枚举项的编号值 编号从0开始
int compareTo(E o) 根据枚举项的编号比较大小的
String name() 返回枚举常量的名称
String toString() 返回枚举常量的名称
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回带指定名称的指定枚举类型的枚举常量。
编译器编译时在枚举类中加入的方法:
public static Week[] values(); //得到所有的枚举项
public static Week valueOf(java.lang.String);//根据枚举项的名字返回枚举项对象
*/
enum Week //Enum 枚举项 枚举常量
{
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
class Demo8
{
public static void main(String[] args)
{
Week w1=Week.MONDAY;
sop(w1);
Week[] weeks={Week.MONDAY,Week.TUESDAY,Week.WEDNESDAY,Week.THURSDAY,Week.FRIDAY,Week.SATURDAY,Week.SUNDAY};
sop("weeks[0]:ordinal:"+weeks[0].ordinal());
sop("weeks[1]:ordinal:"+weeks[1].ordinal());
sop("weeks[2]:ordinal:"+weeks[2].ordinal());
sop(weeks[0].compareTo(weeks[1])); //-1 编号相减
sop(weeks[6].compareTo(weeks[2])); //4
sop(weeks[0].name());
sop(weeks[3].name());
sop(weeks[5].name());
sop("==============================");
sop(weeks[1].toString());
sop(weeks[2].toString());
sop(weeks[4].toString());
Week w = Week.valueOf(Week.class,weeks[0].name());
sop(w.ordinal());//0
sop("==========================");
Week[] arr = Week.values();
for(Week week:arr)
{
sop(week.name());
}
sop("==========================");
Week wk = Week.valueOf("TUESDAY");
sop(wk);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
我们一起来看看API中怎么讲解Enum包的
- String toString()方法
返回枚举常量的名称(默认情况下和下面提到的name()方法一样的作用,除非重写该方法)
- int ordinal()方法
返回枚举项的编号值,从0开始
- int compareTo(E o)
根据枚举项的编号比较大小的
- String name()
返回枚举常量的名称
- valueOf()方法
返回的是一个枚举类型的对象
此外,枚举类实现抽象方法。
枚举类实现接口
1.枚举类中除了枚举项还有其它成员,那么最后一个枚举项后边必须加分号,枚举项必须写在第一行
2.在枚举类中定义构造方法,定义方法,定义属性
就像下面这样:
enum Season
{
SPRING("春季"),SUMMER("夏季"),AUTUMN("秋季"),WINTER("冬季");
private String desc;
//构造方法默认就是private的
Season(){}
Season(String desc){
this.desc=desc;
}
public String getDesc()
{
return this.desc;
}
public void setDesc(String desc)
{
this.desc=desc;
}
}
class Demo9
{
public static void main(String[] args)
{
Season season=Season.SUMMER;
sop(season.getDesc());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
此外,在枚举类中定义非静态方法,定义静态方法都可以。
enum Season
{
SPRING("春季"),SUMMER("夏季"),AUTUMN("秋季"),WINTER("冬季");
private String desc;
//构造方法默认就是private的
Season(){}
Season(String desc){
this.desc=desc;
}
public String getDesc()
{
return this.desc;
}
public void setDesc(String desc)
{
this.desc=desc;
}
public void show()
{
System.out.println("hello");
}
public static void fun()
{
System.out.println("static");
}
}
class Demo10
{
public static void main(String[] args)
{
Season summer = Season.AUTUMN;
summer.show();
summer.fun();
Season.fun();
}
}
枚举类中可以有抽象方法,但是必须重写
enum Season
{
SPRING("春季"){
public void show(){
System.out.println("spring");
}
},SUMMER("夏季"){
public void show(){
System.out.println("summer");
}
},AUTUMN("秋季"){
public void show(){
System.out.println("autumn");
}
},WINTER("冬季"){
public void show(){
System.out.println("winter");
}
};
private String desc;
//构造方法默认就是private的
Season(){}
Season(String desc){
this.desc=desc;
}
public String getDesc()
{
return this.desc;
}
public abstract void show();
}
class Demo11
{
public static void main(String[] args)
{
Season summer = Season.AUTUMN;//
summer.show();
}
}
同样的,枚举类可以实现接口,但是不能再继承其他类,只能实现接口
interface inter
{
void fun();
}
enum Week implements inter
{
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY;
public void fun()
{
System.out.println("fun");
}
}
class Demo12
{
public static void main(String[] args)
{
Enum w=Week.SUNDAY; //多态
Object ww=Week.SUNDAY;
ww.fun();
/*
Class claz = Week.TUESDAY.getClass();
System.out.println(claz);
Week[] arr = (Week[])claz.getEnumConstants();//得到所有的枚举项对象
for(Week k:arr)
{
System.out.println(k);
}
*/
}
}
总结
五、lambda表达式(JDK1.8)
lambda表达式适合于接口,且接口中只有一个抽象方法(接口中需要重写的方法只有一个),否则不能使用lambda
lambda表达式也叫匿名函数: 方法名都省略了
只有一个抽象方法的接口才能使用lambda:
只有一个抽象方法的接口:函数式接口
到底怎么才算是函数式接口?
@FunctionalInterface//用来检测接口是不是函数式接口
interface Test1//是函数式接口
{
void test();
}
interface Test2//不是函数式接口
{
void test1();
void test2();
}
interface Test3 extends Test1//是函数式接口
{
}
interface Test4//每个类中都有Object中的toString方法,所以只需要重写一个方法,所以属于函数式接口
{
void test4();
String toString();
}
interface Test5//是
{
void test();
static void fun(){};
}
interface Test6//是
{
void test();
default void fun(){};
}
interface Test7//不是
{
}
class Demo16
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
学会了怎么判断函数式接口,先来看看lambda表达式最原始的样子
interface NoneReturnNoneParame//无参无返回值
{
void test();
}
interface NoneReturnSingleParame//1个参数无返回值
{
void test(int a);
}
interface NoneReturnMultipleParame//多个参数无返回值
{
void test(int a,int b);
}
interface SingleReturnNoneParame//无参数有返回值
{
int test();
}
interface SingleReturnSingleParame//1个参数有返回值
{
int test(int a);
}
interface SingleReturnMultipleParame//多个参数有返回值
{
int test(int a,int b);
}
class Demo17
{
public static void main(String[] args)
{
//无参无返回值
NoneReturnNoneParame noneReturnNodeParame=() -> {System.out.println("无参无返回值");};
noneReturnNodeParame.test();
1个参数无返回值
NoneReturnSingleParame noneReturnSingleParame=(int a) ->{System.out.println("1个参数无返回值");};
noneReturnSingleParame.test(4);
//多个参数无返回值
NoneReturnMultipleParame noneReturnMultipleParame=(int a,int b) -> {System.out.println(a+b);};
noneReturnMultipleParame.test(5,5);
//无参数有返回值
SingleReturnNoneParame singleReturnNoneParame=() ->{System.out.println("无参数有返回值");return 6;};
int num = singleReturnNoneParame.test();
System.out.println(num);
//1个参数有返回值
SingleReturnSingleParame singleReturnSingleParame=(int a) ->{System.out.println("1个参数有返回值");return a;};
num = singleReturnSingleParame.test(66);
System.out.println(num);
//多个参数有返回值
SingleReturnMultipleParame singleReturnMultipleParame=(int a,int b) ->{System.out.println("1个参数有返回值");return a+b;};
num=singleReturnMultipleParame.test(6,8);
System.out.println(num);
}
}
真正的lamda表达式是作了简化的,规则如下:
class Demo18
{
public static void main(String[] args)
{
//lambda表达式的简化
// NoneReturnSingleParame noneReturnSingleParame=(int a) ->{System.out.println("1个参数无返回值");};
//只有一个参数的时候可以省略小括号
NoneReturnSingleParame noneReturnSingleParame= a ->{System.out.println("1个参数无返回值");};
//如果方法体中只有一条语句,那么大括号可以省略
NoneReturnSingleParame noneReturnSingleParame= a ->System.out.println("1个参数无返回值");
noneReturnSingleParame.test(4);
//多个参数无返回值 不管有几个参数,数据类型都可以省略,要省略类型必须都省略,否则都不省
//NoneReturnMultipleParame noneReturnMultipleParame=(a,b) -> {System.out.println(a+b);};
NoneReturnMultipleParame noneReturnMultipleParame=(a,b) -> System.out.println(a+b);
noneReturnMultipleParame.test(5,5);
//无参数有返回值 如果方法有返回值,且大括号中只有一条语句,这条语句还是负责返回的
SingleReturnNoneParame singleReturnNoneParame=() ->6;
int num = singleReturnNoneParame.test();
System.out.println(num);
SingleReturnMultipleParame singleReturnMultipleParame=(int a,int b) ->{return a+b;};
SingleReturnMultipleParame singleReturnMultipleParame=(a,b) ->a+b;
num=singleReturnMultipleParame.test(6,8);
System.out.println(num);
}
}
总结
好的,今天就到这里了