gpt4 book ai didi

java - 如何将方法的返回类型声明为传递给方法的数组中最后一个 lambda 的返回类型

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:08:49 26 4
gpt4 key购买 nike

我提出一些我认为不可能的问题,如果是,我会删除问题。

我有方法:

public Object convertBy(Function... functions) {
}

这些函数是:

interface FLines extends Function {
@Override
default Object apply(Object t) {
return null;
};

public List<String> getLines(String fileName);
}

interface Join extends Function {
@Override
default Object apply(Object t) {
return null;
};

public String join(List<String> lines);//lines to join
}

interface CollectInts extends Function {
@Override
default Object apply(Object t) {
return null;
};

public List<Integer> collectInts(String s);
}

interface Sum<T, R> extends Function<T, R> {
@Override
default Object apply(Object t) {
return null;
};

public R sum(T list);//list of Integers
}

这些接口(interface)中的抽象方法返回不同类型的值。我将 lambda 传递给我的 convertBy 方法。

我想将 convertBy 的返回类型设置为与 functions[functions.length - 1] 的返回类型相同。

这可能吗?


编辑:

我已经更改了方法的签名和接口(interface)内部方法的签名。它有效,但前提是我确实在下面主要发布的标记位置进行了转换。它只需要在 4 个方法调用中的 3 个中进行强制转换,我想在 main 中完全摆脱强制转换。

import java.util.List;
import java.util.function.Function;


public class InputConverter<T> {

private T value;

public InputConverter(T value) {
this.value = value;
}


public <T, R> R convertBy(Function<T, R> special, Function... functions) {
if (functions.length == 0) {
FLines flines = (FLines) special;
return (R) flines.getLines((value instanceof String) ? (String) value : null);
} else if (functions.length == 1) {
FLines flines = (FLines) functions[0];
Join join = (Join) special;
return (R) join.join(flines.getLines((String) value));
} else if (functions.length == 2) {
if (functions[0] instanceof FLines) {
FLines flines = (FLines) functions[0];
Join join = (Join) functions[1];
CollectInts collectInts = (CollectInts) special;
return (R) collectInts.collectInts(join.join(flines.getLines((String) value)));
} else {
Join join = (Join) functions[0];
CollectInts collectInts = (CollectInts) functions[1];
Sum sum = (Sum) special;
return (R) sum.sum(collectInts.collectInts(join.join((List<String>) value)));
}
} else {
FLines flines = (FLines) functions[0];
Join join = (Join) functions[1];
CollectInts collectInts = (CollectInts) functions[2];
Sum sum = (Sum) special;
return (R) sum.sum(collectInts.collectInts(join.join(flines.getLines((String) value))));
}
}

/* public Integer convertBy(Join join, CollectInts collectInts, Sum sum) {
return sum.sum(collectInts.collectInts(join.join((List<String>) value)));
}*/

}

interface FLines<T, R> extends Function {
@Override
default Object apply(Object t) {
return null;
};
public R getLines(T fileName);
// public List<String> getLines(String fileName);
}

interface Join<T,R> extends Function {
@Override
default Object apply(Object t) {
return null;
};
public R join(T lines);//lines to join
// public String join(List<String> lines);//lines to join
}

interface CollectInts<T, R> extends Function {
@Override
default Object apply(Object t) {
return null;
};
public R collectInts(T t);
// public List<Integer> collectInts(String s);
}

interface Sum<T, R> extends Function<T, R> {
@Override
default Object apply(Object t) {
return null;
};

public R sum(T list);//list of Integers
}

主要方法:

   FLines<String, List<String>> flines ....

Join<List<String>, String> join ...
CollectInts<String, List<Integer>> collectInts ...

Sum<List<Integer>, Integer> sum ...

String fname =/* System.getProperty("user.home") + "/*/ "LamComFile.txt";
InputConverter<String> fileConv = new InputConverter<>(fname);
List<String> lines = fileConv.convertBy(flines);//cannot cast from Object to List<String>
String text = fileConv.convertBy( join, flines);//cannot cast from Object to String
List<Integer> ints = fileConv.convertBy(collectInts,flines, join);//cannot cast from Object to List<Integer>
Integer sumints = fileConv.convertBy(sum, flines, join, collectInts);//works without cast!

我不明白为什么编译器可以理解 sum 返回的内容,但不推断例如 collectInts 返回的内容。

最佳答案

看来,您对泛型类型层次结构有一些误解。当您想要扩展泛型类型时,您必须对扩展类或接口(interface)的实际类型做出基本决定。您可以指定确切的类型,如

interface StringTransformer extends Function<String,String> {}

(这里我们创建了一个扩展泛型但本身不是泛型的类型)

或者您可以创建一个通用类型,它使用自己的类型参数来指定父类(super class)的实际类型参数:

interface NumberFunc<N extends Number> extends Function<N,N> {}

请注意,我们如何创建一个新的类型参数 N有自己的约束,并使用它来参数化父类(super class),以要求其类型参数与我们的相匹配。

相反,当你声明一个类时

interface FLines<T, R> extends Function

您正在扩展原始 类型 Function并创建新的类型参数 <T, R>这在您的场景中完全没用。

为了留在上面的示例中,您可以将它们实现为

StringTransformer reverse = s -> new StringBuilder(s).reverse().toString();
NumberFunc<Integer> dbl = i -> i*2;

并且由于它们继承了正确类型化的方法,您可以使用它们来组合函数:

Function<String,Integer> f = reverse.andThen(Integer::valueOf).andThen(dbl);
System.out.println(f.apply("1234"));

将此应用到您的场景中,您可以像这样定义接口(interface)

interface FLines extends Function<String,List<String>> {
@Override default List<String> apply(String fileName) {
return getLines(fileName);
}
public List<String> getLines(String fileName);
}
interface Join extends Function<List<String>,String> {
@Override default String apply(List<String> lines) {
return join(lines);
}
public String join(List<String> lines);
}
interface CollectInts extends Function<String,List<Integer>> {
@Override default List<Integer> apply(String s) {
return collectInts(s);
}
public List<Integer> collectInts(String s);
}
interface Sum extends Function<List<Integer>, Integer> {
@Override default Integer apply(List<Integer> list) {
return sum(list);
}
public Integer sum(List<Integer> list);
}

并重新设计您的 InputConverter只接受可能是组合函数的一个函数:

public class InputConverter<T> {

private T value;

public InputConverter(T value) {
this.value = value;
}
public <R> R convertBy(Function<? super T, ? extends R> f) {
return f.apply(value);
}
}

这可以以类型安全的方式使用:

FLines flines = name -> {
try { return Files.readAllLines(Paths.get(name)); }
catch(IOException ex) { throw new UncheckedIOException(ex); }
};
Join join = list -> String.join(",", list);
CollectInts collectInts=
s -> Arrays.stream(s.split(",")).map(Integer::parseInt).collect(Collectors.toList());
Sum sum = l -> l.stream().reduce(0, Integer::sum);

InputConverter<String> fileConv = new InputConverter<>("LamComFile.txt");
List<String> lines = fileConv.convertBy(flines);
String text = fileConv.convertBy(flines.andThen(join));
List<Integer> ints = fileConv.convertBy(flines.andThen(join).andThen(collectInts));
Integer sumints = fileConv.convertBy(
flines.andThen(join).andThen(collectInts).andThen(sum)
);

关于java - 如何将方法的返回类型声明为传递给方法的数组中最后一个 lambda 的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33298519/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com