接口中默認方法修飾為普通方法
在jdk8之前,interface之中可以定義變量和方法,變量必須是public、static、final的,方法必須是public、abstract的,由於這些修飾符都是默認的。
接口定義方法:public 抽象方法 需要子類實現
接口定義變量:public、static、final
在JDK 1.8開始 支持使用static和default 修飾 可以寫方法體,不需要子類重寫。
方法:
普通方法 可以有方法體
抽象方法 沒有方法體需要子類實現 重寫。
案例
public interface JDK8Interface {
/*
* 默認就是public abstract JDK7之前不能有方法體
* */
void add();
/*
* jdk8 提供默認實現
* */
default void get() {
System.out.println("default方法可以寫方法體");
}
static void getStaticOrder() {
System.out.println("靜態方法可以寫方法體");
}
}
子類實現接口
public class JDK8InterfaceImpl implements JDK8Interface {
/*
* 子類實現接口 沒有強制要求重寫default和static方法
* */
@Override
public void add() {
System.out.println("add方法");
}
}
方法調用
public class Test01 {
public static void main(String[] args) {
JDK8Interface jdk8Interface=new JDK8InterfaceImpl();
jdk8Interface.add();
jdk8Interface.get();
JDK8Interface.getStaticOrder();
}
}

Lambda表達式
是一個匿名函數,簡化我們調用匿名函數的過程
Lambda好處: 簡化我們匿名內部類的調用。
Lambda+方法引入 代碼變得更加精簡。
public static void main(String[] args) {
//使用匿名內部類的方式調用
// new OrderService(){
// @Override
// public void addOrder() {
// System.out.println("addorder");
// }
// }.addOrder();
((OrderService) () -> System.out.println("addorder")).addOrder();
// new Thread(new Runnable() {
// @Override
// public void run() {
// System.out.println(Thread.currentThread().getName()+"運行");
// }
// }).start();
new Thread(() -> System.out.println(Thread.currentThread().getName()+"運行")).start();
}
Lambda表達式的規范
使用Lambda表達式 依賴於函數接口
-
在接口中只能夠允許有一個抽象方法
-
在函數接口中定義object類中方法
-
使用默認或者靜態方法
-
@FunctionalInterface 表示該接口為函數接口
Java中使用Lambda表達式的規范,必須是為函數接口
函數接口的定義:在該接口中只能存在一個抽象方法,該接口稱作為函數接口
@FunctionalInterface
public interface MyFunctionalInterface {
void get();
default void add() {
}
String toString();
}
常見例如Runnable接口

方法調用
public static void main(String[] args) {
((MyFunctionalInterface) () -> System.out.println()).get();
}
Lambda基礎語法
()--參數列表
-> 分隔
{} 方法體
(函數接口的參數列表 不需要寫類型 需要定義參數名稱)->{方法體}
無參方法調用
@FunctionalInterface
public interface MyFunctionalInterface {
void get();
}
MyFunctionalInterface myFunctionalInterface= ()->{
System.out.println("使用lambda表達式");
};
有參帶返回值調用
@FunctionalInterface
public interface YouFunctionalInterface {
String get(int i,int j);
}
public static void main(String[] args) {
YouFunctionalInterface youFunctionalInter=(i, j)->{
return i+"--"+j;
};
System.out.println(youFunctionalInter.get(1, 1));
}
精簡版
public static void main(String[] args) {
//無參方法原始版本
MyFunctionalInterface functionalInterface=()->{
System.out.println("");
};
functionalInterface.get();
//精簡版1
((MyFunctionalInterface)()->{
System.out.println("");
}).get();
//精簡版2 在方法體只有一條語句的時候,不需要寫大括號了
MyFunctionalInterface functionalInterface2=()-> System.out.println("");
//最終精簡版3
((MyFunctionalInterface)()-> System.out.println("")).get();
//有參方法
YouFunctionalInterface youFunctionalInterface=(int i,int j)->{
return "";
};
String s = youFunctionalInterface.get(2, 3);
//精簡版1
YouFunctionalInterface youFunctionalInterface1=( i, j)->{
return "";
};
//精簡版2
YouFunctionalInterface youFunctionalInterface2=(i, j)-> i+"--"+j;
String s1 = youFunctionalInterface1.get(2, 3);
//最終精簡版3
String s2 = ((YouFunctionalInterface) (i, j) -> i + "--" + j).get(1, 2);
System.out.println(s2);
}
Lambda實戰案例
Foreach
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("111");
arrayList.add("222");
arrayList.add("333");
// arrayList.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
arrayList.forEach(s->{
System.out.println(s);
});
}
Lambda集合排序
public class UserEntity {
private String name;
private Integer age;
public UserEntity(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "UserEntity{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) {
ArrayList<UserEntity> userlists = new ArrayList<>();
userlists.add(new UserEntity("aa", 22));
userlists.add(new UserEntity("bb", 18));
userlists.add(new UserEntity("cc", 36));
userlists.sort(new Comparator<UserEntity>() {
@Override
public int compare(UserEntity o1, UserEntity o2) {
return o1.getAge()- o2.getAge();
}
});
//精簡遍歷
userlists.forEach(s-> System.out.println(s));
//精簡排序
userlists.sort((o1, o2) -> o1.getAge()- o2.getAge());
}
Java 8 stream流
Stream 是JDK1.8 中處理集合的關鍵抽象概念,Lambda 和 Stream 是JDK1.8新增的函數式編程最有亮點的特性了,它可以指定你希望對集合進行的操作,可以執行非常復雜的查找、過濾和映射數據等操作。使用Stream API 對集合數據進行操作,就類似於使用SQL執行的數據庫查詢。Stream 使用一種類似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。Stream API可以極大提高Java程序員的生產力,讓程序員寫出高效率、干凈、簡潔的代碼
這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 並且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等

Stream :非常方便精簡的形式遍歷集合實現 過濾、排序等
Stream創建方式
parallelStream為並行流采用多線程執行
Stream采用單線程執行
parallelStream效率比Stream要高
Stream將list轉換為set
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Stream<UserEntity> stream=userEntities.stream();
Set<UserEntity> collect = stream.collect(Collectors.toSet());
collect.forEach(s-> System.out.println(s));
}
set集合底層依賴於map 集合,map集合底層基於equals和hashcode比較防止重復
Stream將list轉換為map
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
/*
* list集合只有key list轉換map的時候需要指定key value,key=username value=user對象
* */
Stream<UserEntity> stream=userEntities.stream();
Map<String,UserEntity> collect = stream.collect(Collectors.toMap(new Function<UserEntity,String>() {
@Override
public String apply(UserEntity o) {
return o.getName();
}
}, new Function<UserEntity, UserEntity>() {
@Override
public UserEntity apply(UserEntity usrentity) {
return usrentity;
}
}));
//精簡版
collect.forEach(new BiConsumer<String, UserEntity>() {
@Override
public void accept(String s, UserEntity userEntity) {
System.out.println(s+","+userEntity);
}
});
//最終精簡版
collect.forEach((BiConsumer)(s,userEntity)->System.out.println(s+","+userEntity));
}
Stream將Reduce 求和
public static void main(String[] args) {
Stream<Integer> integerStream=Stream.of(5,6,7,8);
Optional<Integer> reduce = integerStream.reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
});
System.out.println(reduce);
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Optional<UserEntity> sum=userEntities.stream().reduce(new BinaryOperator<UserEntity>() {
@Override
public UserEntity apply(UserEntity userEntity, UserEntity userEntity2) {
UserEntity userEntity1=new UserEntity("sum",userEntity.getAge()+userEntity2.getAge());
return userEntity1;
}
});
System.out.println(sum);
}
Stream求最大最小
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Stream<UserEntity> stream=userEntities.stream();
Optional<UserEntity> min = stream.min(new Comparator<UserEntity>() {
@Override
public int compare(UserEntity o1, UserEntity o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(min.get());
//簡化版
Optional<UserEntity> min1 = stream.min((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println(min1.get());
}
Stream Match 匹配
anyMatch表示,判斷的條件里,任意一個元素成功,返回true
allMatch表示,判斷條件里的元素,所有的都是,返回true
noneMatch跟allMatch相反,判斷條件里的元素,所有的都不是,返回true
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Stream<UserEntity> stream=userEntities.stream();
boolean b = stream.anyMatch(new Predicate<UserEntity>() {
@Override
public boolean test(UserEntity userEntity) {
return "aa".equals(userEntity.getName());
}
});
System.out.println(b);
//簡化版
boolean b1 = stream.anyMatch((userEntity) -> "aa".equals(userEntity.getName()));
System.out.println(b1);
}
Stream for循環
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Stream<UserEntity> stream=userEntities.stream();
stream.forEach((userEntity -> System.out.println(userEntity)));
}
Stream filter過濾器
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Stream<UserEntity> stream=userEntities.stream();
stream.filter(new Predicate<UserEntity>() {
@Override
public boolean test(UserEntity userEntity) {
return "aa".equals(userEntity.getName()) && userEntity.getAge() >= 18;
}
}).forEach((userEntity -> System.out.println(userEntity)));
//精簡版
stream.filter((userEntity)->"aa".equals(userEntity.getName()) && userEntity.getAge() >= 18)
.forEach((userEntity -> System.out.println(userEntity) ));
}
Stream limit和skip
Limit 從頭開始獲取
Skip 就是跳過
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("aa", 20));
userEntities.add(new UserEntity("bb", 28));
userEntities.add(new UserEntity("cc", 35));
userEntities.add(new UserEntity("dd", 16));
Stream<UserEntity> stream = userEntities.stream();
stream.skip(2).limit(2).forEach((userEntity -> System.out.println(userEntity)));
}
stream 綜合案例
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("mayikt", 20));
userEntities.add(new UserEntity("meite", 28));
userEntities.add(new UserEntity("zhangsan", 35));
userEntities.add(new UserEntity("xiaowei", 16));
userEntities.add(new UserEntity("mayikt_list", 109));
userEntities.add(new UserEntity("mayikt_zhangsan", 110));
userEntities.add(new UserEntity("lisi", 109));
userEntities.add(new UserEntity("mayikt", 100));
userEntities.add(new UserEntity("mayikt", 60));
Stream<UserEntity> stream=userEntities.stream();
stream.sorted((o1,o2)->o1.getAge()-o2.getAge())
.filter((userEntity -> "mayikt".equals(userEntity.getName())))
.limit(3)
.forEach((userEntity)-> System.out.println(userEntity));
}
並行流與串行流區別
串行流:單線程的方式操作; 數據量比較少的時候。
並行流:多線程方式操作;數據量比較大的時候
原理:Fork join 將一個大的任務拆分n多個小的子任務並行執行,最后在統計結果,有可能會非常消耗cpu的資源,確實可以提高效率。
注意:數據量比較少的情況下,不要使用並行流
方法引用
什么是方法引入
方法引入:需要結合lambda表達式能夠讓代碼變得更加精簡
-
靜態方法引入: 類名::(靜態)方法名稱
-
對象方法引入 類名:: 實例方法名稱
-
實例方法引入 new對象 對象實例::方法引入
-
構造函數引入 類名::new
需要遵循一個規范:
方法引入 方法參數列表、返回類型與函數接口參數列表與返回類型必須要保持一致。
靜態方法引入
/*
* 靜態方法引入
* */
public class Test01 {
public static void main(String[] args) {
MyFunctionalInterface myFunctionalInterface = () -> {
/*引入getStaticMethod方法*/
Test01.getStaticMethod();
};
myFunctionalInterface.get();
// 使用方法引入調用方法 必須滿足:方法引入的方法必須和函數接口中的方法參數列表/返回值一定保持一致。
MyFunctionalInterface messageInterface = Test01::getStaticMethod;
messageInterface.get();
}
public static void getStaticMethod() {
System.out.println("我是 getMethod");
}
}
實例對象方法引入
public class Test02 {
public static void main(String[] args) {
Test02 test02=new Test02();
MyFunctionalInterface myFunctionalInterface = () -> {
/*引入getStaticMethod方法*/
test02.getStaticMethod();
};
myFunctionalInterface.get();
// 精簡版
MyFunctionalInterface messageInterface = test02::getStaticMethod;
messageInterface.get();
}
public void getStaticMethod() {
System.out.println("我是 getMethod2");
}
}
構造函數引入
public static void main(String[] args) {
UserInterface userInterface=new UserInterface() {
@Override
public UserEntity getUser() {
return new UserEntity();
}
};
//精簡版
UserInterface userInterface3=UserEntity::new;
userInterface2.getUser();
}
對象方法引入
public class Test04 {
public static void main(String[] args) {
Myservice myservice=new Myservice() {
@Override
public String get(Test04 test04) {
return test04.objGet();
}
};
Myservice myservice1=(Test04-> Test04.objGet());
//精簡版 傳入Test04 返回string值
Myservice myservice2=Test04::objGet;
Function<String,Integer> function=new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
};
//精簡版
Function<String,Integer> function2=String::length;
System.out.println(function2.apply("dfdf"));
}
@FunctionalInterface
public interface Myservice {
String get(Test04 userEntity);
}
JDK8Optional
Optional 類是一個可以為null的容器對象。如果值存在則isPresent()方法會返回true,調用get()方法會返回該對象。
Optional 是個容器:它可以保存類型T的值,或者僅僅保存null。Optional提供很多有用的方法,這樣我們就不用顯式進行空值檢測。
Optional 類的引入很好的解決空指針異常。
判斷參數是否為空
ofNullable(可以傳遞一個空對象)
Of(不可以傳遞空對象)
public static void main(String[] args) {
String username=null;
Integer a1 = 1;
Optional<Integer> a = Optional.ofNullable(a1);
System.out.println(a.isPresent());//true
Optional<String> username1 = Optional.ofNullable(username);
System.out.println(username1.isPresent());//false
}
isPresent表示結果返回是否為空, true 不為空,返回 false 為空
參數為空可以設定默認值
public static void main(String[] args) {
Integer a1 = null;
Integer a = Optional.ofNullable(a1).orElse(10);
System.out.println(a);//10
}
參數實現過濾
public static void main(String[] args) {
Integer a1 = 16;
Optional<Integer> a = Optional.ofNullable(a1);
//判斷是否等於16
boolean present = a.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer.equals(16);
}
}).isPresent();
System.out.println(present);//true
boolean isPresent = a.filter(a2 -> a2==17).isPresent();
System.out.println(isPresent);//false
}
與Lambda表達式結合使用,優化代碼
優化方案1
public static void main(String[] args) {
// 優化前
String name = "meite";
if (name != null) {
System.out.println(name);
}
//優化后
Optional<String> name2 = Optional.ofNullable(name);
// 當value 不為空時,則不會調用
name2.ifPresent(s -> System.out.println(s));
name2.ifPresent(System.out::print);
}
優化方案2
public class Test05 {
private static UserEntity userEntity = null;
public static void main(String[] args) {
UserEntity userEntity = Test05.getOrder();
System.out.println(userEntity);
}
public static UserEntity getOrder() {
// 優化前
if (userEntity == null) {
return createOrder();
}
return userEntity;
//優化1
return Optional.ofNullable(Test05.userEntity).orElseGet(new Supplier<UserEntity>() {
@Override
public UserEntity get() {
return createOrder();
}
});
//優化2
return Optional.ofNullable(Test05.userEntity).orElseGet(()-> {
Test05.userEntity =createOrder();
return Test05.userEntity;
});
//精簡版
return Optional.ofNullable(Test05.userEntity).orElseGet(() -> createOrder());
}
private static UserEntity createOrder() {
return new UserEntity("ylc", 12);
}
}
優化方案3
public class Test06 {
public static void main(String[] args) {
String orderName = Test06.getOrderName();
System.out.println(orderName);
}
public static String getOrderName() {
// 優化前寫法:
UserEntity userEntity = new UserEntity("123456", 19);
if (userEntity != null) {
String userEntityName = userEntity.getName();
if (userEntityName != null) {
return userEntityName.toLowerCase();
}
}
//優化后
Optional<String> s1 = Optional.ofNullable(userEntity)
.map((s) -> s.getName())
.map((s) -> s.toLowerCase());
return s1.get();
}
}
