Guava 中的链接顺序
我对番石榴及其风格有点陌生。我确实在挖掘它,但我一直被绊倒的一件事是链式方法的顺序。我似乎遇到这个问题最多的是使用复合Ordering
时。我必须不断问自己这样的问题:
自然
去哪儿了?nullFirst
(或最后一个)去哪里了?- 哪个
nullsFirst
做什么? (在下面的示例中,一个用于主机,一个用于姓氏,一个用于名字?)
这是我刚刚正在处理的一个示例。它看起来很麻烦,我只是不确定我是否把它们放在一起正确。我有一些 JUnit 来测试它,看起来还不错,但总是存在那些奇怪的边界情况。
Ordering<Host> lastNameThenFirstNameOrdering = Ordering.natural().nullsFirst().onResultOf(new Function<Host, String>() {
public String apply(Host host) {
return host.getLastName();
}}).compound(Ordering.natural().nullsFirst().onResultOf(new Function<Host, String>() {
public String apply(Host host) {
return host.getFirstName();
}})).nullsFirst();
至于一个实际问题:这些事情如何执行是否有明确的规则?它似乎是从最后到第一个,但我很难说清楚。
编辑:只是想指出我试图替换的又大又丑的代码:
Ordering<Host> ordering2 = new Ordering<Host>() {
public int compare(Host host1, Host host2) {
if (host1 == null || host2 == null) {
return host1 == host2 ? 0 : ((host1 == null) ? -1 : 1);
}
if(host1.getLastName() != null || host2.getLastName() != null){
if (host1.getLastName() == null) {
return -1;
} else if (host2.getLastName() == null) {
return 1;
}
if (host1.getLastName().compareTo(host2.getLastName()) != 0) {
return host1.getLastName().compareTo(host2.getLastName());
}
}
if (host1.getFirstName() == null) {
return -1;
} else if (host2.getFirstName() == null) {
return 1;
}
return host1.getFirstName().compareTo(host2.getFirstName());
}};
I'm a bit new to Guava and it's style. I'm definitely digging it, but one thing I keep tripping over is the order of chained methods. Where I seem to have this problem the most is when using compound Ordering
s. I have to keep asking myself questions like:
- Where does the
natural
go? - Where does the
nullFirst
(or last) go? - Which
nullsFirst
does what? (In the example below, one for host, one for last name, one for first name?)
Here's an example of one that I was just working on. It looks cumbersome, and I'm just not sure if I put it all together right. I have some JUnits to test it, and it seems okay, but there are always those quirky boundary cases.
Ordering<Host> lastNameThenFirstNameOrdering = Ordering.natural().nullsFirst().onResultOf(new Function<Host, String>() {
public String apply(Host host) {
return host.getLastName();
}}).compound(Ordering.natural().nullsFirst().onResultOf(new Function<Host, String>() {
public String apply(Host host) {
return host.getFirstName();
}})).nullsFirst();
As for an actual question: Is there a well-defined rule for how these things get executed? It seems to be last-to-first, but I'm having trouble telling that.
edit: Just wanted to point out the large, ugly code I was trying to replace:
Ordering<Host> ordering2 = new Ordering<Host>() {
public int compare(Host host1, Host host2) {
if (host1 == null || host2 == null) {
return host1 == host2 ? 0 : ((host1 == null) ? -1 : 1);
}
if(host1.getLastName() != null || host2.getLastName() != null){
if (host1.getLastName() == null) {
return -1;
} else if (host2.getLastName() == null) {
return 1;
}
if (host1.getLastName().compareTo(host2.getLastName()) != 0) {
return host1.getLastName().compareTo(host2.getLastName());
}
}
if (host1.getFirstName() == null) {
return -1;
} else if (host2.getFirstName() == null) {
return 1;
}
return host1.getFirstName().compareTo(host2.getFirstName());
}};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为你的做法是正确的,但非常丑陋。为了提高可读性,请尝试以下操作:
使用枚举
将函数移动到实现
Function
的枚举。每个枚举项都可以提供它自己的实现。缩进代码
现在引用这些枚举函数并正确缩进代码。这就是它的样子:
我想说这会让一切变得更容易理解。
IDE 配置
关于正确的缩进(至少如果您使用 Eclipse),请参阅以下问题:
枚举作为函数
关于枚举:这称为枚举单例模式。 Guava 的人在他们的代码库中都使用它。 在维基百科或Effective Java,第 3 项。虽然这些来源都讨论单项枚举,但这里的方法几乎相同。
I think what you do is correct, but awfully ugly. Try this for readability:
Use an Enum
Move the functions to an enum that implements
Function<Host, String>
. Each of the enum items can provide it's own implementation.Indent your Code
Now reference those enum functions and indent your code properly. This is what it will look like:
I'd say that makes everything much more understandable.
IDE Configuration
Regarding proper indentation (at least if you use Eclipse), see this question:
Enums as Functions
Regarding the enum: this is called the enum singleton pattern. The Guava guys use it all over their code base. Read about it on wikipedia or in Effective Java, Item 3. Although those sources both talk about single-item enums, the approach is almost the same here.
每个链接调用都会将先前的顺序“包装”到新的顺序中,所以你是对的,执行顺序可以被认为是“向后”的。
我编写并审阅了 Ordering 类,但我仍然经常不得不停下来,为 nullsFirst()、onResultOf() 和 reverse() 的正确交错摸不着头脑!
Each chaining call is "wrapping" the previous ordering into a new one, so you're right, the execution order can be thought of as "backwards".
I wrote and reviewed the Ordering class and I still regularly have to stop and scratch my head over the correct interleaving of nullsFirst(), and onResultOf() and reverse()!
以下是我对此的偏好,假设您必须能够处理
null
主机、名字和姓氏。对我来说,似乎非null
名字和姓氏应该是Host
类的要求。通常,您应该尽量避免允许集合包含null
对象。或者,我会采取类似于 Sean 的方法,但为了可读性而将其分解。
请记住,您还可以将这些单独的排序设置为类的静态最终字段,以便您在排序时可以在任何地方轻松使用它们,例如
Host.LAST_NAME_ORDER
。The following would be my preference for doing this, assuming you must be able to handle
null
hosts, first names and last names. To me, it seems like a non-null
first name and last name ought to be a requirement of theHost
class. And you should generally try to avoid allowing collections to containnull
objects.Alternatively, I'd take an approach similar to Sean's but break things down for readability.
Keep in mind that you could also make these individual orderings static final fields of the class, allowing you to easily use them anywhere when sorting like
Host.LAST_NAME_ORDER
.