引发异常的Java 8 Lambda函数?

引发异常的Java 8 Lambda函数?,java,lambda,java-8,Java,Lambda,Java 8,我知道如何创建对具有字符串参数并返回int的方法的引用,它是: Function<String, Integer> 我将如何定义此引用?免责声明:我还没有使用Java 8,只是阅读了有关它的内容 函数不会抛出IOException,因此不能在其中放入任何抛出IOException的代码。如果调用的方法需要函数,则传递给该方法的lambda不能抛出IOException,句点。您可以这样编写lambda(我认为这是lambda语法,不确定): 或者,如果要将lambda传递给的方法是

我知道如何创建对具有
字符串
参数并返回
int
的方法的引用,它是:

Function<String, Integer>
我将如何定义此引用?

免责声明:我还没有使用Java 8,只是阅读了有关它的内容

函数
不会抛出
IOException
,因此不能在其中放入任何
抛出IOException的代码。如果调用的方法需要
函数
,则传递给该方法的lambda不能抛出
IOException
,句点。您可以这样编写lambda(我认为这是lambda语法,不确定):

或者,如果要将lambda传递给的方法是您自己编写的方法,则可以定义一个新的函数接口,并将其用作参数类型,而不是
函数

通过IOException的公共接口函数{
O应用(I输入)引发IOException;
}

您需要执行以下操作之一

  • 如果是您的代码,则定义您自己的功能接口来声明选中的异常:

    @FunctionalInterface
    public interface CheckedFunction<T, R> {
       R apply(T t) throws IOException;
    }
    
    public Integer myWrappedMethod(String s) {
        try {
            return myMethod(s);
        }
        catch(IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    
  • 否则,将
    整数myMethod(字符串s)
    包装到一个不声明选中异常的方法中:

    @FunctionalInterface
    public interface CheckedFunction<T, R> {
       R apply(T t) throws IOException;
    }
    
    public Integer myWrappedMethod(String s) {
        try {
            return myMethod(s);
        }
        catch(IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    
    然后:

    Function<String, Integer> f = (String t) -> myWrappedMethod(t);
    
    函数f=(字符串t)->myWrappedMethod(t);
    
    或:

    函数f=
    (字符串t)->{
    试一试{
    返回myMethod(t);
    }
    捕获(IOE异常){
    抛出新的未选中异常(e);
    }
    };
    

这不是Java 8特有的。您正在尝试编译与以下内容等效的内容:

interface I {
    void m();
}
class C implements I {
    public void m() throws Exception {} //can't compile
}

使用函数包装器的另一个解决方案是,如果一切顺利,则返回结果包装器的一个实例(如成功),或者返回结果包装器的一个实例(如失败)

一些代码可以澄清一些事情:

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;
    }
}
公共接口ThrowableFunction{
B应用(A)抛出异常;
}
公共抽象类尝试{
公共静态布尔isSuccess(Try-tryy){
返回tryy成功实例;
}
公共静态功能tryOf(一次性功能){
返回一个->{
试一试{
B结果=函数。应用(a);
返回新的成功(结果);
}捕获(例外e){
返回新故障(e);
}
};
}
公共抽象布尔isSuccess();
公共布尔isError(){
return!issucess();
}
公共摘要一个getResult();
公共抽象异常getError();
}
公开课的成功扩展了尝试{
私人最终结果;
公众的成功(结果){
this.result=结果;
}
@凌驾
公共布尔值isSuccess(){
返回true;
}
@凌驾
公开一个getResult(){
返回结果;
}
@凌驾
公共异常getError(){
返回新的UnsupportedOperationException();
}
@凌驾
公共布尔等于(该对象){
如果(!(成功的那一刻)){
返回false;
}
返回Objects.equal(result,((Success)that).getResult());
}
}
公共类失败扩展了Try{
私人最终例外;
公共故障(例外){
this.exception=异常;
}
@凌驾
公共布尔值isSuccess(){
返回false;
}
@凌驾
公开一个getResult(){
抛出新的UnsupportedOperationException();
}
@凌驾
公共异常getError(){
返回异常;
}
}
一个简单的用例:

List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
    map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
    collect(Collectors.toList());
List result=Lists.newArrayList(1,2,3).stream()。
map(Try.tryOf(i->somethodthrowinganexception(i)))。
collect(Collectors.toList());

我所做的是允许用户在异常情况下给出他实际想要的值。 所以我有一些东西看起来像这样

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;
}

实际上,您可以使用一个处理异常的新接口扩展
消费者
(和
函数
等)——使用Java 8的默认方法

考虑此接口(扩展
消费者
):

但是使用这个新接口,您可以使用lambda表达式实例化它,编译器不会抱怨:

final ThrowingConsumer<String> throwingConsumer = aps -> {
    // maybe some other code here...
    throw new Exception("asdas");
};
list.forEach(throwingConsumer);

这个问题也一直困扰着我;这就是为什么我创造了

有了它,您可以:

final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
默认行为是,当抛出lambda抛出选中的异常时,抛出一个
ThrownByLambdaException
,并将选中的异常作为原因。因此,您可以捕捉到这一点并找到原因

其他功能也可用。

公共测试(){
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();
    }
}
int pageId=-1; 列表用户=null; 试一试{ //未编译:Object page=DatabaseConnection.getSpringConnection().queryForObject(“从书签页面选择*,(rw,n)->新门户(rw.getInt(“id”),”,users.parallelStream().filter(uu->uu.getVbid()==rw.getString(“user\u id”).findFirst().get(),rw.getString(“name”); //汇编: Object page=DatabaseConnection.getSpringConnection().queryForObject(“从书签页面选择*,(rw,n)->{ 试一试{ final Book bk=users.stream().filter(bp->{ 字符串名称=null; 试一试{ name=rw.getString(“name”); }捕获(例外e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } 返回bp.getTitle().equals(name); }).limit(1).collect(collector.toList()).get(0); }捕获(例外e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } 返回新门户(rw.getInt(“id”),“”,users.get(0),rw.getString(“name”); } ); }捕获(例外e){ //TODO自动生成的捕捉块 e、 printStackTrace(); } }
I h
defaultIfThrows(child -> child.getID(), null)
@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;

}
final List<String> list = Arrays.asList("A", "B", "C");
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);
final ThrowingConsumer<String> throwingConsumer = aps -> {
    // maybe some other code here...
    throw new Exception("asdas");
};
list.forEach(throwingConsumer);
list.forEach((ThrowingConsumer<String>) aps -> {
    // maybe some other code here...
    throw new Exception("asda");
});
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
myStringStream.map(f) // <-- works
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();
    }
}
public Object uncheckedNewInstanceForName (String name) {

    try {
        return Class.forName(name).newInstance();
    }
    catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}
@FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
  void accept(T instance) throws X;
}
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");

 }

}
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 { }
}
// 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));
           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;
            });
public interface MyAmazingAPI {
    Integer myMethod(String s) throws IOException;
}
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();
    }
}
strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace))
                .filter(Optional::isPresent)
                .map(Optional::get).collect(toList());
CheckedFunction1<String, Integer> f = this::myMethod;
Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
        .map(i -> ...) // only executed on Success
        ...
 Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);
  FluentFunctions.ofChecked(this::myMethod)
                 .log(s->log.debug(s),e->log.error(e,e.getMessage())
                 .try(5,1000)
                 .apply("my param");
Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));
Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
public static interface CheckedValueSupplier<V> {
    public V get () throws Exception;
}
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);
        }
    }

}
//  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();
    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
@FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
    R apply(T t) throws E;
}
private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
    if ("abc".equals(str)) {
        throw new IOException();
    }
  return 1;
};
Consumer<E extends Exception>
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);

        }
    }
}
 Lambda.handle(() -> method());
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);
        }
    }));
}
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;
    }

}
public class UncheckedExceptions {

    /**
     * throws {@code exception} as unchecked exception, without wrapping exception.
     *
     * @return will never return anything, return type is set to {@code exception} only to be able to write <code>throw unchecked(exception)</code>
     * @throws T {@code exception} as unchecked exception
     */
    @SuppressWarnings("unchecked")
    public static <T extends Throwable> T unchecked(Exception exception) throws T {
        throw (T) exception;
    }


    @FunctionalInterface
    public interface UncheckedFunction<R> {
        R call() throws Exception;
    }

    /**
     * Executes given function,
     * catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
     *
     * @return result of function
     * @see #unchecked(Exception)
     */
    public static <R> R unchecked(UncheckedFunction<R> function) {
        try {
            return function.call();
        } catch (Exception e) {
            throw unchecked(e);
        }
    }


    @FunctionalInterface
    public interface UncheckedMethod {
        void call() throws Exception;
    }

    /**
     * Executes given method,
     * catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
     *
     * @see #unchecked(Exception)
     */
    public static void unchecked(UncheckedMethod method) {
        try {
            method.call();
        } catch (Exception e) {
            throw unchecked(e);
        }
    }
}
unchecked(() -> new File("hello.txt").createNewFile());

boolean fileWasCreated = unchecked(() -> new File("hello.txt").createNewFile());

myFiles.forEach(unchecked(file -> new File(file.path).createNewFile()));
public class UncheckedUtils {

    @FunctionalInterface
    public interface ThrowingConsumer<T> {
        void accept(T t) throws Exception;
    }

    @FunctionalInterface
    public interface ThrowingSupplier<T> {
        T get() throws Exception;
    }

    @FunctionalInterface
    public interface ThrowingRunnable {
        void run() throws Exception;
    }

    public static <T> Consumer<T> unchecked(
            ThrowingConsumer<T> throwingConsumer
    ) {
        return i -> {
            try {
                throwingConsumer.accept(i);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        };
    }

    public static <T> T unchecked(
            ThrowingSupplier<T> throwingSupplier
    ) {
        try {
            return throwingSupplier.get();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public static void unchecked(
            ThrowingRunnable throwing
    ) {
        try {
            throwing.run();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}