jdk1.7/jdk1.8新特性

在面试中经常会问jdk1.6,jdk1.7,jdk1.8的区别:

最近面试的时候的面试官问我jdk8的新特性:
我回答了几个,他提问到:为什么defualt没有被推广,有什么弊端。
我很蒙圈,在这里添加下回答:
我目前还不知道

jdk1.7新增特性:

1.7新特性转载

1 switch 支持string

jdk1.6: int,short,char,byte,Enum
jdk1.7: string,int,short,char,byte,Enum

2 泛型自动判断

ArrayList al1 = new ArrayList(); // Old
ArrayList al2 = new ArrayList<>(); // New

3 新的整数字面表达方式 - “0b"前缀和”_"连数符

byte b1 = 0b00100001; // New
byte b2 = 0x21; // Old
byte b3 = 33; // Old
System.err.println(b1); //33
这里有一些其它的不能在数值型字面值上用下划线的地方:
1 在数字的开始或结尾
2 在浮点型数字的小数点前后
3 F或L下标的前面
4 该数值型字面值是字符串类型的时候
int a4 = 5_______2; // 有效的

4.在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常

1.6

catch (IOException ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());
catch (SQLException ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());
}catch (Exception ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());
}

1.7

catch (IOException | SQLException | Exception ex) {
    logger.error(ex);
    throw new MyException(ex.getMessage());

可以不用重新指定异常类型

static class FirstException extends Exception { }
static class SecondException extends Exception { }

public void rethrowException(String exceptionName) throws Exception {
    try {
        if (exceptionName.equals("First")) {
            throw new FirstException();
        } else {
            throw new SecondException();
        }
    } catch (Exception e) {
      //下面的赋值没有启用重新抛出异常的类型检查功能,这是Java 7的新特性
            // e=new ThirdException();
        throw e;
    }
}

5.try-with-resources语句

1.7之前,须在finnally中手动关闭资源

/** 
 * JDK1.7之前我们必须在finally块中手动关闭资源,否则会导致资源的泄露 
 * @author Liao 
 * 
 */  
public class PreJDK7 {  

    public static String readFirstLingFromFile(String path) throws IOException {  
        BufferedReader br = null;  

        try {  
            br = new BufferedReader(new FileReader(path));  
            return br.readLine();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {//必须在这里关闭资源  
            if (br != null)  
                br.close();  
        }  
        return null;  
    }  
}

1.7

/** 
 * JDK1.7之后就可以使用try-with-resources,不需要 
 * 我们在finally块中手动关闭资源 
 * @author Liao 
 */  
public class AboveJDK7 {  

    static String readFirstLineFromFile(String path) throws IOException {  

        try (BufferedReader br = new BufferedReader(new FileReader(path))) {  
            return br.readLine();  
        }  
    }  
}

jdk1.8新增特性:

1.8新特性
1.8主要是简化写法

1. default关键字

在1.8以前接口内的方法只能是抽象方法,在1.8可以新增default修饰的方法,且实现类不能继承该方法。
优势:若需要新增一个统一的方法,以前需要在每一个实现类中继承,现在只需要在接口类增加一个defualt方法即可。

接口类

public interface interFaceClass {
	void myFuncation();
  default void mydefualtFuncation(){
	  System.err.println("this is a defualt funcation");
  };
}

实现类

public class implementClass implements interFaceClass {
	@Override
	public void myFuncation() {
		// TODO Auto-generated method stub
	}
}

测试类

public static void main(String[] args) {
		interFaceClass test = new implementClass();
		test.mydefualtFuncation();   //this is a defualt funcation
	}

2. 时间类:

localdate
jdk1.8提供了新的API解决之前版本关于获取时间上繁琐及SimpleDateFormat的线程不安全.总体来看新的API提供了许多便捷的方法获取想要的时间。
localdate
localtime
localdatetime
zonedatetime
为方便使用和记忆,我在下面的例子中逐一获取并对比;
测试时间是 2018-09-30
1.7

Date date =  new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd   HH:mm:ss");

//获取当前时间
date.getDate();// 30
System.out.println(date);//  Sun Sep 30 09:51:04 CST 2018

//按格式获取当前时间
System.out.println(df.format(date)); // 2018-09-30 09:51:04

//获取前一天时间
Calendar cal=Calendar.getInstance();
cal.add(Calendar.DATE,  -1);
Date yesterday = cal.getTime();
System.out.println(df.format(yesterday )); // 2018-09-29 09:51:04
		
//获取指定时间
String dateOfBirthString= "2017-10-11";
Date dateOfBirth = new SimpleDateFormat("yy-MM-dd").parse(dateOfBirthString);
System.out.println(df.format(dateOfBirth )); // 2017/10/11 00:00:00

//比较两个时间是否相同
boolean flag =  dateOfBirth.equals(dateTody);
System.out.println("flag:  "+flag);// flag;  false

//比价两个时间的差
//太麻烦了我就不写了

//将日期转化为字符串
String dateString1 = dateTody.toString;
String dateString2 = df.format(dateTody);

1.8

// 获取当前时间
LocalDate dateTody = LocalDate.now();
LocalTime timeNow=LocalTime.now();
System.out.println(dateTody+" "+  timeNow);// 2018-09-30  10:36:45.260
int year =  dateToday.getYear();
int month = dateToday.getMonthValue();	
int day =   dateToday.getDayOfMonth();

// 按格式获取当前时间
DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String text = dateToday.format(formatters);
System.err.println(text);//2018年09月30日

//获取前一天时间
LocalDate yestoday = dateToday.minusDays(1);
System.err.println(yestoday );//2018-09-29
	
//获取指定时间
LocalDate dateOfBirth = LocalDate.of(2017, 10, 11);
System.err.println(dateOfBirth );//2017-10-11

//比较两个时间是否相同
Boolean flag =  dateToday.equals(dateOfBirth);

//比价两个时间的差
long dy=(   dateToday.toEpochDay() - dateOfBirth.toEpochDay() );
System.err.println("相差:"+dy);//相差:354
	
//将日期转化为字符串
dateToday.toString();


//比较时用的方法:
//一年以后
LocalDate lastYear = dateToday.plus(1,ChronoUnit.YEARS);
System.err.println(lastYear);//2019-09-30

// 取本月第1天:		
LocalDate firstDayOfThisMonth1=dateToday.withDayOfMonth(1);
LocalDate firstDayOfThisMonth = dateToday.with(TemporalAdjusters.firstDayOfMonth()); // 2018-04-01		
// 取本月第2天:		
LocalDate secondDayOfThisMonth = dateToday.withDayOfMonth(2); // 2018-04-02		
// 取本月最后一天,再也不用计算是28,29,30还是31:		
LocalDate lastDayOfThisMonth = dateToday.with(TemporalAdjusters.lastDayOfMonth()); // 2018-04-30		
// 取下一天:		
LocalDate firstDayOfNextMonth = lastDayOfThisMonth.plusDays(1); // 变成了2018-05-01		
// 取2017年1月第一个周一:		
LocalDate firstMondayOf2017 = LocalDate.parse("2017-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2017-01-02 

3 lamdba 表达式

“Lambda表达式”是一个匿名函数,是jdk1.8重要的新特性
首先了解下内部类的使用和优点:内部类可以访问外部类,但只有外围的外部类才能访问该内部类,内部类可以使得该类实现多继承,
匿名内部类是唯一一种没有构造器的类,且不能有静态变量
这是一个内部类调用
创建静态内部类对象的一般形式为: 外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()
创建成员内部类对象的一般形式为: 外部类类名.内部类类名 xxx = 外部类对象名.new 内部类类名()

public class outerClass {
	int a=1;	
	class innerClass{
		int a=2;
		void Printable(){
			int a =3;
			System.err.println(a);
			System.err.println(this.a);
			System.err.println(outerClass.this.a);
		}
	}
	
	public static void main(String[] args) {
		outerClass out1 = new outerClass();
		outerClass.innerClass inner2 = out1.new innerClass();
		inner2.Printable();
	}
}
}

匿名内部类

public  abstract  class Person {
	 abstract void f();	
}

Person 是一个抽象类是不能被实例化的,但是我们通过匿名内部类就可以实现对其的向下转型

public class Test {
	public static void main(String[] args) {
		Person p = new Person() {
			@Override
			void f() {
				// TODO Auto-generated method stub
				System.err.println("我是匿名内部类");
			}
        };
        p.f();
	}
}

上面等效于

Person person=new child();
	person.f(); //child是Person 子类

使用lamdba实现上面的匿名内部类(Person 必须是接口)

 Person p2 =() -> System.err.println("我是匿lambda");
 p2.f();

使用lamdba实现对数组的遍历

List<String> list = Arrays.asList("我是1","我是2");
        for ( String a : list) {
			System.err.println(a);
		}      
list.forEach( a -> System.err.println("我是lambda"+a) );// 一句话搞定
list.forEach(System.out :: println);  //println无法写参数

看了上面的例子我们再来解释下lambda表达式,由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。
基本语法

(parameters) -> expression
或
(parameters) ->{ statements; }

变量作用域
lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

		String ab="           我是变量";		
		Person p = new Person() {
			@Override
			public void f() {
				// TODO Auto-generated method stub
				System.err.println("我是匿名内部类"+ab);    //匿名内部类一样会报错
			}
        };		
        p.f();        
        Person p2 =() -> System.err.println("我是匿lambda"+ab);
        p2.f();
        ab="123131231";  // 当ab变量不赋值时上述方法均不会报错,但是改变值之后就都报错了,需要将ab设置为final类型防止出现编译错误

对数组排序(对下列方法使用lambda改造)

String[] players = {"Rafael Nadal", "Novak Djokovic",   
    "Stanislas Wawrinka", "David Ferrer",  
    "Roger Federer", "Andy Murray",  
    "Tomas Berdych", "Juan Martin Del Potro",  
    "Richard Gasquet", "John Isner"};  
   
// 1.1 使用匿名内部类根据 name 排序 players  
Arrays.sort(players, new Comparator<String>() {  
    @Override  
    public int compare(String s1, String s2) {  
        return (s1.compareTo(s2));  
    }  
});  

lambda

Arrays.sort(players,(s1,s2)->s1.compareTo(s2));//一句话搞定,注意lambda针对的是匿名内部类

4 函数式接口

@FunctionalInterface
java 8提供 @FunctionalInterface作为注解,这个注解是非必须的,只要接口符合函数式接口的标准(即只包含一个方法的接口),虚拟机会自动判断, 但 最好在接口上使用注解@FunctionalInterface进行声明,以免团队的其他人员错误地往接口中添加新的方法。

5 Stream()

自己的总结

  //排序 
String[] players = {"a", "e", "d", "c"};  
        	   
// 1.1 使用匿名内部类根据 name 排序 players  
        	Arrays.sort(players, new Comparator<String>() {  
				@Override
				public int compare(String s1, String s2) {
					// TODO Auto-generated method stub
					  return (s1.compareTo(s2));  
				}  
        	});  
        	
        	for (String string : players) {
				System.err.println(string);
			}
        	
Arrays.sort(players,(s1,s2)->s1.compareTo(s2));

        
//steam()
 List <Integer> steamtest = Arrays.asList(1,2,50,30);

//对元素操作
 List<Integer >   getList =  steamtest.stream().map(a->a*2).collect(Collectors.toList());
		 getList.forEach(System.out::println);

//排序
List<Integer >   getsortList =  steamtest.stream().sorted((a1,a2)->a1.compareTo(a2)).collect(Collectors.toList());
  		getsortList.forEach(System.out::println);	

//过滤      
List<Integer >   getFilterList =steamtest.stream().filter(s-> (s>=2)).collect(Collectors.toList());
      getFilterList.forEach(System.out::println);	

//生成数组
 Integer[] atest = steamtest.stream().toArray(Integer[]::new); 
     
//对元素叠加计算
 int value = steamtest.stream().reduce(0, (acc,item)->acc+item).intValue();
		 System.err.println(value);

6 HashMap

https://www.cnblogs.com/everSeeker/p/5601861.html

猜你喜欢

转载自blog.csdn.net/qq_31941773/article/details/82888839