- 浏览: 184633 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wsdst497:
chrome 版本号39 新窗口还是会被屏蔽
超链接实现新窗口打开很容易 -
zhanyeting:
[b][/b]
ajax 页面无刷新更改数据库中的内容 -
ewf_momo:
...
STRUTS 2 -
gaoxingang2008:
排一下版 太乱了
javascript -
javsky:
经验值得借鉴,项目还是不错的~我们公司最近也在做相关的项目,物 ...
IT个人年终工作总结[1]
2009-12-04
对Java中匿名类的一些思考
关键字: 对java中匿名类的一些思考
引言
Java中的匿名类是比较有意思的一种编程方式,在swing中关于监听器的注册时,经常可见到这样的代码:
Java代码
iexit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int y = JOptionPane.showConfirmDialog(
null,
"Confirm exit",
"Confirm Exit Dialog",
JOptionPane.YES_NO_OPTION);
if(y == JOptionPane.YES_OPTION){System.exit(0);}
}
});
Java代码
iexit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int y = JOptionPane.showConfirmDialog(
null,
"Confirm exit",
"Confirm Exit Dialog",
JOptionPane.YES_NO_OPTION);
if(y == JOptionPane.YES_OPTION){System.exit(0);}
}
});
iexit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int y = JOptionPane.showConfirmDialog(
null,
"Confirm exit",
"Confirm Exit Dialog",
JOptionPane.YES_NO_OPTION);
if(y == JOptionPane.YES_OPTION){System.exit(0);}
}
}); 通常使用匿名类的场景是,临时的创建一个类,实现指定的接口 ,使得调用者可以通过接口的方法来实现一定的操作。比如上边这个例子中,exit这个菜单项,需要一个动作监听器,如果用常规写法,大概如此:
Java代码
class XListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//action here
}
}
XListener l = new XListener();
iexit.addActionListener(l);
Java代码
class XListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//action here
}
}
XListener l = new XListener();
iexit.addActionListener(l);
class XListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//action here
}
}
XListener l = new XListener();
iexit.addActionListener(l);
虽然完成了同样的工作,但是代码量明显比刚才要多。
实例
在javascript,或者其他函数式编程语言中,常常可以见到诸如此类的写法:
Js代码
$("#element").click(function(){
//do something
});
$("div.type").each(function(index){
//do something else with the index
});
Js代码
$("#element").click(function(){
//do something
});
$("div.type").each(function(index){
//do something else with the index
});
$("#element").click(function(){
//do something
});
$("div.type").each(function(index){
//do something else with the index
}); 将一个匿名函数传递给另一个函数,实现一些列定制的动作,正好工作中有个地方要用到类似的东东,就用java的匿名类实现了一套类似的机制:
Java代码
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
//用数组构造一个integer 的 list
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);//再添加一个元素
//做一次过滤,只有偶数被留下来
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){//再做一次过滤,10的倍数被留下来
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
Java代码
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
//用数组构造一个integer 的 list
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);//再添加一个元素
//做一次过滤,只有偶数被留下来
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){//再做一次过滤,10的倍数被留下来
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
//用数组构造一个integer 的 list
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);//再添加一个元素
//做一次过滤,只有偶数被留下来
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){//再做一次过滤,10的倍数被留下来
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
}); 这样可以将很多的条件AND到一起,对数据做条件过滤。
设计与实现
首先,需要定义一个接口(这是匿名类的基础),在这个例子中,我定义了一个过滤器接口,其中只有一个方法,即isLegal(Object item), 这个方法接受一个Obejct参数,返回一个boolean值,调用者根据这个boolean值来对最终结果做过滤:
Java代码
package org.free.fplist;
/**
* defined what condition should be used in <code>FilterableList.filter()</code>
*
* @author juntao.qiu@gmail.com
*
*/
public interface Filter {
/**
* this is a condition definition, pass a object in, and then
* a <code>true</code> or <code>false</code> will be returned.
* @param item
* @return
*/
boolean isLegal(Object item);
}
Java代码
package org.free.fplist;
/**
* defined what condition should be used in <code>FilterableList.filter()</code>
*
* @author juntao.qiu@gmail.com
*
*/
public interface Filter {
/**
* this is a condition definition, pass a object in, and then
* a <code>true</code> or <code>false</code> will be returned.
* @param item
* @return
*/
boolean isLegal(Object item);
}
package org.free.fplist;
/**
* defined what condition should be used in <code>FilterableList.filter()</code>
*
* @author juntao.qiu@gmail.com
*
*/
public interface Filter {
/**
* this is a condition definition, pass a object in, and then
* a <code>true</code> or <code>false</code> will be returned.
* @param item
* @return
*/
boolean isLegal(Object item);
}
另外,我们需要一个接口,用来表示一个链表具有被过滤的能力(FPable):
Java代码
package org.free.fplist;
/**
* This is the interface defined Function-programmable support
*
* @author juntao.qiu@gmail.com
*
*/
public interface FPable<E> {
/**
* append a new element to list, and then return <code>this</code> object
*
* @param e element you want to insert into
* @return
*/
FPable<E> append(E e);
/**
* do a filter by the given rule, the <code>Filter</code>
* object passed in is defined as a interface, and you need
* to implement the condition.
*
* @param f
* @return
*/
FPable<E> filter(Filter f);
/**
* mapping the action to each item of <code>function-programming-list</code>
* and will not affect the original list
*
* @param act the Action will used to mapping
* @return
*/
FPable<E> mapping(Action act);
/**
* distinct the <code>FilterableList</code>, keep one same elements only, and
* does not affect the List itself.
*
* @return
*/
FPable<E> distinct();
/**
* for debug only, print the <code>index</code> and <code>content</code>
* of each item of a list.
*/
void print();
}
Java代码
package org.free.fplist;
/**
* This is the interface defined Function-programmable support
*
* @author juntao.qiu@gmail.com
*
*/
public interface FPable<E> {
/**
* append a new element to list, and then return <code>this</code> object
*
* @param e element you want to insert into
* @return
*/
FPable<E> append(E e);
/**
* do a filter by the given rule, the <code>Filter</code>
* object passed in is defined as a interface, and you need
* to implement the condition.
*
* @param f
* @return
*/
FPable<E> filter(Filter f);
/**
* mapping the action to each item of <code>function-programming-list</code>
* and will not affect the original list
*
* @param act the Action will used to mapping
* @return
*/
FPable<E> mapping(Action act);
/**
* distinct the <code>FilterableList</code>, keep one same elements only, and
* does not affect the List itself.
*
* @return
*/
FPable<E> distinct();
/**
* for debug only, print the <code>index</code> and <code>content</code>
* of each item of a list.
*/
void print();
}
package org.free.fplist;
/**
* This is the interface defined Function-programmable support
*
* @author juntao.qiu@gmail.com
*
*/
public interface FPable<E> {
/**
* append a new element to list, and then return <code>this</code> object
*
* @param e element you want to insert into
* @return
*/
FPable<E> append(E e);
/**
* do a filter by the given rule, the <code>Filter</code>
* object passed in is defined as a interface, and you need
* to implement the condition.
*
* @param f
* @return
*/
FPable<E> filter(Filter f);
/**
* mapping the action to each item of <code>function-programming-list</code>
* and will not affect the original list
*
* @param act the Action will used to mapping
* @return
*/
FPable<E> mapping(Action act);
/**
* distinct the <code>FilterableList</code>, keep one same elements only, and
* does not affect the List itself.
*
* @return
*/
FPable<E> distinct();
/**
* for debug only, print the <code>index</code> and <code>content</code>
* of each item of a list.
*/
void print();
}
附加的,我需要对这个链表有函数映射 (map)的支持,上面这个接口中的Action,为另一个接口,同样会被很多的匿名类使用到:
Java代码
package org.free.fplist;
public interface Action {
public Object doAction(Object item);
}
Java代码
package org.free.fplist;
public interface Action {
public Object doAction(Object item);
}
package org.free.fplist;
public interface Action {
public Object doAction(Object item);
}
好了,我们现在来看一个FPable的实现FPList,FPList继承了LinkedList,并且实现了FPable,可以对其中的数据进行过滤(前提是传入一个过滤器 ),或者对其中的元素进行映射(传入一个动作 ),FPList会自动的将过滤器和动作作用到List中的每一个元素。
Java代码
package org.free.fplist;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
public class FPList<E> extends LinkedList<E> implements FPable<E>{
private static final long
serialVersionUID = 348375840291148300L;
public FPList(){
}
/**
* construct a fp-list by given array.
*
* @param es
*/
public FPList(E[] es){
for(int i = 0;i < es.length;i++){
add(es[i]);
}
}
public FPList<E> filter(Filter f){
FPList<E> filtered = new FPList<E>();
for(int i = 0; i < size();i++){
E o = get(i);
if(f.isLegal(o)){
filtered.add(o);
}
}
return filtered;
}
public FPList<E> append(E e){
add(e);
return this;
}
public FPList<E> distinct(){
FPList<E> filtered = this;
Set<E> set = new HashSet<E>();
for(int i = 0; i < filtered.size();i++){
set.add(filtered.get(i));
}
filtered.clear();
Iterator<E> it = set.iterator();
while(it.hasNext()){
filtered.add(it.next());
}
return filtered;
}
public FPList<E> mapping(Action act){
FPList<E> mapped = this;
for(int i = 0;i < size();i++){
mapped.add(i, (E)act.doAction(get(i)));
mapped.remove(i+1);
}
return mapped;
}
public void print(){
for(int i = 0;i < size();i++){
System.err.println("index : "+i+", content : "+get(i));
}
}
}
Java代码
package org.free.fplist;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
public class FPList<E> extends LinkedList<E> implements FPable<E>{
private static final long
serialVersionUID = 348375840291148300L;
public FPList(){
}
/**
* construct a fp-list by given array.
*
* @param es
*/
public FPList(E[] es){
for(int i = 0;i < es.length;i++){
add(es[i]);
}
}
public FPList<E> filter(Filter f){
FPList<E> filtered = new FPList<E>();
for(int i = 0; i < size();i++){
E o = get(i);
if(f.isLegal(o)){
filtered.add(o);
}
}
return filtered;
}
public FPList<E> append(E e){
add(e);
return this;
}
public FPList<E> distinct(){
FPList<E> filtered = this;
Set<E> set = new HashSet<E>();
for(int i = 0; i < filtered.size();i++){
set.add(filtered.get(i));
}
filtered.clear();
Iterator<E> it = set.iterator();
while(it.hasNext()){
filtered.add(it.next());
}
return filtered;
}
public FPList<E> mapping(Action act){
FPList<E> mapped = this;
for(int i = 0;i < size();i++){
mapped.add(i, (E)act.doAction(get(i)));
mapped.remove(i+1);
}
return mapped;
}
public void print(){
for(int i = 0;i < size();i++){
System.err.println("index : "+i+", content : "+get(i));
}
}
}
package org.free.fplist;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
public class FPList<E> extends LinkedList<E> implements FPable<E>{
private static final long
serialVersionUID = 348375840291148300L;
public FPList(){
}
/**
* construct a fp-list by given array.
*
* @param es
*/
public FPList(E[] es){
for(int i = 0;i < es.length;i++){
add(es[i]);
}
}
public FPList<E> filter(Filter f){
FPList<E> filtered = new FPList<E>();
for(int i = 0; i < size();i++){
E o = get(i);
if(f.isLegal(o)){
filtered.add(o);
}
}
return filtered;
}
public FPList<E> append(E e){
add(e);
return this;
}
public FPList<E> distinct(){
FPList<E> filtered = this;
Set<E> set = new HashSet<E>();
for(int i = 0; i < filtered.size();i++){
set.add(filtered.get(i));
}
filtered.clear();
Iterator<E> it = set.iterator();
while(it.hasNext()){
filtered.add(it.next());
}
return filtered;
}
public FPList<E> mapping(Action act){
FPList<E> mapped = this;
for(int i = 0;i < size();i++){
mapped.add(i, (E)act.doAction(get(i)));
mapped.remove(i+1);
}
return mapped;
}
public void print(){
for(int i = 0;i < size();i++){
System.err.println("index : "+i+", content : "+get(i));
}
}
}
使用匿名类
匿名类的使用是比较方便的,为了代码更简洁,我使用了jQuery中的链机制,其实,大家平时使用的StringBuffer就提供这样的能力。
Java代码
package org.free.fplist;
public class Main {
public static void main(String[] args){
String[] as = new String[]{
"Apple",
"Borland",
"Cisco",
"Dell",
"Epson",
"Flick",
"Google"
};
FPList<String> k = new FPList<String>(as);
k.distinct().filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("e") >= 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("p") >= 0 ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
return ((String)item)+", co";
}
}).print();
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
even.mapping(new Action(){
public Object doAction(Object item) {
return ((Integer)item).intValue()*10;
}
}).mapping(new Action(){
public Object doAction(Object item){
return ((Integer)item).intValue()/2;
}
}).print();
Person[] person = new Person[]{
new Person("abruzzi", 25, "male"),
new Person("smith", 25, "female"),
new Person("json", 26, "female"),
new Person("jet.lee", 25, "male")
};
FPList<Person> fp = new FPList<Person>(person);
fp.filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getAge() == 25 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getSex().equals("male") ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
System.err.println(((Person)item).getName());
return null;
}
});
}
}
Java代码
package org.free.fplist;
public class Main {
public static void main(String[] args){
String[] as = new String[]{
"Apple",
"Borland",
"Cisco",
"Dell",
"Epson",
"Flick",
"Google"
};
FPList<String> k = new FPList<String>(as);
k.distinct().filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("e") >= 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("p") >= 0 ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
return ((String)item)+", co";
}
}).print();
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
even.mapping(new Action(){
public Object doAction(Object item) {
return ((Integer)item).intValue()*10;
}
}).mapping(new Action(){
public Object doAction(Object item){
return ((Integer)item).intValue()/2;
}
}).print();
Person[] person = new Person[]{
new Person("abruzzi", 25, "male"),
new Person("smith", 25, "female"),
new Person("json", 26, "female"),
new Person("jet.lee", 25, "male")
};
FPList<Person> fp = new FPList<Person>(person);
fp.filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getAge() == 25 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getSex().equals("male") ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
System.err.println(((Person)item).getName());
return null;
}
});
}
}
package org.free.fplist;
public class Main {
public static void main(String[] args){
String[] as = new String[]{
"Apple",
"Borland",
"Cisco",
"Dell",
"Epson",
"Flick",
"Google"
};
FPList<String> k = new FPList<String>(as);
k.distinct().filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("e") >= 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("p") >= 0 ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
return ((String)item)+", co";
}
}).print();
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
even.mapping(new Action(){
public Object doAction(Object item) {
return ((Integer)item).intValue()*10;
}
}).mapping(new Action(){
public Object doAction(Object item){
return ((Integer)item).intValue()/2;
}
}).print();
Person[] person = new Person[]{
new Person("abruzzi", 25, "male"),
new Person("smith", 25, "female"),
new Person("json", 26, "female"),
new Person("jet.lee", 25, "male")
};
FPList<Person> fp = new FPList<Person>(person);
fp.filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getAge() == 25 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getSex().equals("male") ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
System.err.println(((Person)item).getName());
return null;
}
});
}
}
main的运行结果如下:
index : 0, content : Apple, co
index : 0, content : 50
index : 1, content : 100
index : 2, content : 150
index : 3, content : 500
abruzzi
jet.lee
上边的例子显示,匿名类在接口 中的方法不多的时候,整个匿名类整体作为一个对象传递给另外一个方法,可以很好的做到可定制性。比如第三个例子,使用Person bean的时候,可以定制多个过滤条件,依次将原始列表过滤成一个符合要求的列表。
另,文章中用到了比较多的函数式编程的概念,虽然java原生不支持,但是函数式编程作为一种思想,肯定可以在命令式的程序设计中有所体现。
对Java中匿名类的一些思考
关键字: 对java中匿名类的一些思考
引言
Java中的匿名类是比较有意思的一种编程方式,在swing中关于监听器的注册时,经常可见到这样的代码:
Java代码
iexit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int y = JOptionPane.showConfirmDialog(
null,
"Confirm exit",
"Confirm Exit Dialog",
JOptionPane.YES_NO_OPTION);
if(y == JOptionPane.YES_OPTION){System.exit(0);}
}
});
Java代码
iexit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int y = JOptionPane.showConfirmDialog(
null,
"Confirm exit",
"Confirm Exit Dialog",
JOptionPane.YES_NO_OPTION);
if(y == JOptionPane.YES_OPTION){System.exit(0);}
}
});
iexit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int y = JOptionPane.showConfirmDialog(
null,
"Confirm exit",
"Confirm Exit Dialog",
JOptionPane.YES_NO_OPTION);
if(y == JOptionPane.YES_OPTION){System.exit(0);}
}
}); 通常使用匿名类的场景是,临时的创建一个类,实现指定的接口 ,使得调用者可以通过接口的方法来实现一定的操作。比如上边这个例子中,exit这个菜单项,需要一个动作监听器,如果用常规写法,大概如此:
Java代码
class XListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//action here
}
}
XListener l = new XListener();
iexit.addActionListener(l);
Java代码
class XListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//action here
}
}
XListener l = new XListener();
iexit.addActionListener(l);
class XListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//action here
}
}
XListener l = new XListener();
iexit.addActionListener(l);
虽然完成了同样的工作,但是代码量明显比刚才要多。
实例
在javascript,或者其他函数式编程语言中,常常可以见到诸如此类的写法:
Js代码
$("#element").click(function(){
//do something
});
$("div.type").each(function(index){
//do something else with the index
});
Js代码
$("#element").click(function(){
//do something
});
$("div.type").each(function(index){
//do something else with the index
});
$("#element").click(function(){
//do something
});
$("div.type").each(function(index){
//do something else with the index
}); 将一个匿名函数传递给另一个函数,实现一些列定制的动作,正好工作中有个地方要用到类似的东东,就用java的匿名类实现了一套类似的机制:
Java代码
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
//用数组构造一个integer 的 list
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);//再添加一个元素
//做一次过滤,只有偶数被留下来
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){//再做一次过滤,10的倍数被留下来
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
Java代码
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
//用数组构造一个integer 的 list
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);//再添加一个元素
//做一次过滤,只有偶数被留下来
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){//再做一次过滤,10的倍数被留下来
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
//用数组构造一个integer 的 list
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);//再添加一个元素
//做一次过滤,只有偶数被留下来
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){//再做一次过滤,10的倍数被留下来
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
}); 这样可以将很多的条件AND到一起,对数据做条件过滤。
设计与实现
首先,需要定义一个接口(这是匿名类的基础),在这个例子中,我定义了一个过滤器接口,其中只有一个方法,即isLegal(Object item), 这个方法接受一个Obejct参数,返回一个boolean值,调用者根据这个boolean值来对最终结果做过滤:
Java代码
package org.free.fplist;
/**
* defined what condition should be used in <code>FilterableList.filter()</code>
*
* @author juntao.qiu@gmail.com
*
*/
public interface Filter {
/**
* this is a condition definition, pass a object in, and then
* a <code>true</code> or <code>false</code> will be returned.
* @param item
* @return
*/
boolean isLegal(Object item);
}
Java代码
package org.free.fplist;
/**
* defined what condition should be used in <code>FilterableList.filter()</code>
*
* @author juntao.qiu@gmail.com
*
*/
public interface Filter {
/**
* this is a condition definition, pass a object in, and then
* a <code>true</code> or <code>false</code> will be returned.
* @param item
* @return
*/
boolean isLegal(Object item);
}
package org.free.fplist;
/**
* defined what condition should be used in <code>FilterableList.filter()</code>
*
* @author juntao.qiu@gmail.com
*
*/
public interface Filter {
/**
* this is a condition definition, pass a object in, and then
* a <code>true</code> or <code>false</code> will be returned.
* @param item
* @return
*/
boolean isLegal(Object item);
}
另外,我们需要一个接口,用来表示一个链表具有被过滤的能力(FPable):
Java代码
package org.free.fplist;
/**
* This is the interface defined Function-programmable support
*
* @author juntao.qiu@gmail.com
*
*/
public interface FPable<E> {
/**
* append a new element to list, and then return <code>this</code> object
*
* @param e element you want to insert into
* @return
*/
FPable<E> append(E e);
/**
* do a filter by the given rule, the <code>Filter</code>
* object passed in is defined as a interface, and you need
* to implement the condition.
*
* @param f
* @return
*/
FPable<E> filter(Filter f);
/**
* mapping the action to each item of <code>function-programming-list</code>
* and will not affect the original list
*
* @param act the Action will used to mapping
* @return
*/
FPable<E> mapping(Action act);
/**
* distinct the <code>FilterableList</code>, keep one same elements only, and
* does not affect the List itself.
*
* @return
*/
FPable<E> distinct();
/**
* for debug only, print the <code>index</code> and <code>content</code>
* of each item of a list.
*/
void print();
}
Java代码
package org.free.fplist;
/**
* This is the interface defined Function-programmable support
*
* @author juntao.qiu@gmail.com
*
*/
public interface FPable<E> {
/**
* append a new element to list, and then return <code>this</code> object
*
* @param e element you want to insert into
* @return
*/
FPable<E> append(E e);
/**
* do a filter by the given rule, the <code>Filter</code>
* object passed in is defined as a interface, and you need
* to implement the condition.
*
* @param f
* @return
*/
FPable<E> filter(Filter f);
/**
* mapping the action to each item of <code>function-programming-list</code>
* and will not affect the original list
*
* @param act the Action will used to mapping
* @return
*/
FPable<E> mapping(Action act);
/**
* distinct the <code>FilterableList</code>, keep one same elements only, and
* does not affect the List itself.
*
* @return
*/
FPable<E> distinct();
/**
* for debug only, print the <code>index</code> and <code>content</code>
* of each item of a list.
*/
void print();
}
package org.free.fplist;
/**
* This is the interface defined Function-programmable support
*
* @author juntao.qiu@gmail.com
*
*/
public interface FPable<E> {
/**
* append a new element to list, and then return <code>this</code> object
*
* @param e element you want to insert into
* @return
*/
FPable<E> append(E e);
/**
* do a filter by the given rule, the <code>Filter</code>
* object passed in is defined as a interface, and you need
* to implement the condition.
*
* @param f
* @return
*/
FPable<E> filter(Filter f);
/**
* mapping the action to each item of <code>function-programming-list</code>
* and will not affect the original list
*
* @param act the Action will used to mapping
* @return
*/
FPable<E> mapping(Action act);
/**
* distinct the <code>FilterableList</code>, keep one same elements only, and
* does not affect the List itself.
*
* @return
*/
FPable<E> distinct();
/**
* for debug only, print the <code>index</code> and <code>content</code>
* of each item of a list.
*/
void print();
}
附加的,我需要对这个链表有函数映射 (map)的支持,上面这个接口中的Action,为另一个接口,同样会被很多的匿名类使用到:
Java代码
package org.free.fplist;
public interface Action {
public Object doAction(Object item);
}
Java代码
package org.free.fplist;
public interface Action {
public Object doAction(Object item);
}
package org.free.fplist;
public interface Action {
public Object doAction(Object item);
}
好了,我们现在来看一个FPable的实现FPList,FPList继承了LinkedList,并且实现了FPable,可以对其中的数据进行过滤(前提是传入一个过滤器 ),或者对其中的元素进行映射(传入一个动作 ),FPList会自动的将过滤器和动作作用到List中的每一个元素。
Java代码
package org.free.fplist;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
public class FPList<E> extends LinkedList<E> implements FPable<E>{
private static final long
serialVersionUID = 348375840291148300L;
public FPList(){
}
/**
* construct a fp-list by given array.
*
* @param es
*/
public FPList(E[] es){
for(int i = 0;i < es.length;i++){
add(es[i]);
}
}
public FPList<E> filter(Filter f){
FPList<E> filtered = new FPList<E>();
for(int i = 0; i < size();i++){
E o = get(i);
if(f.isLegal(o)){
filtered.add(o);
}
}
return filtered;
}
public FPList<E> append(E e){
add(e);
return this;
}
public FPList<E> distinct(){
FPList<E> filtered = this;
Set<E> set = new HashSet<E>();
for(int i = 0; i < filtered.size();i++){
set.add(filtered.get(i));
}
filtered.clear();
Iterator<E> it = set.iterator();
while(it.hasNext()){
filtered.add(it.next());
}
return filtered;
}
public FPList<E> mapping(Action act){
FPList<E> mapped = this;
for(int i = 0;i < size();i++){
mapped.add(i, (E)act.doAction(get(i)));
mapped.remove(i+1);
}
return mapped;
}
public void print(){
for(int i = 0;i < size();i++){
System.err.println("index : "+i+", content : "+get(i));
}
}
}
Java代码
package org.free.fplist;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
public class FPList<E> extends LinkedList<E> implements FPable<E>{
private static final long
serialVersionUID = 348375840291148300L;
public FPList(){
}
/**
* construct a fp-list by given array.
*
* @param es
*/
public FPList(E[] es){
for(int i = 0;i < es.length;i++){
add(es[i]);
}
}
public FPList<E> filter(Filter f){
FPList<E> filtered = new FPList<E>();
for(int i = 0; i < size();i++){
E o = get(i);
if(f.isLegal(o)){
filtered.add(o);
}
}
return filtered;
}
public FPList<E> append(E e){
add(e);
return this;
}
public FPList<E> distinct(){
FPList<E> filtered = this;
Set<E> set = new HashSet<E>();
for(int i = 0; i < filtered.size();i++){
set.add(filtered.get(i));
}
filtered.clear();
Iterator<E> it = set.iterator();
while(it.hasNext()){
filtered.add(it.next());
}
return filtered;
}
public FPList<E> mapping(Action act){
FPList<E> mapped = this;
for(int i = 0;i < size();i++){
mapped.add(i, (E)act.doAction(get(i)));
mapped.remove(i+1);
}
return mapped;
}
public void print(){
for(int i = 0;i < size();i++){
System.err.println("index : "+i+", content : "+get(i));
}
}
}
package org.free.fplist;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
public class FPList<E> extends LinkedList<E> implements FPable<E>{
private static final long
serialVersionUID = 348375840291148300L;
public FPList(){
}
/**
* construct a fp-list by given array.
*
* @param es
*/
public FPList(E[] es){
for(int i = 0;i < es.length;i++){
add(es[i]);
}
}
public FPList<E> filter(Filter f){
FPList<E> filtered = new FPList<E>();
for(int i = 0; i < size();i++){
E o = get(i);
if(f.isLegal(o)){
filtered.add(o);
}
}
return filtered;
}
public FPList<E> append(E e){
add(e);
return this;
}
public FPList<E> distinct(){
FPList<E> filtered = this;
Set<E> set = new HashSet<E>();
for(int i = 0; i < filtered.size();i++){
set.add(filtered.get(i));
}
filtered.clear();
Iterator<E> it = set.iterator();
while(it.hasNext()){
filtered.add(it.next());
}
return filtered;
}
public FPList<E> mapping(Action act){
FPList<E> mapped = this;
for(int i = 0;i < size();i++){
mapped.add(i, (E)act.doAction(get(i)));
mapped.remove(i+1);
}
return mapped;
}
public void print(){
for(int i = 0;i < size();i++){
System.err.println("index : "+i+", content : "+get(i));
}
}
}
使用匿名类
匿名类的使用是比较方便的,为了代码更简洁,我使用了jQuery中的链机制,其实,大家平时使用的StringBuffer就提供这样的能力。
Java代码
package org.free.fplist;
public class Main {
public static void main(String[] args){
String[] as = new String[]{
"Apple",
"Borland",
"Cisco",
"Dell",
"Epson",
"Flick",
"Google"
};
FPList<String> k = new FPList<String>(as);
k.distinct().filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("e") >= 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("p") >= 0 ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
return ((String)item)+", co";
}
}).print();
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
even.mapping(new Action(){
public Object doAction(Object item) {
return ((Integer)item).intValue()*10;
}
}).mapping(new Action(){
public Object doAction(Object item){
return ((Integer)item).intValue()/2;
}
}).print();
Person[] person = new Person[]{
new Person("abruzzi", 25, "male"),
new Person("smith", 25, "female"),
new Person("json", 26, "female"),
new Person("jet.lee", 25, "male")
};
FPList<Person> fp = new FPList<Person>(person);
fp.filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getAge() == 25 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getSex().equals("male") ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
System.err.println(((Person)item).getName());
return null;
}
});
}
}
Java代码
package org.free.fplist;
public class Main {
public static void main(String[] args){
String[] as = new String[]{
"Apple",
"Borland",
"Cisco",
"Dell",
"Epson",
"Flick",
"Google"
};
FPList<String> k = new FPList<String>(as);
k.distinct().filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("e") >= 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("p") >= 0 ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
return ((String)item)+", co";
}
}).print();
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
even.mapping(new Action(){
public Object doAction(Object item) {
return ((Integer)item).intValue()*10;
}
}).mapping(new Action(){
public Object doAction(Object item){
return ((Integer)item).intValue()/2;
}
}).print();
Person[] person = new Person[]{
new Person("abruzzi", 25, "male"),
new Person("smith", 25, "female"),
new Person("json", 26, "female"),
new Person("jet.lee", 25, "male")
};
FPList<Person> fp = new FPList<Person>(person);
fp.filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getAge() == 25 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getSex().equals("male") ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
System.err.println(((Person)item).getName());
return null;
}
});
}
}
package org.free.fplist;
public class Main {
public static void main(String[] args){
String[] as = new String[]{
"Apple",
"Borland",
"Cisco",
"Dell",
"Epson",
"Flick",
"Google"
};
FPList<String> k = new FPList<String>(as);
k.distinct().filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("e") >= 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
return ((String)item).indexOf("p") >= 0 ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
return ((String)item)+", co";
}
}).print();
Integer[] is = new Integer[]{
4,13,65,64,2,4,5,9,10,25,20,32,30
};
FPList<Integer> p = new FPList<Integer>(is);
p.append(100);
FPList<Integer> even = p.filter(new Filter(){
public boolean isLegal(Object item) {
int x = ((Integer)item).intValue();
return x % 2 == 0 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item){
int x = ((Integer)item).intValue();
return x % 10 == 0 ? true : false;
}
});
even.mapping(new Action(){
public Object doAction(Object item) {
return ((Integer)item).intValue()*10;
}
}).mapping(new Action(){
public Object doAction(Object item){
return ((Integer)item).intValue()/2;
}
}).print();
Person[] person = new Person[]{
new Person("abruzzi", 25, "male"),
new Person("smith", 25, "female"),
new Person("json", 26, "female"),
new Person("jet.lee", 25, "male")
};
FPList<Person> fp = new FPList<Person>(person);
fp.filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getAge() == 25 ? true : false;
}
}).filter(new Filter(){
public boolean isLegal(Object item) {
Person p = (Person)item;
return p.getSex().equals("male") ? true : false;
}
}).mapping(new Action(){
public Object doAction(Object item) {
System.err.println(((Person)item).getName());
return null;
}
});
}
}
main的运行结果如下:
index : 0, content : Apple, co
index : 0, content : 50
index : 1, content : 100
index : 2, content : 150
index : 3, content : 500
abruzzi
jet.lee
上边的例子显示,匿名类在接口 中的方法不多的时候,整个匿名类整体作为一个对象传递给另外一个方法,可以很好的做到可定制性。比如第三个例子,使用Person bean的时候,可以定制多个过滤条件,依次将原始列表过滤成一个符合要求的列表。
另,文章中用到了比较多的函数式编程的概念,虽然java原生不支持,但是函数式编程作为一种思想,肯定可以在命令式的程序设计中有所体现。
发表评论
-
socket
2017-01-16 17:31 494http://guoliangqi.iteye.com/b ... -
十分钟理解Java中的弱引用
2016-06-05 11:59 272十分钟理解Java中的弱引用 Android开发探索 ... -
//递归循环遍历list转化为tree
2015-11-16 11:41 1470//递归循环遍历list转化为tree pub ... -
转换数字为人民币大写
2015-11-15 16:05 627/** * 转换数字为人民币大写 * @param m ... -
JAVA 求昨天、明天的算法(前两天,后三天求法)
2015-11-02 15:04 1988JAVA 求昨天、明天的算法(前两天,后三天求法) ... -
java 后台过滤写 敏感字符
2015-02-04 09:56 1232<!--StartFragment --> S ... -
java反射详解
2014-11-05 11:16 7031、通过一个对象获得完整的包名和类名 Java ... -
项目中读取人人网数据出入数据
2014-07-08 14:24 378项目中读取人人网数据出入数据 -
dhtmlxCombo
2014-07-08 14:18 0顶顶顶顶顶的斗地主 -
学校数据
2014-06-13 22:56 599明天去爬山啊明天去爬山啊明天去爬山啊明天去爬山啊明天去爬山 ... -
全国所有地市 大学高中小学数据
2014-05-24 22:40 0全国所有地市 大学高中小学数据 -
SSH2_jQuery_Ajax_Register2
2014-05-12 10:11 814SSH2_jQuery_Ajax_Register2SSH2_ ... -
Java中的接口
2013-04-12 09:24 833Java中的接口是一系列方 ... -
java
2013-04-11 15:25 7971. 深入Struts2的配置文件 本部分主要介绍 ... -
java 泛型
2013-04-11 10:12 878平时看java源代码的时候,如果碰到泛型的话,我想? T K ... -
list
2013-02-27 14:40 959在java里面要想去除list中的重复数据可以使用两种方式实 ... -
Java编程中“为了性能”需做的26件事
2013-02-21 15:59 647最近的机器内存又爆满 ... -
spring @Transactional配置说明 .
2013-02-06 11:13 1347事务注解说明@Transactional 类事务说明机制 ... -
java.util.ResourceBundle使用详解
2013-02-05 16:32 638java.util.ResourceBundle使 ... -
Java中的注解以及应用 @Deprecated @SupressWarning @Override
2013-02-05 16:25 908Annotation注解在Java中有着很广泛的,他是做为一种 ...
相关推荐
书中的挑战和练习题设计巧妙,鼓励读者实践和思考,从而深化对知识的理解。 总之,《Head First Java》第三版是一本不可多得的Java学习资源,其独特的教学方法和丰富的内容深受业界专家和Java社区的好评。无论你是...
9. **枚举和匿名类**:Java的枚举类型提供了一种安全的方式来表示固定数量的值,而匿名类则在需要简单实现一个接口或继承一个类时非常有用。 10. **垃圾收集和内存管理**:Java的自动内存管理是其区别于其他语言的...
这里提到的“我做过的经典java练习题”可能是一个集合,包含了作者在学习Java过程中遇到的一些具有代表性的题目。这些题目可能涵盖了许多Java的基础知识,如语法、数据类型、控制结构、类与对象、异常处理、多线程、...
3. **听课感想.pdf**:这份文件可能是作者在学习Java过程中对课程或者讲座的个人感悟和理解,包含了对某个主题的深度思考和反馈。通过阅读这样的笔记,我们可以了解作者对Java学习过程中的难点、重点和关键点的理解...
1. **函数式编程**:Java 8引入了 Lambda 表达式,这是一种简洁的匿名函数定义方式,它使得处理集合数据变得更加方便,特别是在并行编程中。Lambda表达式的核心概念是行为参数化,允许将代码视为数据进行传递。 2. ...
- **Innerclasses**:涉及Java中的内部类,包括匿名类、成员内部类、局部内部类等。 - **Holding**:可能是关于数据存储和容器(如ArrayList、LinkedList、HashSet等)的讨论。 - **Polymorphism**:讲解Java的多...
通过解答书中的课后习题,可以巩固这些基础知识,并加深对Java编程的理解。编程题的练习更是提升实际编程能力的有效途径,特别是偶数题,它们可能涉及到一些实战性的编程问题,帮助学习者将理论知识转化为实践技能。...
这个阶段将重点讲解面向对象编程的核心概念,包括成员变量、成员方法、封装、继承、多态、静态变量、静态方法、接口与抽象类、内部类、匿名内部类以及Lambda表达式。学习者需要了解基本的数据结构(如数组、链表、...
3. 内部类:介绍了Java中的匿名内部类、局部内部类、成员内部类和静态内部类,阐述了它们在实际编程中的应用和优势。 4. 泛型:讲解了泛型的概念,如何使用泛型类和泛型方法,以及类型擦除的原理。泛型提升了代码的...
这需要实现Java中的`ActionListener`接口,或者使用匿名内部类来处理这些交互。 3. **数据结构与算法**:棋盘的状态需要存储和更新。可以使用二维数组来表示棋盘,每个元素代表一个格子的状态(空、黑棋、白棋)。...
以下是一些Java面试中经常被问到的关键知识点,结合提供的文件名,我们可以推断出这些文档可能包含了Java基础知识、进阶主题以及面试策略。 1. **Java基础**: - **数据类型**:Java分为基本数据类型和引用数据...
- **匿名读者**:认为这是关于Java最好的书,并表示已经从1996年开始学习Java,本书帮助他巩固了许多模糊的概念,并扩展了他的知识面。 #### 三、主要内容概述 1. **基础知识**: - Java的历史和发展。 - Java的...
5. **类型推断(Type Inference)**:在匿名内部类和局部变量中,编译器能够自动推断出类型,减少了冗余的类型声明。 6. **可变参数(Varargs)**:允许方法接受不定数量的参数,提高了函数的灵活性。 这个课后...
以下是对“JAVA面试题汇总”文档中部分关键知识点的深入解析,旨在帮助求职者更好地准备JAVA面试。 ### 1. super()与this()的区别 在JAVA中,`super()`和`this()`都是用于构造函数中调用其他构造函数的关键字,但...
面试宝典中的基础部分按顺序包括:基本语法(如变量、数据类型、流程控制等)、类和对象(封装、构造器、访问修饰符等)、内部类(匿名类、局部内部类、成员内部类等)、继承(单一继承、接口、多态等)、异常处理...
接口在Java中用于定义一组行为规范,实现接口的类必须提供接口中声明的所有方法的具体实现。 ##### 7.1 接口体组织 - **默认**:接口中的成员默认为`public static final`(对于字段)和`public abstract`(对于...
10. **Java的高级特性**: 包括枚举、匿名类、内省、动态代理等,这些都是Java程序员应掌握的进阶知识。 11. **源代码分析**: 附带的源代码可以帮助读者更直观地理解书中的例子和概念,通过实践加深理解。 ...
在实际工作中,结合Java的特性(如多态、接口、匿名内部类等)灵活运用设计模式,能够解决许多复杂的问题,使代码更加优雅和高效。 总的来说,"java与设计模式"是一个涵盖广泛的主题,涉及Java编程中的高级技巧和...
这个名为"thinkinjava源码-think-in-java:用Java源代码思考"的资源很可能是该书中的示例代码库,允许读者通过实际代码来探索和理解书中讲解的概念。在"think-in-java-master"这个压缩包中,我们很可能找到了按照书本...
- 匿名内部类没有名字,可以实现接口或继承类,但只能继承一个类(因为Java不支持多继承)。不过,匿名内部类不能继承一个非静态的内部类,因为这需要一个外部类的实例,而匿名内部类自身没有。 3. **Static ...