Maison  >  Article  >  Java  >  Introduction détaillée aux nouvelles fonctionnalités du JDK8

Introduction détaillée aux nouvelles fonctionnalités du JDK8

王林
王林avant
2019-11-26 13:45:053000parcourir

Introduction détaillée aux nouvelles fonctionnalités du JDK8

Programmation fonctionnelle

L'orientation objet souligne que "tout est un objet". pour le faire avec. La réflexion sur la programmation fonctionnelle met l'accent sur « quoi faire » plutôt que sur « comment le faire ».

Fil d'ouverture ordinaire

// 匿名内部类对象
Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("乌鸦坐飞机");
    }
};
new Thread(task).start();

Plus de didacticiels vidéo gratuits sur Java : Tutoriel en ligne Java

Fonction Ouvrir un fil avec programmation

new Thread(() -> System.out.println("龙卷风摧毁停车场")).start();

Les parenthèses devant : paramètres de méthode S'il n'y a pas de paramètres, écrivez () La flèche pointe vers ce qui doit être fait plus tard. attelle corporelle, qui représente le spécifique Que faire.

Expression Lambda

L'expression Lambda, également connue sous le nom de fermeture, est la nouvelle fonctionnalité la plus importante à l'origine de la sortie de Java 8.

Lambda permet de passer des fonctions en tant que paramètres d'une méthode (les fonctions sont passées en méthodes en tant que paramètres). L'utilisation d'expressions lambda peut rendre votre code plus concis et compact.

Trois éléments : paramètres, flèches, code

Format : (nom du paramètre de type de paramètre) -> Le principe de la formule : il doit y avoir une interface et il doit y avoir une et une seule méthode abstraite dans l'interface

Démonstration : Écrivez une interface Cook, et il y a une méthode makeFood() dans l'interface

public static void main(String[] args) {
    method(() -> {
        System.out.println("闪刀启动!");
    });
}
 
private static void method(Cook cook) {
    cook.makeFood();
}

Expression Lambda Règles d'omission de formule :

Le type de paramètre peut être omis. Mais vous ne pouvez omettre que les types de tous les paramètres en même temps, ou ne pas les omettre du tout. S'il y a un et un seul paramètre, alors les parenthèses peuvent être omises. S'il y a une et une seule instruction entre les accolades, alors, qu'il y ait ou non une valeur de retour, return, accolades, les parenthèses et les points-virgules peuvent être omis.

    public static void main(String[] args) {
        method((a, b)-> a + b);
    }
 
    private static void method(Calculator calculator) {
        int result = calculator.sum(1234, 9876);
        System.out.println(result);
    }

Lorsque vous créez une interface, vous pouvez également utiliser des expressions lambda au lieu de classes internes anonymes

Runnable task = () -> System.out.println("闪刀启动!");
new Thread(task).start();

Interface fonctionnelle

L'interface a et Il y a une seule méthode abstraite, appelée interface fonctionnelle.

Il y a une nouvelle annotation

dans JDK8, qui est utilisée pour détecter si une interface est une interface fonctionnelle. S'il ne s'agit pas d'une interface fonctionnelle, une erreur sera signalée lors de la compilation. L'annotation @FunctionalInerface est facultative Même si cette annotation n'est pas utilisée, tant que l'interface répond aux exigences de définition d'une interface fonctionnelle, elle reste une interface fonctionnelle.

@FunctionalInterface
public interface MyInterface {
    void method();
}
@FunctionalInterface

Référence de la méthode

Ce code peut en fait être abrégé.

Printer printer = (str) -> System.out.println(str);Tant qu'il est déductible, il est référençable, donc passer des paramètres n'a pas vraiment de sens, donc ici vous pouvez réellement utiliser des références de méthode pour abréger

System.out::printlnÀ partir de java8, un L'expression dans l'opérateur new, l'opérateur de référence de méthode (deux deux-points écrits successivement), est une référence de méthode. L'essence de la référence de méthode et de Lambda est exactement la même, et le but est de simplifier l'écriture des expressions Lambda.

Méthode d'écriture Lambda :

s->System.out.println(s)Méthode d'écriture de référence de méthode :

System.out::printlnLes deux méthodes d'écriture sont complètement équivalentes

 
    public static void main(String[] args) {
        method(System.out::println);
    }
 
    private static void method(Printer printer) {
        printer.print("hello");
    }

Interface

méthode par défaut

L'interface avait à l'origine deux méthodes abstraites, mais elle doit maintenant être transformée en trois méthodes abstraites. la classe doit également implémenter une nouvelle méthode.

Lorsqu'il y a trop de classes d'implémentation, il est très difficile à utiliser. Le JDK utilisait le mode de conception ouvert-fermé : ouvert pour les extensions et fermé pour les modifications. C'est-à-dire : créer une nouvelle interface, hériter de l'interface d'origine et définir de nouvelles méthodes. Cependant, dans ce cas, les classes d'implémentation d'origine n'ont pas de nouvelles méthodes pour le moment, la méthode par défaut de l'interface peut être utilisée.

Le mot-clé est modifié avec default et la méthode nécessite un corps de méthode. Toutes les sous-classes d'une telle méthode seront implémentées par défaut (vous n'avez pas besoin de l'écrire vous-même). Si vous souhaitez la remplacer, vous pouvez également la remplacer dans la classe d'implémentation

/**
 * 从java8开始,接口当中允许定义default默认方法
 * 修饰符:public default(public可以省略,default不能省略)
 */
public interface MyInterface {
 
    void method1();
 
    void method2();
 
    default void methodNew() {
        System.out.println("接口默认方法执行");
    }
 
}

Remarque. : La méthode par défaut dans l'interface est équivalente. Donc un nouveau mot-clé et le "par défaut" des quatre modificateurs ne sont pas le même concept.

L'utilisation du mot-clé par défaut peut permettre au programme d'obtenir l'effet « d'héritage multiple ».

Méthode statique

À partir de Java8, les méthodes statiques peuvent être définies dans les interfaces et leur utilisation est la même que celle des méthodes statiques des classes générales.

public interface Animal {
 
    void eat();
 
    static Animal getAnimal() {
        return new Cat();
    }
}

Opération de streaming

La première impression que le traitement de streaming donne aux développeurs est qu'il rend les opérations de collecte beaucoup plus simples. Habituellement, nous avons besoin de plusieurs lignes de code pour terminer l'opération. être implémenté sur une seule ligne à l’aide du traitement en streaming.

Par exemple, si nous voulons filtrer tous les nombres pairs d'une collection contenant des entiers et les encapsuler dans une nouvelle liste pour le retour, alors avant java8, nous devons l'implémenter via le code suivant :

Pour une collection de nombres :

List<Integer> evens = new ArrayList<>();
for (final Integer num : nums) {
    if (num % 2 == 0) {
        evens.add(num);
    }
}

Grâce au traitement de streaming de Java8, nous pouvons simplifier le code en :

List<Integer> evens = nums.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());

Expliquons brièvement la signification de la ligne d'instruction ci-dessus, stream() opération Convertissez la collection en flux, filter() effectue notre processus de filtrage personnalisé, ici nous filtrons tous les nombres pairs via des expressions lambda, et enfin nous encapsulons les résultats via collect() et les spécifions via Collectors.toList() Encapsulé dans un Liste de collecte et retournée.

常用操作案例:

        //初始化list集合
        List<String> list = new ArrayList<String>();
        list.add("测试数据1");
        list.add("测试数据2");
        list.add("测试数据3");
        list.add("测试数据12");
        
        //使用λ表达式遍历集合
        list.forEach(s -> System.out.println(s));
        
        //结合Predicate使用和过滤条件筛选元素
        Predicate<String> contain1 = n -> n.contains("1");
        Predicate<String> contain2 = n -> n.contains("2");
        
        //根据条件遍历集合
        list.stream().filter(contain1).forEach(n -> System.out.println(n));
        list.stream().filter(s -> contain1.test(s)).forEach(s -> System.out.println(s));
        list.stream().filter(contain1.and(contain2)).forEach(n -> System.out.println(n));
        list.stream().filter(contain1.or(contain2)).forEach(n -> System.out.println(n));
        
        //将过滤后的元素重新放到一个集合中
        List<String> newList = list.stream().filter(contain1.and(contain2)).collect(Collectors.toList());
        
集合中decimal求和
		BigDecimal sum = list
				.stream()
				.map(Person::getAmount)
				.reduce(BigDecimal::add)
				.get();
 
//排序 , 也需要新的集合接收
	List<Student> resultList = new ArrayList<Student>();
	resultList = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList())

推荐java相关文章:java零基础入门

欢迎大家一起来学习!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer