La fonction Lambda de Java 8 qui fait exception?
je sais comment créer une référence à une méthode qui a un paramètre String
et renvoie un int
, c'est:
Function<String, Integer>
cependant, cela ne fonctionne pas si la fonction lance une exception, dire qu'il est défini comme:
Integer myMethod(String s) throws IOException
comment définirais-Je cette référence?
23 réponses
vous aurez besoin de faire l'un des suivants.
-
si c'est votre code, alors définissez votre propre interface fonctionnelle qui déclare l'exception cochée
@FunctionalInterface public interface CheckedFunction<T, R> { R apply(T t) throws IOException; }
et l'utiliser
void foo (CheckedFunction f) { ... }
-
sinon, envelopper
Integer myMethod(String s)
dans une méthode qui ne déclare pas une exception cochée:public Integer myWrappedMethod(String s) { try { return myMethod(s); } catch(IOException e) { throw new UncheckedIOException(e); } }
puis
Function<String, Integer> f = (String t) -> myWrappedMethod(t);
ou
Function<String, Integer> f = (String t) -> { try { return myMethod(t); } catch(IOException e) { throw new UncheckedIOException(e); } };
vous pouvez en fait prolonger Consumer
(et Function
etc.) avec une nouvelle interface qui gère les exceptions -- en utilisant les méthodes par défaut de Java 8 !
Considérer cette interface (s'étend Consumer
):
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
@Override
default void accept(final T elem) {
try {
acceptThrows(elem);
} catch (final Exception e) {
// Implement your own exception handling logic here..
// For example:
System.out.println("handling an exception...");
// Or ...
throw new RuntimeException(e);
}
}
void acceptThrows(T elem) throws Exception;
}
ensuite, par exemple, si vous avez une liste:
final List<String> list = Arrays.asList("A", "B", "C");
si vous voulez le consommer (par ex. avec forEach
) avec un code qui lance des exceptions, vous ont traditionnellement mis en place un bloc d'essai/prise:
final Consumer<String> consumer = aps -> {
try {
// maybe some other code here...
throw new Exception("asdas");
} catch (final Exception ex) {
System.out.println("handling an exception...");
}
};
list.forEach(consumer);
mais avec cette nouvelle interface, vous pouvez l'instancier avec une expression lambda et le compilateur ne se plaindra pas:
final ThrowingConsumer<String> throwingConsumer = aps -> {
// maybe some other code here...
throw new Exception("asdas");
};
list.forEach(throwingConsumer);
ou même tout simplement mouler pour être plus succinct!:
list.forEach((ThrowingConsumer<String>) aps -> {
// maybe some other code here...
throw new Exception("asda");
});
mise à jour : on dirait qu'il y a une très belle bibliothèque utilitaire partie de Durian appelé erreurs qui peut être utilisé pour résoudre ce problème avec beaucoup plus de flexibilité. Par exemple, dans mon implémentation ci-dessus, j'ai explicitement défini la Politique de gestion des erreurs ( System.out...
ou throw RuntimeException
), alors que les erreurs de Durian vous permettent d'appliquer une politique à la volée via une large série de méthodes utilitaires. Merci pour partager , @NedTwigg!.
exemple d'utilisation:
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
je pense Durian Errors
classe combine plusieurs des avantages des diverses suggestions ci-dessus.
- envelopper une fonction lancer à une interface fonctionnelle Java 8 standard.
- spécifier facilement diverses politiques pour traiter les erreurs "
- quand on enroule une méthode qui renvoie une valeur, il y a une distinction importante entre spécifier une valeur par défaut ou repenser une RuntimeException.
- versions de lancement des interfaces fonctionnelles de Java 8
- similaire à réponse de fge
- interfaces Standard pour lancer des exceptions spécifiques
- qui répond à préoccupation de Zoltán
pour inclure Durian dans votre projet, vous pouvez soit:
- saisir jcenter ou maven central à
com.diffplug.durian:durian:3.3.0
- ou simplement copier coller juste deux petites classes dans votre code:
Throwing.java
etErrors.java
ceci n'est pas spécifique à Java 8. Vous essayez de compiler quelque chose d'équivalent à:
interface I {
void m();
}
class C implements I {
public void m() throws Exception {} //can't compile
}
avertissement: Je n'ai pas encore utilisé Java 8, seulement lu à ce sujet.
Function<String, Integer>
ne lance pas IOException
, donc vous ne pouvez pas mettre de code que throws IOException
. Si vous appelez une méthode qui attend un Function<String, Integer>
, alors la lambda que vous passez à cette méthode ne peut pas jeter IOException
, période. Vous pouvez soit écrire un lambda comme ceci (je pense que c'est la syntaxe lambda, pas sûr):
(String s) -> {
try {
return myMethod(s);
} catch (IOException ex) {
throw new RuntimeException(ex);
// (Or do something else with it...)
}
}
ou, si la méthode à laquelle vous passez la lambda est celle que vous avez écrite vous-même, vous pouvez définir une nouvelle interface fonctionnelle et l'utiliser comme le type de paramètre au lieu de Function<String, Integer>
:
public interface FunctionThatThrowsIOException<I, O> {
O apply(I input) throws IOException;
}
si vous n'avez pas l'esprit d'utiliser un tiers lib ( Vavr ) vous pouvez écrire
CheckedFunction1<String, Integer> f = this::myMethod;
il a également le soi-disant Try monad qui traite les erreurs:
Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
.map(i -> ...) // only executed on Success
...
s'il vous plaît lire la suite ici .
clause de non-responsabilité: je suis le créateur de Vavr.
vous pouvez utiliser unthrow wrapper
Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));
ou
Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
vous pouvez.
extension du UtilException
de @marcg et ajout du <E extends Exception>
générique lorsque nécessaire: de cette façon, le compilateur vous forcera à nouveau à ajouter des clauses de rejet et tout se passe comme si vous pouviez lancer des exceptions vérifiées nativement sur les flux de java 8.
public final class LambdaExceptionUtil {
@FunctionalInterface
public interface Function_WithExceptions<T, R, E extends Exception> {
R apply(T t) throws E;
}
/**
* .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
*/
public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E {
return t -> {
try {
return function.apply(t);
} catch (Exception exception) {
throwActualException(exception);
return null;
}
};
}
@SuppressWarnings("unchecked")
private static <E extends Exception> void throwActualException(Exception exception) throws E {
throw (E) exception;
}
}
public class LambdaExceptionUtilTest {
@Test
public void testFunction() throws MyTestException {
List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList());
assertEquals(2, sizes.size());
assertEquals(4, sizes.get(0).intValue());
assertEquals(5, sizes.get(1).intValue());
}
private Integer transform(String value) throws MyTestException {
if(value==null) {
throw new MyTestException();
}
return value.length();
}
private static class MyTestException extends Exception { }
}
j'ai eu ce problème avec la Classe.forName et de la Classe.nouvelle substance à l'intérieur d'un lambda, donc je viens de faire:
public Object uncheckedNewInstanceForName (String name) {
try {
return Class.forName(name).newInstance();
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
dans la lambda, au lieu d'appeler la classe.forName("maclasse").newInstance () je viens d'appeler uncheckedNewInstanceForName ("myClass")
vous pouvez cependant créer votre propre Interfacefonctionnel qui lance comme ci-dessous..
@FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
void accept(T instance) throws X;
}
puis l'implémenter en utilisant Lambdas ou références comme indiqué ci-dessous.
import java.io.FileWriter;
import java.io.IOException;
//lambda expressions and the execute around method (EAM) pattern to
//manage resources
public class FileWriterEAM {
private final FileWriter writer;
private FileWriterEAM(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
private void close() throws IOException {
System.out.println("close called automatically...");
writer.close();
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
//...
public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException {
final FileWriterEAM writerEAM = new FileWriterEAM(fileName);
try {
block.accept(writerEAM);
} finally {
writerEAM.close();
}
}
public static void main(final String[] args) throws IOException {
FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet"));
FileWriterEAM.use("eam2.txt", writerEAM -> {
writerEAM.writeStuff("how");
writerEAM.writeStuff("sweet");
});
FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt);
}
void writeIt() throws IOException{
this.writeStuff("How ");
this.writeStuff("sweet ");
this.writeStuff("it is");
}
}
une autre solution utilisant une fonction wrapper serait de retourner soit une instance d'un wrapper de votre résultat, dire succès, si tout allait bien, soit une instance de, disons échec.
un code pour clarifier les choses:
public interface ThrowableFunction<A, B> {
B apply(A a) throws Exception;
}
public abstract class Try<A> {
public static boolean isSuccess(Try tryy) {
return tryy instanceof Success;
}
public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) {
return a -> {
try {
B result = function.apply(a);
return new Success<B>(result);
} catch (Exception e) {
return new Failure<>(e);
}
};
}
public abstract boolean isSuccess();
public boolean isError() {
return !isSuccess();
}
public abstract A getResult();
public abstract Exception getError();
}
public class Success<A> extends Try<A> {
private final A result;
public Success(A result) {
this.result = result;
}
@Override
public boolean isSuccess() {
return true;
}
@Override
public A getResult() {
return result;
}
@Override
public Exception getError() {
return new UnsupportedOperationException();
}
@Override
public boolean equals(Object that) {
if(!(that instanceof Success)) {
return false;
}
return Objects.equal(result, ((Success) that).getResult());
}
}
public class Failure<A> extends Try<A> {
private final Exception exception;
public Failure(Exception exception) {
this.exception = exception;
}
@Override
public boolean isSuccess() {
return false;
}
@Override
public A getResult() {
throw new UnsupportedOperationException();
}
@Override
public Exception getError() {
return exception;
}
}
Un cas d'utilisation simple :
List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
collect(Collectors.toList());
ce problème me dérange aussi; c'est pourquoi j'ai créé ce projet .
avec elle vous pouvez faire:
final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
il y a un total de 39 interfaces définies par le JDK qui ont un tel équivalent Throwing
; ce sont toutes les @FunctionalInterface
utilisées dans les flux (la base Stream
mais aussi IntStream
, LongStream
et DoubleStream
).
et comme chacun d'eux s'étendent leur contrepartie non lanceur, vous pouvez les utiliser directement dans lambdas ainsi:
myStringStream.map(f) // <-- works
le comportement par défaut est que lorsque votre LAMBDA jeter une exception vérifiée, un ThrownByLambdaException
est lancé avec l'exception vérifiée comme cause. Vous pouvez donc capturer cela et obtenir la cause.
d'Autres fonctionnalités sont également disponibles.
vous pouvez utiliser ET pour cela. ET est une petite bibliothèque Java 8 pour la conversion/traduction d'exception.
avec ET il ressemble à ceci:
// Do this once
ExceptionTranslator et = ET.newConfiguration().done();
...
// if your method returns something
Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t));
// if your method returns nothing
Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t));
Les instances ExceptionTranslator
sont sécurisées et peuvent être partagées par plusieurs composants. Vous pouvez configurer des règles de conversion d'exception plus spécifiques (par exemple FooCheckedException -> BarRuntimeException
) si vous le souhaitez.
Si aucune autre règle n'est disponible, les exceptions cochées sont automatiquement converties en RuntimeException
.
(Disclaimer: je suis l'auteur de HE)
Sournois jeter idiome permet de contourner les CheckedException
de l'expression Lambda. Envelopper un CheckedException
dans un RuntimeException
n'est pas bon pour la manipulation stricte des erreurs.
il peut être utilisé comme une fonction Consumer
utilisée dans une collection Java.
Voici une version simple et améliorée de réponse de jib .
import static Throwing.rethrow;
@Test
public void testRethrow() {
thrown.expect(IOException.class);
thrown.expectMessage("i=3");
Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
int i = e.intValue();
if (i == 3) {
throw new IOException("i=" + i);
}
}));
}
ce vient d'envelopper le lambda dans un renvoyer . Il fait CheckedException
rethrow n'importe quel Exception
qui a été jeté dans votre lambda.
public final class Throwing {
private Throwing() {}
@Nonnull
public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) {
return consumer;
}
/**
* The compiler sees the signature with the throws T inferred to a RuntimeException type, so it
* allows the unchecked exception to propagate.
*
* http://www.baeldung.com/java-sneaky-throws
*/
@SuppressWarnings("unchecked")
@Nonnull
public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
throw (E) ex;
}
}
trouver un code complet et des tests unitaires ici .
il y a beaucoup de bonnes réponses déjà publiées ici. J'essaie juste de résoudre le problème avec une perspective différente. C'est juste mes 2 cents, s'il vous plaît corrigez-moi si je me trompe quelque part.
la clause des lancements dans L'Interfacefonctionnel n'est pas une bonne idée
je pense que ce n'est probablement pas une bonne idée d'appliquer throws IOException à cause des raisons suivantes
-
Ce on dirait un anti-motif pour Stream / Lambda. L'idée est que l'appelant décider de ce code et comment traiter l'exception. Dans de nombreux cas, L'Exception IOException pourrait ne pas s'appliquer au client. Par exemple, si le client obtient de la valeur à partir de cache / mémoire au lieu d'effectuer l'entrée/sortie réelle
-
aussi, les exceptions manipulation dans les cours d'eau devient vraiment hideux. Par exemple, voici mon code est comme si j'utilise votre API
acceptMyMethod(s -> { try { Integer i = doSomeOperation(s); return i; } catch (IOException e) { // try catch block because of throws clause // in functional method, even though doSomeOperation // might not be throwing any exception at all. e.printStackTrace(); } return null; });
laid n'est-ce pas? En outre, comme je l'ai mentionné dans mon premier point, que la méthode d'opér ation de dos peut ou non lancer IOException (en fonction de l'implémentation du client/appelant), mais en raison de la clause de lancer dans votre méthode D'Interfacefonctionnel, je dois toujours écrire le try-catch.
Que dois-je faire si je sais vraiment cette API throws IOException
-
alors, nous confondons probablement Fonctionnellementl'Interfaceavec des Interfaces typiques. Si vous savez que cette API va lancer IOException, alors vous connaissez probablement aussi un comportement par défaut/abstrait. Je pense que vous devriez définir une interface et déployer votre bibliothèque (avec implémentation par défaut/abstract) comme suit
public interface MyAmazingAPI { Integer myMethod(String s) throws IOException; }
mais, le problème de try-catch existe toujours pour le client. Si j'utilise votre API dans stream, je dois quand même gérer IOException dans hideux bloc try-catch.
-
Fournir une valeur par défaut stream-friendly API comme suit:
public interface MyAmazingAPI { Integer myMethod(String s) throws IOException; default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) { try { return Optional.ofNullable(this.myMethod(s)); } catch (Exception e) { if (exceptionConsumer != null) { exceptionConsumer.accept(e); } else { e.printStackTrace(); } } return Optional.empty(); } }
la méthode par défaut prend l'objet consommateur comme argument, qui sera responsable de gérer l'exception. Maintenant, du point de vue du client, le code ressemblera à ceci
strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace)) .filter(Optional::isPresent) .map(Optional::get).collect(toList());
Bel à droite? Bien sûr, logger ou autre logique de manipulation pourrait être utilisé au lieu de Exception:: printStackTrace.
-
vous pouvez également exposer une méthode similaire à https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function - . Ce qui signifie que vous pouvez exposer une autre méthode, qui contiendra l'exception du précédent appel de méthode. L'inconvénient est que vous faites maintenant votre APIs staeful, ce qui signifie que vous devez gérer thread-safety et qui finira par devenir un succès de performance. Juste une option à envisager.
créer un type de retour personnalisé qui propagera l'exception cochée. C'est une alternative à la création d'une nouvelle interface qui reflète l'existant interface fonctionnelle avec la légère modification d'une "throws exception" sur l'interface fonctionnelle de la méthode.
définition
CheckedValueSupplier
public static interface CheckedValueSupplier<V> {
public V get () throws Exception;
}
CheckedValue
public class CheckedValue<V> {
private final V v;
private final Optional<Exception> opt;
public Value (V v) {
this.v = v;
}
public Value (Exception e) {
this.opt = Optional.of(e);
}
public V get () throws Exception {
if (opt.isPresent()) {
throw opt.get();
}
return v;
}
public Optional<Exception> getException () {
return opt;
}
public static <T> CheckedValue<T> returns (T t) {
return new CheckedValue<T>(t);
}
public static <T> CheckedValue<T> rethrows (Exception e) {
return new CheckedValue<T>(e);
}
public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
return Result.rethrows(e);
}
}
public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Utilisation
// Don't use this pattern with FileReader, it's meant to be an
// example. FileReader is a Closeable resource and as such should
// be managed in a try-with-resources block or in another safe
// manner that will make sure it is closed properly.
// This will not compile as the FileReader constructor throws
// an IOException.
Function<String, FileReader> sToFr =
(fn) -> new FileReader(Paths.get(fn).toFile());
// Alternative, this will compile.
Function<String, CheckedValue<FileReader>> sToFr = (fn) -> {
return CheckedValue.from (
() -> new FileReader(Paths.get("/home/" + f).toFile()));
};
// Single record usage
// The call to get() will propagate the checked exception if it exists.
FileReader readMe = pToFr.apply("/home/README").get();
// List of records usage
List<String> paths = ...; //a list of paths to files
Collection<CheckedValue<FileReader>> frs =
paths.stream().map(pToFr).collect(Collectors.toList());
// Find out if creation of a file reader failed.
boolean anyErrors = frs.stream()
.filter(f -> f.getException().isPresent())
.findAny().isPresent();
que se passe-t-il?
ajouter "jette exception" à chaque interface fonctionnelle dans le JDK violerait le principe sec d'une manière des plus odieuses. Pour éviter cela, une seule interface fonctionnelle qui lance une exception cochée est créée ( CheckedValueSupplier
). Ce sera la seule interface fonctionnelle qui autorise les exceptions vérifiées. Toutes les autres interfaces fonctionnelles vont utiliser le CheckedValueSupplier
pour envelopper n'importe quel code qui jette un coché exception.
la classe CheckedValue
tiendra le résultat de l'exécution de toute logique qui jette une exception cochée. Cela empêche la propagation d'une exception cochée jusqu'au point où le code tente d'accéder à la valeur qu'une instance de CheckedValue
contient.
Les problèmes avec cette approche.
- nous lançons maintenant" Exception " masquant effectivement le type spécifique lancé à l'origine.
- nous ignorons qu'une exception s'est produite jusqu'à ce que
CheckedValue#get()
soit appelé.
certaines interfaces fonctionnelles ( Consumer
par exemple) doivent être manipulées d'une manière différente car elles ne fournissent pas de valeur de retour.
fonction tenant lieu de consommateur
une approche consiste à utiliser une fonction au lieu d'un consommateur, ce qui s'applique lors de la manipulation flux.
List<String> lst = Lists.newArrayList();
// won't compile
lst.stream().forEach(e -> throwyMethod(e));
// compiles
lst.stream()
.map(e -> CheckedValueSupplier.from(
() -> {throwyMethod(e); return e;}))
.filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior
Dégénérer
alternativement, vous pouvez toujours monter à un RuntimeException
. Il y a d'autres réponses qui couvrent l'indexation d'une exception cochée à l'intérieur d'un Consumer
.
ne consommez pas.
il suffit d'éviter les interfaces fonctionnelles tous ensemble et d'utiliser un bon-ole-fashioned pour boucle.
par défaut, Java 8 fonction ne permet pas de jeter l'exception et comme suggéré dans les réponses multiples Il ya plusieurs façons de le réaliser, une façon est:
@FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
R apply(T t) throws E;
}
Définir comme:
private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
if ("abc".equals(str)) {
throw new IOException();
}
return 1;
};
et ajouter throws
ou try/catch
la même exception dans la méthode de l'appelant.
si cela ne vous dérange pas d'utiliser une bibliothèque tierce, avec cyclops-react , une bibliothèque à laquelle je contribue, vous pouvez utiliser le FluentFunctions API to write
Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);
ofChecked prend une fonction de vérification de jOOλ et renvoie la référence adoucie à un java standard (non vérifié) de JDK.util.fonction.Fonction.
vous pouvez aussi continuer à travailler avec la fonction capturée via les fonctions fluentes api!
par exemple pour exécuter votre méthode, en la retraçant jusqu'à 5 fois et en enregistrant son statut vous pouvez écrire
FluentFunctions.ofChecked(this::myMethod)
.log(s->log.debug(s),e->log.error(e,e.getMessage())
.try(5,1000)
.apply("my param");
Ce que je fais est de permettre à l'utilisateur de donner la valeur qu'il fait envie en cas d'exception . Donc j'ai quelque chose qui ressemble à ça
public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
return x -> {
try {
return delegate.apply(x);
} catch (Throwable throwable) {
return defaultValue;
}
};
}
@FunctionalInterface
public interface FunctionThatThrows<T, R> {
R apply(T t) throws Throwable;
}
et cela peut alors être appelé comme:
defaultIfThrows(child -> child.getID(), null)
plusieurs des solutions proposées utilisent un argument générique de E pour passer dans le type de l'exception qui est lancée.
encore plus loin, et plutôt que de passer dans le type de l'exception, passer d'un Consommateur de type d'exception, comme dans...
Consumer<E extends Exception>
vous pourriez créer plusieurs variantes réutilisables de Consumer<Exception>
qui couvriraient les besoins communs de traitement des exceptions de votre application.
je vais faire quelque chose de générique:
public interface Lambda {
@FunctionalInterface
public interface CheckedFunction<T> {
T get() throws Exception;
}
public static <T> T handle(CheckedFunction<T> supplier) {
try {
return supplier.get();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
utilisation:
Lambda.handle(() -> method());
utilisez Jool Library
ou dites jOOλ library
de JOOQ
. Non seulement il fournit des interfaces d'exception gérées non vérifiées, mais il fournit également Seq class avec beaucoup de méthodes utiles.
contient aussi des Interfaces fonctionnelles avec jusqu'à 16 paramètres. De plus, il fournit la classe Tuple qui est utilisée dans différents scénarios.
spécifiquement dans la recherche de bibliothèque pour org.jooq.lambda.fi.util.function
paquet. Il contient toutes les Interfaces de Java 8 avec Vérifiée ajouté. Voir ci-dessous pour référence:-
public void frankTest() {
int pageId= -1;
List<Book> users= null;
try {
//Does Not Compile: Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name")));
//Compiles:
Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> {
try {
final Book bk= users.stream().filter(bp -> {
String name= null;
try {
name = rw.getString("name");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bp.getTitle().equals(name);
}).limit(1).collect(Collectors.toList()).get(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name"));
} );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}