Réflexion: Comment utiliser une interface fonctionnelle pour vos propres fonctions (java)

en premier

Même si vous pouvez utiliser des expressions lambda dans des flux, etc., il peut y avoir des personnes qui ne peuvent pas utiliser l'interface fonctionnelle pour leurs propres fonctions. Pour ces personnes, je voudrais présenter comment appliquer une interface fonctionnelle à une fonction auto-créée à l'aide d'un exemple simple.

exemple

Il est courant de copier les propriétés d'un objet dans un autre. A ce moment, il arrive souvent que la condition de copie soit définie uniquement lorsque la valeur de la propriété n'est pas nulle. Et, comme dans cet exemple, des copies de diverses propriétés de type sont souvent alignées. Il peut y avoir des cas où vous pouvez copier et coller de cette manière, mais je voudrais imaginer un peu. Créons une fonction commune pour le code suivant afin de simplifier l'appel. Notez que getName () renvoie une chaîne et setName () définit une chaîne. getFlag () renvoie Boolean et setFlag () définit Boolean.

if(objA.getName()!=null) {
    objB.setName(objA.getName());
}
if(objA.getFlag()!=null) {
    objB.setFlag(objA.getFlag());
}

Pseudo code

J'espère que vous pourrez l'écrire comme suit. Voyons comment cela est réalisé en java.

setIfNotNull(value,func) {
    if(value!= null) {
        func(value);
    }
}
setIfNotNull(objA.getName(),objB.setName);
setIfNotNull(objA.getFlag(),objB.setFlag);

Réponse en utilisant l'interface (exemple qui ne fonctionne pas)

Dans le pseudo code ci-dessus, func montre une méthode, mais comment doit-elle être exprimée en java? Une interface est ce qui indique une méthode. Encore une fois, cela peut être possible avec une interface.

public interface SetNameInterface {
    void setName(String value);
}

public Class ObjB implements  SetNameInterface{
    void setName(String name);
}

public void setIfNotNull(String value,SetNameInterface obj) {
    if(value!= null) {
        obj.setName(value);
    }
}

setIfNotNull(objA.getName(),objB);

Il était possible de prendre en charge setName (), mais il est clair qu'il ne peut pas supporter setFlag (). Cette méthode est intuitive, mais elle ne fonctionne pas.

Réponse en utilisant l'interface (cela fonctionne mais est redondant)

Parce que nous voulons appeler setName () et setFlag () depuis setIfNotNull () avec le nom de fonction commun func. Que diriez-vous d'avoir un objet avec func comme interface pour setName () et setFlag ()?


public Class ObjB {
	public void setName(String name) {
		System.out.println("OnjB.setName:"+name);
	}
	public void setFlag(Boolean flag) {
		System.out.println("OnjB.setFlag:"+flag);
	}
}

public interface FuncInterface<T> {
    void func(T value);
}

public class ObjBSetName implements FuncInterface<String> {
	ObjB obj;
	public ObjBSetName(ObjB obj) {
		this.obj = obj;
	}
	@Override
	public void func(String value) {
		obj.setName(value);
	}
}

public class ObjBSetFlag implements FuncInterface<Boolean> {
	ObjB obj;
	public ObjBSetFlag(ObjB obj) {
		this.obj = obj;
	}
	@Override
	public void func(Boolean value) {
		obj.setFlag(value);
	}
}

public <T>void setIfNotNull(T value,FuncInterface<T> obj) {
    if(value!= null) {
        obj.func(value);
    }
}

setIfNotNull(objA.getName(),new ObjBSetName(objB));
setIfNotNull(objA.getFlag(),new ObjBSetFlag(objB));

ObjBSetName et ObjBSetFlag ont tous deux des fonctions func définies dans l'interface FuncInterface. Lorsque la fonction func est appelée, le traitement d'origine objB.setName () et objB.setFlag () sont appelés. Dans l'interface FuncInterface, le type du paramètre passé à la méthode est déclaré comme type générique (T dans ce cas). En conséquence, setIfNotNull () modifie également value et obj pour utiliser des types génériques.

Répondre en utilisant une classe anonyme

J'ai réalisé ce que je veux faire avec cela, mais il est redondant de préparer ObjBSetName et ObjBSetFlag. Utilisons une classe anonyme.

Comment écrire une classe anonyme

nouveau nom de classe ou d'interface parente () { Contenu de classe anonyme (définitions de champs et de méthodes) };

Parce que c'est

    var objBSetName = new FuncInterface<String>() {
        @Override
        public void func(String value) {
            objB.setName(value);
        }
    };
    var objBSetFlag = new FuncInterface<Boolean>() {
        @Override
        public void func(Boolean value) {
            objB.setFlag(value);
        }
    };

Écrire, L'appel est

    setIfNotNull(objA.getName(),objBSetName);
    setIfNotNull(objA.getFlag(),objBSetFlag);

Ce sera. Dans la classe anonyme, vous pouvez référencer directement l'objet objB.

Réponse en utilisant la formule lambda

Pour les interfaces avec une seule fonction définie, la classe anonyme peut être remplacée par une expression lambda, donc

    FuncInterface<String> objBSetName = (v) -> objB.setName(v);
    FuncInterface<Boolean> objBSetFlag = (v) -> objB.setFlag(v);

Peut être réécrit comme. L'expression lambda n'a pas la notation func, mais elle implémente la fonction définie dans FuncInterface. Il est difficile de voir que func a disparu dans l'expression lambda, mais vous pouvez le comprendre en le comparant à la classe anonyme.

Omettez la variable plus loin,

    setIfNotNull(objA.getName(),(v) -> objB.setName(v));
    setIfNotNull(objA.getFlag(),(v) -> objB.setFlag(v));

Peut être résumé comme.

Répondre à l'aide d'une interface fonctionnelle

À propos, la déclaration de l'interface appelée FuncInterface est en fait une interface fonctionnelle. Le consommateur existe déjà, alors remplaçons-le par celui-ci. (Avant de créer votre propre interface, c'est une bonne idée de vérifier si l'interface fonctionnelle fournie peut être utilisée.)

public <T>void setIfNotNull(T value,Consumer<T> obj) {
    if(value!= null) {
        obj.accept(value);
    }
}

De plus, comme il a un argument, l'appel peut être effectué à l'aide d'une référence de méthode.

    setIfNotNull(objA.getName(),objB::setName);
    setIfNotNull(objA.getFlag(),objB::setFlag);

Ce sera. C'était plutôt chouette.

Résumé

Cette fois, j'ai expliqué avec un petit exemple, mais vous pouvez voir que le "traitement" peut être passé à la fonction. Je pense. La déclaration pour cela est "l'interface fonctionnelle". Vous avez peut-être déjà imaginé que vous pourriez l'utiliser pour réaliser un «modèle de stratégie». Veuillez l'appliquer à votre programme et réutiliser le programme.

Recommended Posts

Réflexion: Comment utiliser une interface fonctionnelle pour vos propres fonctions (java)
Comment lire votre propre fichier YAML (*****. Yml) en Java
Comment créer votre propre annotation en Java et obtenir la valeur
Comment appeler des fonctions en bloc avec la réflexion Java
Résumé de la mise en œuvre des arguments par défaut en Java
[Forge] Comment enregistrer votre propre Entité et Entité Render dans 1.13.2
Comment dériver le dernier jour du mois en Java
Comment apprendre JAVA en 7 jours
Gérez vos propres annotations en Java
Comment utiliser les classes en Java?
Comment nommer des variables en Java
Comment concaténer des chaînes avec Java
Comprendre comment la programmation fonctionnelle a été introduite dans Java d'un seul coup
Comment obtenir la longueur d'un fichier audio avec Java
Comment incrémenter la valeur de Map sur une ligne en Java
Comment implémenter le calcul de la date en Java
Comment implémenter le filtre de Kalman par Java
Prise en charge multilingue de Java Comment utiliser les paramètres régionaux
[java] Résumé de la gestion des caractères
Comment faire une conversion de base en Java
Comment appliquer les conventions de codage en Java
Comment intégrer Janus Graph dans Java
[Java] [Maven3] Résumé de l'utilisation de Maven3
Comment obtenir la date avec Java
Comment obtenir le chemin absolu d'un répertoire s'exécutant en Java
Créez vos propres raccourcis avec Xcode pour éliminer les travaux d'installation compliqués des pods
La première année de vie professionnelle a résumé comment passer l'examen Java Bronze
Résumé de la sélection des éléments dans Selenium
[java] Résumé de la gestion des chaînes de caractères
Comment afficher une page Web en Java
[Java] Résumé de la façon d'omettre les expressions lambda
Comment obtenir une classe depuis Element en Java
Comment masquer les champs nuls en réponse en Java
Comment utiliser JQuery dans Rails 6 js.erb
Comment résoudre les problèmes d'expression en Java
Comment écrire Java String # getBytes dans Kotlin?
Comment obtenir le nom de classe de l'argument de LoggerFactory.getLogger lors de l'utilisation de SLF4J en Java
[Java] Comment afficher les jours acquis par LocalDate et DateTimeformatter en japonais
Résumé de l'utilisation du jeu de proxy dans IE lors de la connexion avec Java
[Java] Comment obtenir l'URL de la source de transition
Comment créer un environnement Java en seulement 3 secondes
[Java] Comment omettre le constructeur privé dans Lombok
Comment écrire Scala du point de vue de Java
[Java] Types de commentaires et comment les rédiger
Comment entrer / sortir des fichiers mainframe IBM en Java?
[Java] Comment obtenir la valeur maximale de HashMap
À partir d'avril 2018 Comment installer Java 8 sur Mac
Comment utiliser CommandLineRunner dans Spring Batch of Spring Boot
Résumé de l'API de communication Java (3) Comment utiliser SocketChannel
Comment convertir A en A et A en A en utilisant le produit logique et la somme en Java
Comment Git gérer les projets Java EE dans Eclipse
Résumé de l'API de communication Java (2) Comment utiliser HttpUrlConnection
Comment mettre l'ancien Java (série 8) dans macOS 10.15 Catalina
Comment exécuter l'exemple WebCamCapture de NyARToolkit pour Java
Remarques sur l'utilisation des expressions régulières en Java
Considérer l'adoption du langage Java à l'ère Reiwa ~ Comment choisir un SDK sûr
Fonctions Azure en Java
Comment obtenir le nom d'une classe / méthode exécutée en Java