由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - what is java enclosure-今天被hm问倒了
相关主题
面试中:问倒公司的有理有利有力的问题,简单实用无冒犯。Re: java enclosure是什么-今天被hm问倒了
相关话题的讨论汇总
话题: tree话题: inorder话题: java话题: 函数话题: closure
进入JobHunting版参与讨论
1 (共1页)
b********r
发帖数: 118
1
java experience也5years+ 被hm问了这个问题不知道
人家让我google一下 下次meet再聊 回来google 居然没找到
他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了
多谢
s******5
发帖数: 673
2
Not sure if this is what you are looking for..
(it is called closure)
http://gioorgi.com/2010/closure-in-java-fast-and-nice/
but it def does something with java inner class..

【在 b********r 的大作中提到】
: java experience也5years+ 被hm问了这个问题不知道
: 人家让我google一下 下次meet再聊 回来google 居然没找到
: 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了
: 多谢

s******5
发帖数: 673
3

Plus:
http://stackoverflow.com/questions/355167/how-are-anonymous-inner-classes-used-in-java/355382#355382

【在 b********r 的大作中提到】
: java experience也5years+ 被hm问了这个问题不知道
: 人家让我google一下 下次meet再聊 回来google 居然没找到
: 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了
: 多谢

y*********e
发帖数: 518
4
感觉对方是在问 Closure。
这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
若是做过 functional programming(比如haskell),应该对 Lamdba 表达
式比较熟悉。
从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
void inOrder(Tree tree) {
if (tree != null) {
inOrder(tree.getLeft());
System.out.println(tree.getValue());
inOrder(tree.getRight());
}
}
但是如上的函数只是把Node的值打印到终端。若是要变得generic一点,要遍历的
过程中,能引入一个函数,对每一个Node执行这个函数,该多好。这样就引入了一
个概念:能否把函数当做一个对象,传递入inOrder函数呢?
可以用如下的代码调用inOrder函数(Java 7的语法比较雷):
inOrder(tree,
#(Tree tree)(System.out.println(tree.getValue())
);
inOrder的定义要修改成:
void inOrder(Tree tree, #()(Tree tree));
一些示范代码:
之一:
#int(int x) fc; // 声明一个 variable
fc = #(int x)(x + 1); // 第一个括号是引入参数,第二个括号是代码
int x = fc(4); // 4加1,得5,然后赋值给x
之二:
int y = #(int x)(x + 1).(3); // y = 3 + 1
住:如上的语法还不是final版本。。在Java 7出来之前一切都会有变动。
所以Closure其实包含2个部分:1是把每个函数当作对象,2是一个简化的匿名函数
的语法。
在Java 6的话,就用interface+匿名类来实现了:
interface Closure { public void invoke(T t); }
void inOrder(Tree tree, Closure closure) {
if (tree != null) {
inOrder(tree.getLeft());
closure.invoke(tree);
inOrder(tree.getRight());
}
}
执行的代码如此:
inOrder(tree, new Closure() {
public void invoke(Tree tree) {
System.out.println(tree.getValue());
}
});
Java的最初的设计,即所有函数必须属于一个对象,导致了对拉姆达表达式的支持
非常困难。写出来的代码让人非常雷。
相比之下,C#的语言就简介多了:
delegate void TraversalAction(Tree tree); // 一个函数模板
void InOrder(Tree tree, TraversalAction action) {
if (tree != null) {
InOrder(tree.getLeft());
action(tree); // 执行该函数
InOrder(tree.getRight());
}
}
执行的代码如此:
InOrder(tree,
{ tree => Console.WriteLine(tree) } // 一个代码片段
);
也可以这么执行:
// 把一个代码片段存放入variable中
var func = (TraversalAction) delegate (Tree tree) {
tree => Console.WriteLine(tree);
};
// 把func传入函数InOrder作为一个参数
InOrder(tree, func);
总结一点:拉姆达表达式就是把一个代码片段或者一个函数当作对象。该对象
可以赋值给variable,也可以作为函数的引入参数。
若是C/C++语言,最经典的例子就是qsort函数:
void qsort (
void * base,
size_t num,
size_t size,
int (*comparator)(const void*, const void*)
);
第四个参数,就是一个function pointer。在调用qsort函数的时候,可以
把另外一个函数当作参数直接调入qsort。

【在 b********r 的大作中提到】
: java experience也5years+ 被hm问了这个问题不知道
: 人家让我google一下 下次meet再聊 回来google 居然没找到
: 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了
: 多谢

c*******s
发帖数: 1555
5
niu

【在 y*********e 的大作中提到】
: 感觉对方是在问 Closure。
: 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
: Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
: 若是做过 functional programming(比如haskell),应该对 Lamdba 表达
: 式比较熟悉。
: 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
: 举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
: void inOrder(Tree tree) {
: if (tree != null) {
: inOrder(tree.getLeft());

f*******h
发帖数: 53
6
Niu, thanks.

【在 y*********e 的大作中提到】
: 感觉对方是在问 Closure。
: 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
: Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
: 若是做过 functional programming(比如haskell),应该对 Lamdba 表达
: 式比较熟悉。
: 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
: 举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
: void inOrder(Tree tree) {
: if (tree != null) {
: inOrder(tree.getLeft());

d**e
发帖数: 6098
7
真是牛得一塌糊涂

【在 y*********e 的大作中提到】
: 感觉对方是在问 Closure。
: 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
: Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
: 若是做过 functional programming(比如haskell),应该对 Lamdba 表达
: 式比较熟悉。
: 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
: 举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
: void inOrder(Tree tree) {
: if (tree != null) {
: inOrder(tree.getLeft());

c*****h
发帖数: 166
8
这个apache commons包里面有 functor里面的一种 又看了下 很像visitor pattern
c*****h
发帖数: 166
y*********e
发帖数: 518
10
Apache Common里面那个提供的是一系列的interface还有static的函数来做辅助。
真正的Closure还要提供语法上的支持。要提供一种简单的方法,能够把一个代码片段
当作参数带入函数。
比如,你给的链接里面的 Ruby 的示例代码:
def highPaid(emps)
threshold = 150
return emps.select { |e| e.salary > threshold }
end
这里的代码片段 |e| e.salary > threshold 其实会被编译成一个匿名函数。输入 e,返回
e.salary > threshold。所以输入类型是Employee,输出是Boolean。
但是Java 6在语法上就不支持,非要创建一个interface,然后new一个新的对象,把对
象当作参数带入select函数。麻烦之级。
除此之外,还要求编译器能自动鉴别数据类型 (Type Inference)。比如,我写一个匿
名函数,x => x + 1,这个 x 可以是 int,也可以是 long,还可以是 double。对于
支持generic的语言来说,这个可以做成一个generic:
T foo(T t) {
return t + 1;
}
但是Java的generic用的是type erase,到了Java bytecode所有的Type信息都消失了,
变成了Object。也即,上例的Java Generic函数会被编译成(如果编译成功的话):
Object foo(Object t) {
return t + 1; // 所以编译会失败 -___-,因为Object不支持操作符+
}
这就造成了Java 7对Closure支持的困难,编译器无法做到Type Inference。写Closure
的时候还必须指明数据类型。要写成大概这样的形式: int x => x + 1。
T*********g
发帖数: 496
11
是问闭包呢。

【在 b********r 的大作中提到】
: java experience也5years+ 被hm问了这个问题不知道
: 人家让我google一下 下次meet再聊 回来google 居然没找到
: 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了
: 多谢

h**********d
发帖数: 4313
12
强,学习了

【在 y*********e 的大作中提到】
: 感觉对方是在问 Closure。
: 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
: Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
: 若是做过 functional programming(比如haskell),应该对 Lamdba 表达
: 式比较熟悉。
: 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
: 举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
: void inOrder(Tree tree) {
: if (tree != null) {
: inOrder(tree.getLeft());

1 (共1页)
进入JobHunting版参与讨论
相关主题
面试中:问倒公司的有理有利有力的问题,简单实用无冒犯。Re: java enclosure是什么-今天被hm问倒了
相关话题的讨论汇总
话题: tree话题: inorder话题: java话题: 函数话题: closure