Apache CollectionUtils 的良好用途
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/477012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Good uses for Apache CollectionUtils
提问by javamonkey79
I found the CollectionUtilsclass a year or so ago and a few of the methods like, collect, and transform seem really cool, however, I have yet to find a use where it would not by syntactically cleaner and\or easier to just write the logic with a simple loop.
大约一年前,我发现了CollectionUtils类,其中的一些方法(例如,收集和转换)看起来非常酷,但是,我还没有找到一种用法,它不会通过语法更清晰和\或更容易来编写一个简单的循环逻辑。
Has any found a unique\useful use for these methods (transform, predicatedCollection, collect, etc) e.g. the methods that take a transformer or predicate as an argument?
有没有发现这些方法(transform、predicatedCollection、collect 等)的独特\有用的用途,例如将转换器或谓词作为参数的方法?
采纳答案by joel.neely
I think the key issue is designing/coding for flexibility.
我认为关键问题是设计/编码的灵活性。
If you have a single use case (e.g. selecting the members of a collection that satisfy some specific condition), then coding a relatively simple loop by hand works. On the other hand...
如果您只有一个用例(例如选择满足某些特定条件的集合成员),那么手动编写一个相对简单的循环就可以了。另一方面...
Suppose that the set of possible conditions grew large, or could even be composed on-the-fly at run-time (even dynamically, based on user input/interaction). Or suppose that there were a few very complex conditions which could be composed with operators (e.g. A and B, C and not D, etc.) into even more cases.
假设可能的条件集变得很大,或者甚至可以在运行时即时组合(甚至是动态的,基于用户输入/交互)。或者假设有一些非常复杂的条件可以用运算符(例如 A 和 B、C 而不是 D 等)组合成更多情况。
Suppose that, having made the selection, there was some other processing that was to be done on the resulting collection.
假设在进行了选择之后,还要对生成的集合进行一些其他处理。
Now consider the structure of the code that might result from a brute-force, in-line approach to writing the above: an outer loop containing a complex decision process to determine which test(s) to perform, mixed together with code that does one or more things with the "surviving" members of the collection. Such code tends to be (and especially to become over time with maintenance) difficult to understand and difficult to modify without the risk of introducing defects.
现在考虑使用蛮力、内联方法编写上述内容可能产生的代码结构:包含复杂决策过程的外循环,以确定要执行的测试,与执行一个或多个测试的代码混合在一起或与集合中“幸存”成员的更多东西。这样的代码往往(尤其是随着维护时间的推移而变得)难以理解和难以在不存在引入缺陷的风险的情况下进行修改。
So the point is to pursue a strategy in which each aspect:
所以关键是要追求一个战略,其中每个方面:
- basic "select something" process,
- predicates that express elementary criteria,
- combining operators that compose predicates, and
- transformers that operate on values,
- 基本的“选择某物”过程,
- 表达基本标准的谓词,
- 组合构成谓词的运算符,以及
- 对值进行操作的转换器,
can be coded and tested independently, then snapped together as needed.
可以独立编码和测试,然后根据需要拼凑在一起。
回答by Andrzej Doyle
collect() is useful when you have possible alternative representations of your objects.
当您有对象的可能替代表示时,collect() 很有用。
For example, recently I was dealing with a piece of code that needed to match lists of objects from two different sources. These objects were of different classes as they were used at different points in the code, but for my purposes had the same relevant concepts (i.e. they both had an ID, both had a property path, both had a "cascade" flag etc.).
例如,最近我正在处理一段需要匹配来自两个不同来源的对象列表的代码。这些对象属于不同的类,因为它们在代码中的不同点使用,但出于我的目的,它们具有相同的相关概念(即它们都有一个 ID,都有一个属性路径,都有一个“级联”标志等) .
I found that it was much easier to define a simple intermediate representation of these properties (as an inner class), define transformers for both concrete object classes (again very simple as it's just using relevant accessor methods to get the properties out), and then use collect()to convert my incoming objects into the intermediate representation. Once they're there, I can use standard Collections methods to compare and manipulate the two as sets.
我发现定义这些属性的简单中间表示(作为内部类)要容易得多,为两个具体对象类定义转换器(同样非常简单,因为它只是使用相关的访问器方法来获取属性),然后用于collect()将我传入的对象转换为中间表示。一旦它们到了那里,我就可以使用标准的 Collections 方法将两者作为集合进行比较和操作。
So as a (semi-)concrete example, let's say I need a method to check that the set of objects in the presentation layer is a subset of the objects cached in the data layer. With the approach outlined above this would be done something like this:
因此,作为(半)具体示例,假设我需要一种方法来检查表示层中的对象集是否是数据层中缓存的对象的子集。使用上面概述的方法,这将是这样完成的:
public boolean isColumnSubset(PresSpec pres, CachedDataSpec dataSpec)
{
final List<IntermediateRepresentation> presObjects = CollectionUtils.collect(pres.getObjects(), PRES_TRANSFORMER);
final List<IntermediateRepresentation> dataObjects = CollectionUtils.collect(dataSpec.getCached(), DATA_TRANSFORMER);
return dataObjects.containsAll(presObjects);
}
To me this is much more readable, with the last line conveying a real sense of what the method is doing, than the equivalent with loops:
对我来说,这更具可读性,最后一行传达了该方法正在做什么的真实意义,而不是等效的循环:
public boolean isColumnSubset(PresSpec pres, CachedDataSpec dataSpec)
{
for (PresSpecificObject presObj : pres.getObjects())
{
boolean matched = false;
for (CachedDataObject dataObj : dataSpec.getCached())
{
if (areObjectsEquivalent(presObj, dataObj)) // or do the tests inline but a method is cleaner
{
matched = true;
break;
}
}
if (matched == false)
{
return false;
}
}
// Every column must have matched
return true;
}
The two are probably about as efficient, but in terms of readability I'd say that the first one is much easier to immediately understand. Even though it comes in being more lines of code overall (due to defining an inner class and two transformers), the separation of the traversal implementation from the actual "true or false" logic makes the latter much clearer. Plus if you have any KLOC metrics it can't be bead either. ;-)
两者的效率可能差不多,但就可读性而言,我想说第一个更容易立即理解。尽管整体代码行数更多(由于定义了一个内部类和两个转换器),遍历实现与实际“真或假”逻辑的分离使后者更加清晰。另外,如果您有任何 KLOC 指标,它也不会是珠子。;-)
回答by Dave Ray
Although I agree with Uri in principle, without closures or function literals or whatever, Java imposes a pretty high syntactic cost to actually use methods like collect, transform, etc. In a lot of cases, the actual lines of code is the same or greater than if you had written the simple loop. addAll, removeAll, and all their friends that don't take function objects as arguments are indispensible though.
虽然我原则上同意 Uri,没有闭包或函数字面量或其他任何东西,Java 对实际使用诸如 collect、transform 等方法的语法施加了相当高的成本。在很多情况下,实际的代码行相同或更多比如果你写了简单的循环。不过,addAll、removeAll 和所有不将函数对象作为参数的朋友都是必不可少的。
All of this also applies to the equally good Google Collections API.
所有这些也适用于同样出色的Google Collections API。
It's sad that Sun has the power to fix these issues in Java 7, but it appears they won't. Cowards.
遗憾的是 Sun 有能力在 Java 7 中修复这些问题,但他们似乎不会。懦夫。
回答by John Nilsson
While we don't use the CollctionUtils we have implemented a few similar utilities our selves and from those we frequently use
虽然我们不使用 CollctionUtils 我们已经实现了一些类似的实用程序我们自己和我们经常使用的那些
empty(Collection c)
空(集合 c)
to test collections, strings and such for emptyness
测试集合、字符串等是否为空
has(...)
已(...)
that only returns !empty(...)
只返回 !empty(...)
mapToProperty(Collection c, String property, Class newType)
mapToProperty(Collection c, String property, Class newType)
this maps a collection of T1 to a collection of T2 using reflection to call "property"
这将使用反射调用“属性”将 T1 的集合映射到 T2 的集合
implode(Collection c, String sep)
内爆(集合 c,字符串 sep)
A sep seperated string with the elements of c
带有 c 元素的 sep 分隔字符串
回答by Uri
I'm not sure I agree with your statement...
我不确定我是否同意你的说法......
A simple loop adds complexity, and is less "readable and obvious" than a call with a sensible name.
一个简单的循环会增加复杂性,并且与具有合理名称的调用相比,其“可读性和明显性”较差。
Refactoring evangelists would claim that your goal should generally be to create flat and short functions that call other operations. While addAll, find, and such methods are easy to implement yourself, avoiding them would require the reader to grasp something more complex than a single word, and may cause code replication.
重构布道者会声称您的目标通常应该是创建调用其他操作的扁平和简短的函数。虽然 addAll、find 等方法很容易自己实现,但避免它们需要读者掌握比单个单词更复杂的东西,并且可能导致代码复制。
IMHO, CollectionUtils actually presents cleaner operations than the standard Java collection library.
恕我直言, CollectionUtils 实际上比标准的 Java 集合库提供了更清晰的操作。

