関数型プログラミングを達成するには、3つの方法
概要
概要
関数型プログラミングJava8の導入は、多くの複雑なコードを大幅に簡略化することができた後に、偶数ワードを簡略化することができます。ここで主に実施例を介して、静的メソッド、およびコードの利点と欠点の方法の簡単な例を用いて、ラムダ式の分析を使用して。
ディレクトリ
(直接ジャンプします)
ディレクトリ
(直接ジャンプします)* 1.はじめに
* 2.ラムダ式
* 3.静的メソッドを使用します
* 4例の方法
* 5.まとめ
1.はじめに
この例を通じて、一つは、他の一方で、エレガントなインターフェイスを使用する方法をどのように貧しい自分の前に書かれたコードの読みやすさを知ることができます実現することができます。それは、このインターフェイスを実装して知っている場合にのみ、以前にクラスを代表して、使用するインターフェースは、いくつかの能力を持っています。しかし、この例に従うことによって、私はインターフェイスも方法で使用することができました。インタフェースの実装が、唯一の(入力/戻り値)を提供する必要がラムダ式から入力するとき。
2.ラムダ式
次のコードを見て:kのマップ、V値が異なるコネクタで印刷されています
public static void printWithComma(Map<String, String> map1, Map<String, String> map2) {
for (Map.Entry<String, String> entry : map1.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "," + value);
}
for (Map.Entry<String, String> entry : map2.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "," + value);
}
}
public static void printWithDash(Map<String, String> map1, Map<String, String> map2) {
for (Map.Entry<String, String> entry : map1.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "-" + value);
}
for (Map.Entry<String, String> entry : map2.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "-" + value);
}
}
public static void printWithColon(Map<String, String> map1, Map<String, String> map2) {
for (Map.Entry<String, String> entry : map1.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + ":" + value);
}
for (Map.Entry<String, String> entry : map2.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + ":" + value);
}
}
复制代码
重複したコードの多くの中に発見読んだ後、自然に共通のコードのいずれかが抽出できる、と思います。そして機能は、2つの入力マップはラインBiConsumerインタフェースの設定で、空間を与えること、です。したがって、共通のインタフェースはBiConsumer抽出方法、コードの再利用の実現を実現することができます。
コードは以下の通りであります:
public static void printWithConsumer(
Map<String, String> map1,
Map<String, String> map2,
BiConsumer<String, String> consumer) {
map1.forEach(consumer);
map2.forEach(consumer);
}
复制代码
印刷の方法は、文に減らすことができます。
public static void printWithComma(Map<String, String> map1, Map<String, String> map2) {
printWithConsumer(map1, map2, (s, s2) -> System.out.println(s+","+s2));
}
复制代码
3.静的メソッドを使用します
また、第2の方法の第2例の使用が簡略化されます。
public static void printWithDash(Map<String, String> map1, Map<String, String> map2) {
printWithConsumer(map1, map2, RefactorToConsumer::staticPrintWithDash);
}
public static void staticPrintWithDash(String s1, String s2) {
System.out.println(s1 + "-" + s2);
}
复制代码
定义的静态方法消耗两个String,得到一个void,符合BiCounsumer的约定,所以可以使用静态方法引用的方式简化代码。
分析二者优缺点:
1.使用静态方法可以给方法取名字,这样更加直观,更容易被理解。
2.使用静态方法可以在方法中写较为复杂的代码,而Lambda中一般就是一两句话。所以需要较多的代码实现的时候,最好还是在静态方法中声明。
4.使用实例方法
为了便于理解,这里使用另外一个简单的例子: 对一个User类实现过滤
代码如下:
public class User {
private final Integer id;
private final String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
// 过滤姓张的用户
public static List<User> filterZhangUsers(List<User> users) {
List<User> list = new ArrayList<>();
for (User user:users
) {
if (user.name.startsWith("张")){
list.add(user);
}
}
return list;
}
}
复制代码
为了减少排版,我这里只写了一个过滤器,但是可以想象如果需要过滤姓王的,ID为偶数的User...我们就可以将其抽取出来,形成一个公共的抽取方法。无论用前面的Lambda表达式也好,用静态方法也可以,实现Predicate接口即可。除此之外,我们还发现这个判定的过程其实就是User类型转换为boolean类型的过程,而恰好方法就是在User类中定义的。所以不必将方法定义成static类型,使用实例方法即可。
代码如下:
public static List<User> filterZhangUsers(List<User> users) {
return filter(users,User::filterNameStartWithZhang);
}
public boolean filterNameStartWithZhang(){
return this.name.startsWith("张");
}
public static List<User> filter(List<User> users, Predicate<User> predicate) {
List<User> results = new ArrayList<>();
for (User user : users
) {
if (predicate.test(user)) {
results.add(user);
}
}
return results;
}
复制代码
由于 filterNameStartWithZhang()方法是非静态的,在方法形参表中看似是空的,实际上形参是(User this),符合Predicate的从某一类型到boolean的设定。
5.总结
概要:
1.重複リファクタリングの多くは、非常に必要なものです。有形コードの量を削減するだけでなく、事実上のバグの可能性を低減し、大幅にコードの可読性を向上させる。だけでなく、
2.ラムダ式を注意し、式の中の変数の参照が効果的に、最終的なタイプである必要があり、それ以外の場合は報告します「ラムダ式で使用される変数であるべき最終的または効果的に最後の」。
解決策:
パラメータの1原子の種類を使用することができます。2.パラメータは、グローバル型として宣言することができます。
詳細はこちらの記事を参照してください。zhuanlan.zhihu.com/p/82921974を