了解如何在Java应用程序中选择正确的方法参数类型并获得更健壮和更短的代码。
我们Java开发人员通常有一个使用方法参数的坏习惯,即不考虑实际需要什么,而只是选择我们习惯的,可用的或首先想到的东西。 考虑以下代表性示例:
private static String poem(Map<Integer, String> numberToWord) {return new StringBuilder().append("There can be only ").append(numberToWord.get(1)).append(" of you.\n").append("Harts are better of when there are ").append(numberToWord.get(2)).append(" of them together.\n").append("These ").append(numberToWord.get(3)).append(" red roses are a symbol of my love to you.\n").toString();}
使用上面的方法时,我们提供了一个将数字转换为字符串的Map。 例如,我们可能提供以下地图:
Map<Integer, String> englishMap = new HashMap<>();englishMap.put(1, "one");englishMap.put(2, "two");englishMap.put(3, "three");
当我们用englishMap调用我们的诗歌方法时,该方法将产生以下输出:
There can be only one of you.
Harts are better of when there are two of them together.
These three red roses are a symbol of my love to you.
听起来不错。 现在,假设您的重要人物是计算机迷,并且想为自己的诗增添趣味并给人留下深刻的印象,那么这就是要走的路:
Map<Integer, String> nerdMap = new HashMap<>();nerdMap.put(1, "1");nerdMap.put(2, "10");nerdMap.put(3, "11");
如果现在将nerdMap提交给poem方法,它将产生以下诗:
There can be only 1 of you.
Harts are better of when there are 10 of them together.
These 11 red roses are a symbol of my love to you.
与所有诗歌一样,很难判断哪首诗比另一首更浪漫,但我当然有自己的看法。
问题所在
上面的解决方案有几个问题:
首先,作为外部呼叫者,我们不能确定poem方法不会更改我们提供的Map。 毕竟,我们提供了一张地图,没有什么阻止接收者对地图做任何可能的事情,甚至完全清除整个地图。 当然可以通过使用Collections.unmodifiableMap()方法包装Map或提供现有地图的副本来避免此副本,从而避免该副本。
其次,当我们只需要将整数转换为String的内容时,我们就不得不使用Map。 在某些情况下,这可能会创建不必要的代码。 回想我们的nerdMap,可以使用Integer :: toBinaryString轻松计算地图中的值,而无需手动映射它们。
解决方案
我们应该努力准确地提供在任何给定情况下所需的内容,而不是更多。 在我们的示例中,我们应该修改poem方法以采用从整数到字符串的函数。 在调用方上如何实现此功能的重要性较低,它可以是映射或函数,也可以是代码或其他东西。 首先,这是应该如何做:
private static String poem(IntFunction<String> numberToWord) {return new StringBuilder().append("There can be only ").append(numberToWord.apply(1)).append(" of you.\n").append("Harts are better of when there are ").append(numberToWord.apply(2)).append(" of them together.\n").append("These ").append(numberToWord.apply(3)).append(" red roses are a symbol of my love to you.\n").toString();}
如果我们想将poem方法与Map一起使用,则可以这样简单地调用它:
// Expose only the Map::get methodSystem.out.println(poem(englishMap::get));
如果我们想像书呆子诗一样计算值,那么我们可以做得更简单:
System.out.println(poem(Integer::toBinaryString));
哎呀,我们甚至可以为另一种患有双重人格障碍的人写一首诗:
System.out.println(poem(no -> englishMap.getOrDefault(no + 1, Integer.toString(no + 1))));
这将产生以下诗歌:
There can be only two of you.
Harts are better of when there are three of them together.
These 4 red roses are a symbol of my love to you.
注意您的方法参数!
翻译自: https://www.javacodegeeks.com/2017/06/use-precise-java-method-parameters.html