用Java将多个列表中的数据提取到新列表中最优雅的方法是什么?
这可能有点主观,但我经常发现,看到其他开发人员如何处理某些日常细节是非常有趣的 我有这样的代码:用Java将多个列表中的数据提取到新列表中最优雅的方法是什么?,java,list,coding-style,Java,List,Coding Style,这可能有点主观,但我经常发现,看到其他开发人员如何处理某些日常细节是非常有趣的 我有这样的代码: class A { public List<SomeType> getOneSet() { ... } public List<SomeType> getAnotherSet() { ... } } class B { public static OtherType convert(SomeType input) { ... } } // ...
class A {
public List<SomeType> getOneSet() { ... }
public List<SomeType> getAnotherSet() { ... }
}
class B {
public static OtherType convert(SomeType input) { ... }
}
// ...
A a = new A();
List<OtherType> rgResults = new ArrayList<OtherType>();
interface Getter<E, I>
{
public E get(I item);
}
public static <T extends Collection<E>, I, E> T convert(T target, Collection<I> source, Getter<E, I> getter)
{
for (I item : source)
{
target.add(getter.get(item));
}
return target;
}
List<String> strings = CollectionUtil.convert(
new ArrayList<String>(someItems.size)
someItems,
new Getter<String, MyClass>()
{
public String get(MyClass item)
{
return item.toString();
}
}
);
这是可行的,但它当然是代码重复。如果循环中的代码变得更复杂,或者有两个以上的集合,那么这是不可接受的
因此,我将循环放在一个以源和目标列表为参数的函数中,但我很好奇是否还有其他方法。尤其是当您从不从多个位置调用函数时,更合适的方法
例如,我希望以下内容不起作用,因为我不能有泛型数组:
for (List<SomeType> rgSrc : new List<SomeType>[] { a.getOneSet(), a.getAnotherSet() } ) {
for (SomeType src : rgSrc) {
rgResults.add(B.convert(src));
}
}
for(List rgSrc:new List[]{a.getOneSet(),a.getAnotherSet()}){
for(SomeType src:rgSrc){
rgResults.add(B.convert(src));
}
}
试试看。这有一个链接迭代器的方法。尝试以下方法:
class A {
public List<SomeType> getOneSet() { ... }
public List<SomeType> getAnotherSet() { ... }
}
class B {
public static OtherType convert(SomeType input) { ... }
}
// ...
A a = new A();
List<OtherType> rgResults = new ArrayList<OtherType>();
interface Getter<E, I>
{
public E get(I item);
}
public static <T extends Collection<E>, I, E> T convert(T target, Collection<I> source, Getter<E, I> getter)
{
for (I item : source)
{
target.add(getter.get(item));
}
return target;
}
List<String> strings = CollectionUtil.convert(
new ArrayList<String>(someItems.size)
someItems,
new Getter<String, MyClass>()
{
public String get(MyClass item)
{
return item.toString();
}
}
);
接口Getter
{
公共E-get(I项);
}
公共静态T转换(T目标、集合源、Getter Getter)
{
对于(I项:来源)
{
add(getter.get(item));
}
回报目标;
}
列表字符串=CollectionUtil.convert(
新建ArrayList(someItems.size)
一些项目,
新吸气剂()
{
公共字符串获取(MyClass项)
{
return item.toString();
}
}
);
您只需根据需要根据需要执行
Getter
。ListUtils函数union(java.util.List list1,java.util.List list2)来自Apache commons collection API的任务==>也=]对于完全不使用循环的解决方案,您可以使用lambdaj转换功能:
请参见遵循“使用他人代码”的原则,我认为您会发现最干净的实现将出现在 你可以做:
for (SomeType input : Iterables.concat(a.getOneSet(), a.getAnotherSet()) {
rgResults.add(B.convert(input);
}
或者,如果将B重写为a并使用:
你完了 从数组中删除泛型参数,循环应该可以工作(尽管会收到警告):
for(List rgSrc:new List[]{a.getOneSet(),a.getAnotherSet()}){
for(SomeType src:rgSrc){
rgResults.add(B.convert(src));
}
}
+1:您还可以使用容量源创建ArrayList.size()。@Adamski:确实可以。在如何创建返回的列表(或者什么应该是集合)方面,我通常会稍微复杂一些,以便调用代码能够控制它。事实上,现在让我修改这个示例,因为源和目标不是同一类型。我正在添加已转换的项目。很酷,但在我的情况下,我不想再添加一个库,只是为了那一点好处。与接口一起使用。
for (List<SomeType> rgSrc : new List[] { a.getOneSet(), a.getAnotherSet() } ) {
for (SomeType src : rgSrc) {
rgResults.add(B.convert(src));
}
}