Maison  >  Article  >  Java  >  Classe facultative, une nouvelle fonctionnalité de Java 8

Classe facultative, une nouvelle fonctionnalité de Java 8

黄舟
黄舟original
2017-02-23 10:30:321903parcourir

Résumé : Facultatif ne remplace pas le mot-clé null, mais fournit une implémentation plus élégante du jugement nul

NullPointException peut être considérée comme une exception que tous les programmeurs Java ont rencontrée, bien que Java ait essayé. pour libérer les programmeurs de la souffrance des pointeurs dès le début de leur conception, les pointeurs existent réellement, et les concepteurs Java ne peuvent que rendre les pointeurs plus simples et plus faciles à utiliser dans le langage Java, mais ne peuvent pas les éliminer complètement, nous avons donc les mots-clés

null

que nous voyons tous les jours.

L'exception de pointeur nul est une exception d'exécution. Pour ce type d'exception, s'il n'y a pas de stratégie de gestion claire, la meilleure pratique consiste à laisser le programme raccrocher plus tôt. Cependant, dans de nombreux scénarios, les développeurs ne le font pas. avoir une stratégie de gestion spécifique, mais pas du tout conscient de l'existence d'une exception de pointeur nul. Lorsqu'une exception se produit, la stratégie de traitement est également très simple. Il suffit d'ajouter un jugement d'instruction if là où l'exception existe. Cependant, une telle stratégie de réponse entraînera l'apparition de plus en plus de jugements nuls dans notre programme. devrait minimiser l'apparition du mot-clé null dans le code, et la classe

Optional

fournie par java8 réduit non seulement NullPointException, mais améliore également la beauté du code. Mais nous devons d'abord préciser qu'il ne s'agit pas d'un remplacement du mot-clé , mais qu'il fournit une implémentation plus élégante de la détermination nulle pour éviter NullPointException

null
.

1. Expérience intuitive

Supposons que nous devions renvoyer la longueur d'une chaîne si nous n'utilisons pas de classe d'outils tiers, nous devons appeler <.>

Méthode :
str.length()

if(null == str) { // Détermination du pointeur nul
return 0;
}
return str.length();
Si vous utilisez la classe Optionnel, l'implémentation est la suivante :

return Optionnel.ofNullable(str).map(String::length).orElse(0);
Le code facultatif est relativement plus concis. Lorsque la quantité de code est importante, nous oublions facilement de vérifier null, mais l'utilisation de la classe Optionnelle évitera ce genre de problème.



2. Utilisation de base

1. Création d'objet

Créer un objet vide

Facultatif8d4bc246b6d7e089a798b557166bf8fb null, l'exception Throws NullPointException

Créer un objet : autorisé à être vide
Si vous n'êtes pas sûr que le paramètre passé ait la possibilité d'une valeur nulle, vous pouvez utiliser facultatif

La méthode

crée un objet. Si le paramètre d'entrée est nul, un objet vide est créé. Un exemple est le suivant :
ofNullable()

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 optStr = Optionnel.ofNullable(str); // Si str est nul, créez un objet vide


2. 🎜>

Le traitement en streaming est également une nouvelle fonctionnalité importante apportée par Java8, qui rend notre fonctionnement des collections plus concis et efficace. Le prochain article sur les nouvelles fonctionnalités de Java8 fournira une introduction complète au traitement du désabonnement. Facultatif ici, il fournit également deux traitements de désabonnement de base : le mappage et le filtrage.

Pour la démonstration, nous avons conçu une classe



, comme suit :

User



Le téléphone portable et l'adresse e-mail ne sont pas nécessaires pour une personne, nous utilisons donc la définition facultative.

/**
 * @author: zhenchao.Wang 2016-9-24 15:36:56
 */
public class User {
    /** 用户编号 */
    private long id;
    private String name;
    private int age;
    private Optional<Long> phone;
    private Optional<String> email;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 省略setter和getter
}

Mapping : map et flatMap

Le mappage est une opération qui convertit l'entrée en une autre forme de sortie. Par exemple, dans l'exemple précédent, nous saisissons une chaîne et sortons. est la longueur de la chaîne, qui est une sorte de réflexion implicite. Nous utilisons la méthode


pour y parvenir. Supposons que nous voulions obtenir le nom d'une personne, alors nous pouvons l'implémenter comme suit :

map()
String name =Optional.ofNullable(user).map(User::getName).orElse("no name");

De cette façon, lorsque le paramètre d'entrée user n'est pas vide, son nom sera renvoyé, sinon


sera renvoyé Si nous voulons obtenir le téléphone ou l'e-mail via la méthode ci-dessus, le. La méthode ci-dessus ne fonctionnera pas, car après map, ce qui est renvoyé est facultatif, que nous appelons imbrication facultative. Nous devons mapper une fois pour obtenir les résultats souhaités :

no name
long phone = optUser.map(User::getPhone) .map( Facultatif::get).orElse(-1L);

En fait, à l'heure actuelle, une meilleure façon est d'utiliser flatMap pour obtenir les résultats souhaités en une seule étape :

téléphone long = optUser.flatMap(User ::getPhone).orElse(-1L);
flapMap peut aplatir chaque flux renvoyé par la méthode en un seul flux, qui sera détaillé dans le prochain article dédié au traitement des flux.


Filtre : filtre

filiter, comme son nom l'indique, est une opération de filtrage Nous pouvons transmettre l'opération de filtrage en tant que paramètre à cette méthode pour atteindre l'objectif de. filtrage. Ajoutez ce que nous espérons Pour filtrer les adultes de plus de 18 ans, vous pouvez mettre en œuvre les éléments suivants :



3. le comportement est lorsque Facultatif ne remplit pas les conditions L'opération effectuée, comme le

que nous avons utilisé dans l'exemple ci-dessus
orElse()

就是一个默认操作,用于在Optional对象为空时执行特定操作,当然也有一些默认操作是当满足条件的对象存在时执行的操作。

get()

get用于获取变量的值,但是当变量不存在时则会抛出

NoSuchElementException

,所以如果不确定变量是否存在,则不建议使用

orElse(T other)

当Optional的变量不满足给定条件时,则执行orElse,比如前面当str为null时,返回0。

orElseGet(Supplier<? extends X> expectionSupplier)

如果条件不成立时,需要执行相对复杂的逻辑,而不是简单的返回操作,则可以使用orElseGet实现:

long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> {
    // do something here
    return -1L;
});
orElseThrow(Supplier<? extends X> expectionSupplier)

与get()方法类似,都是在不满足条件时返回异常,不过这里我们可以指定返回的异常类型。

ifPresent(Consumer117c5a0bdb71ea9a9d0c2b99b03abe3e)

当满足条件时执行传入的参数化操作。

三. 注意事项

Optional是一个final类,未实现任何接口,所以当我们在利用该类包装定义类的属性的时候,如果我们定义的类有序列化的需求,那么因为Optional没有实现Serializable接口,这个时候执行序列化操作就会有问题:

public class User implements Serializable{
    /** 用户编号 */
    private long id;
    private String name;
    private int age;
    private Optional<Long> phone;  // 不能序列化
    private Optional<String> email;  // 不能序列化

不过我们可以采用如下替换策略:

private long phone;
public Optional<Long> getPhone() {
    return Optional.ofNullable(this.phone);
}

看来Optional在设计的时候就没有考虑将它作为类的字段使用~

 以上就是Java8 新特性之 Optional 类 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn