Java 11 引入了 lambda 参数的局部变量类型推断。例如:
Stream.of("a", "b", "c").map((var a) -> "ok")
Run Code Online (Sandbox Code Playgroud)
我的问题是:如果我可以跳过它,为什么要使用它。例如:
Stream.of("a", "b", "c").map(a -> "ok")
Run Code Online (Sandbox Code Playgroud)
?
我阅读了有关此主题的不同文章Eric Lippert 的博客和其他文章,并知道为什么这两个代码的工作方式不同
int[] values = { 7, 9, 13 };
List<Action> f = new List<Action>();
foreach (var value in values)
f.Add( () => Console.WriteLine("foreach value: " + value));
foreach (var item in f)
item();
f = new List<Action>();
for (int i = 0; i < values.Length; i++)
f.Add(() => Console.WriteLine("for value: " + ((i < values.Length) ? values[i] : i)));
foreach (var item in f)
item();
Run Code Online (Sandbox Code Playgroud)
但我没有找到明确的解释,为什么最终(从编译器 c# 版本 5 开始)决定“foreach 循环变量在逻辑上将位于循环体内部,因此闭包每次都会获得一个新的副本”。因为旧的实现提供了使用闭包 Lambda 的更多自由(“按值或按引用”),但要求程序员小心使用它,如果您需要 foreach …
Lambda 是一个有用的东西,但对我来说也有点令人困惑。有人可以在没有 lambda 的情况下执行 linq'WHERE' 查询吗,这样我就可以理解发生了什么。
List<Student> st = new List<Student>() {
new Student(){Id=1,Name="Nav"},
new Student(){Id=2,Name="San"},
new Student(){Id=3,Name="Jat"},
};
Student? me = st.Where(st => st.Name == "Nav").FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
我想看看如何在没有 lambda 的情况下做到这一点。
下面两个 lambda 函数哪一个是正确的?
#include <cstdlib>
extern constinit int exit_code { };
int main( )
{
auto lambda_1 { [ &exit_code ]( ) noexcept
{
exit_code = EXIT_FAILURE;
} };
auto lambda_2 { [ ]( ) noexcept
{
exit_code = EXIT_FAILURE;
} };
lambda_1( );
lambda_2( );
return exit_code;
}
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会警告&exit_code:
#include <cstdlib>
extern constinit int exit_code { };
int main( )
{
auto lambda_1 { [ &exit_code ]( ) noexcept
{
exit_code = EXIT_FAILURE;
} };
auto lambda_2 …Run Code Online (Sandbox Code Playgroud) 我希望能够解析字符串"x => x + 1",并能够实际将其用作 lambda 函数,如下所示:
val string = "x => x + 1"
val lambda = parseLambda(string)
val numbers = List(1, 2, 3)
val result = numbers.map(lambda) // Should be [2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
我对该函数有以下实现parseLambda:
def parseLambda(string: String): Any => Any = {
val toolbox = runtimeMirror(getClass.getClassLoader).mkToolBox()
val tree = toolbox.parse(string)
val lambdaFunction = toolbox.compile(tree)().asInstanceOf[Any => Any]
lambdaFunction
}
Run Code Online (Sandbox Code Playgroud)
它适用于像"(x: Int) => x * 2"or这样的字符串"(s: String) => s.split(" ")",但如果我省略类型,例如"x => …
这是我在 Java MOOC.fi 课程中学习流的代码。下面的代码可以工作,但我编写它的方式相当业余。我正在考虑以某种方式将流中的 if 语句与先前输入中给出的答案的条件集成,以通过更改一行(过滤器方法)来预测该过程。有任何想法吗?
System.out.println("Print the average of the negative numbers or the positive numbers? (n/p)");
String answer = scanner.nextLine();
double average;
if (answer.equals("n")) {
average = inputs.stream()
.mapToInt(s -> Integer.valueOf(s))
.filter(pos -> pos < 0)
.average()
.getAsDouble();
} else {
average = inputs.stream()
.mapToInt(s -> Integer.valueOf(s))
.filter(pos -> pos > 0)
.average()
.getAsDouble();
}
Run Code Online (Sandbox Code Playgroud)
我尝试过forEach,但我不明白如何使用它。我提供给流的集合是一个ArrayList.
我使用的是 Java 11。
鉴于:
List<String> myStrings = Arrays.asList("broom", "monsoon");
Run Code Online (Sandbox Code Playgroud)
返回:
Map<String, Long> stringToNumberOfVowels = Map.of("broom", 2, "monsoon", 3);
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的:
Map<String, Long> vowelsMap = Stream.of("broom").flatMapToInt(String::chars).filter("aeiou".indexOf(c) >= 0).mapToObj(c -> "aeiou".indexOf(c)>=0 ? "broom" : "").collect(Collectors.groupingBy(Function.indenty(), Collectors.counting()));
for(Map.Entry<String, Long> a : vowelsMap.entrySet()) { System.out.println(a.getKey() + "==>"); System.out.println(a.getValue()); }
Run Code Online (Sandbox Code Playgroud)
我的输出(仅适用于流中传递的 1 个字符串):
扫帚==> 2
期望的输出:
扫帚==> 2
季风==> 3
我正在尝试使用 实例化一个对象Constructor.newInstance。构造函数需要一个类型为 的参数DoubleSupplier。如果我首先创建一个DoubleSupplier对象,然后将该对象传递给该newInstance方法,则这是成功的:
DoubleSupplier supplier = () -> 3.0;
obj = ctor.newInstance( supplier );
Run Code Online (Sandbox Code Playgroud)
但如果我尝试直接在调用中使用 lambda newInstance:
obj = ctor.newInstance( () -> 3.0 );
Run Code Online (Sandbox Code Playgroud)
它无法编译,并显示“此表达式的目标类型必须是函数式接口”。这两种方法有什么区别?
顺便说一句,我可以在使用 实例化对象时使用 lambda new。
obj2 = new SubTypeA( () -> 3.0 );
Run Code Online (Sandbox Code Playgroud)
示例程序如下。
public class CtorDemo
{
public static void main(String[] args)
{
SuperType obj = getSubType( SubTypeA.class );
System.out.println( obj.getClass().getName() );
}
private static SuperType
getSubType( Class<? extends SuperType> clazz )
{
SuperType obj …Run Code Online (Sandbox Code Playgroud) 请解释一下为什么这段代码会崩溃?
#include <vector>
#include <cassert>
#include <algorithm>
int main() {
std::vector<int> vt = {1,2,3,4};
assert(std::is_sorted(vt.begin(), vt.end(), [](const auto& a, const auto& b){ return true;}));
}
Run Code Online (Sandbox Code Playgroud)
下面是一个典型的 C 函数,它采用经典函数指针作为参数:
int DoThingy( const char* stuff, int(*helper)(int))
{
int result = 0;
//...call helper...
return result;
}
Run Code Online (Sandbox Code Playgroud)
下面我用一个非捕获 lambda 来调用上面的内容,它神奇地“降级”为函数指针。在“A”处,转换是隐式的。在“B”处,它是明确的。都好。
void UseThingy()
{
auto lam = [](int)->int {
return 42;
};
int i;
i = DoThingy( "hello", lam); //"A" works
int (*ptr)(int) = lam;
i = DoThingy( "hello", ptr); //"B" works
}
Run Code Online (Sandbox Code Playgroud)
但在这个新示例中,回调函数的签名取决于模板类型:
template <typename T>
int DoThingy2( const char* stuff, int (*helper)(T))
{
int result = 0;
//...call helper...
return result;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用上面的这个版本时,“C”行甚至无法编译。然而“D”处的显式版本是有效的。什么?为什么这些不一样?请注意,当我在“E”处给出显式模板参数时,它可以工作,但当然可以<int>从 的签名推断出来lam …
lambda ×10
java ×4
c++ ×3
c# ×2
java-stream ×2
reflection ×2
algorithm ×1
closures ×1
collectors ×1
comparison ×1
dictionary ×1
for-loop ×1
foreach ×1
gcc-warning ×1
java-11 ×1
scala ×1
sorting ×1
templates ×1