我如何重构这个循环

我如何重构这个循环

本文介绍了我如何重构这个循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,我将原始数组和列表用于一个名为 Item 的类.出于遗留原因,这些可以互换使用(我也希望这只是一种类型,但它就是这样).

I've got an application where I use primitive arrays and Lists for a class called Item. These are used interchangeably for legacy reasons (I also wish this was just one type, but it's the way it is).

现在我必须添加一个像这样通过 for-each 循环工作的新方法:

Now I have to add a new method like this that works via a for-each loop:

public void something(Item... items) {
    for (Item i : items) {
        doStuff();
    }
}

public void something(List<Item> items) {
    for (Item i : items) {
        doStuff();
    }
}

换句话说,对于原始数组和列表,两次完全相同的方法.有什么方法可以很好地将其重构为单个方法吗?

In other words, exactly the same method twice for both primitive Arrays and Lists. Is there any way to nicely refactor this into a single method?

推荐答案

您不应该 (*) 在单个方法中执行此操作.Item[]List 是不相关的类型.

You shouldn't (*) do this in a single method. Item[] and List<Item> are unrelated types.

您应该让一个重载调用另一个:something(Item... items) 调用 something(List)something(List) 调用 something(Item... items).

You should make one of the overloads call the other: either something(Item... items) calls something(List<Item>), or something(List<Item>) calls something(Item... items).

两个选项中,数组重载最好调用列表重载:

Of the two options, it is better for the array overload to call the list overload:

public void something(Item... items) {
  something(Arrays.asList(item));
}

这很便宜,因为它不复制数组,而是包装它:创建ListO(1).

This is cheap, because it doesn't copy the array, but rather wraps it: creating the List is O(1).

如果您要从列表重载中调用数组重载:

If you were to invoke the array overload from the list overload:

public void something(List<Item> items) {
  something(items.toArray(new Item[0]));
}

这会更昂贵,因为 toArray 调用必须创建和填充数组:这是一个 O(n) 操作,其中 n 是列表的大小.但是,它有一个轻微的优势,即 something 将无法替换 List 的内容,因为对数组的任何更新都会在执行后简单地丢弃.

This would be more expensive, since the toArray call has to create and populate an array: it is an O(n) operation, where n is the size of the list. However, it has the slight advantage that something would not be able to replace the contents of the List, since any updates to the array are simply discarded after execution.

(*) 你可以,但这真的很糟糕,而且不是类型安全的,因为你必须接受一个 Object 参数,因为有没有其他常见的 ListItem[] 超类型;并且你最终还是不得不为这两种类型重复循环;并且您必须处理传入(在运行时)完全不相关的类型的可能性:

(*) You can, but it would be really gross, and not type-safe, as you'd have to accept an Object parameter, as there is no other common super type of List<Item> and Item[]; and you'd still end up having to repeat the loops for the two types; and you'd have to handle the possibility of a completely unrelated type being passed in (at runtime):

public void something(Object obj) {
  if (obj instanceof List) {
    for (Object element : (List<?>) obj) {
      Item item = (Item) element;  // Potential ClassCastException.
      doStuff();
    }
  } else if (obj instanceof Item[]) {
    for (Item item : (Item[]) obj) {
      doStuff();
    }
  } else {
    throw new IllegalArgumentException();
  }
}

真是一团糟.感谢制造商的重载.

What a mess. Thank the maker for overloads.

这篇关于我如何重构这个循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 06:50