6

直接操作数据是不好的做法,例如:

 Sorter.mergeSort(testData); //(testData is now sorted)

或者我应该创建数据的副本,然后像这样操作并返回:

 sortedData = Sorter.mergeSort(testData); // (sortedData is now sorted and testData remains unsorted)?

我有几种排序方法,我希望它们操作数据的方式保持一致。使用我的 insertSort 方法,我可以直接处理未排序的数据。但是,如果我想让未排序的数据保持不变,那么我将不得不在 insertSort 方法中创建未排序数据的副本并操作并返回它(这似乎相当不必要)。另一方面,在我的 mergeSort 方法中,我需要以一种或另一种方式创建未排序数据的副本,因此我最终做了一些似乎相当不必要的事情,以解决返回新的 sortedList:

List <Comparable> sorted = mergeSortHelper(target);
target.clear();
target.addAll(sorted);`

请告诉我哪个是更好的做法,谢谢!

4

5 回答 5

5

这取决于您是针对性能还是功能纯度进行优化。通常在 Java 中不强调功能纯度,例如Collections.Sort对您提供的列表进行排序(即使它是通过首先制作数组副本来实现的)。

我会在这里优化性能,因为这看起来更像是典型的 Java,任何想要的人都可以先复制集合,比如Sorter.mergeSort(new ArrayList(testData));

于 2013-09-18T15:23:10.947 回答
2

最佳做法是保持一致。

就我个人而言,我更喜欢我的方法不修改输入参数,因为它可能不适用于所有情况(如果他们需要保留原始顺序,您将责任推给最终用户制作副本)。

话虽如此,修改输入有明显的性能优势(尤其是对于大型列表)。所以这可能适合您的应用程序。

只要最终用户清楚该功能,无论哪种方式都可以涵盖您!

于 2013-09-18T15:26:27.877 回答
2

在 Java 中,我通常提供两种选项(无论如何,在编写可重用的实用程序方法时):

/** Return a sorted copy of the data from col. */
public List<T> mergeSort(Collection<T extends Comparable<T>> col);

/** Sort the data in col in place. */
public void mergeSortIn(List<T extends Comparable<T>> col);

我在这里对签名和类型进行了一些假设。也就是说,Java 规范 - 或者至少已经* - 通常是为了改变状态。这通常是一件危险的事情,尤其是跨 API 边界 - 例如更改通过其“客户端”代码传递给您的库的集合。特别是最小化整体状态空间和可变状态通常是设计良好的应用程序/库的标志。

听起来您想重复使用相同的测试数据。为此,我将编写一个构建测试数据并返回它的方法。这样,如果我在不同的测试中再次需要相同的测试数据(即在相同的数据上测试您的 mergeSort() / insertSort() 实现),您只需构建并再次返回它。我通常在编写单元测试(例如在 JUnit 中)时正是这样做的。

无论哪种方式,如果您的代码是供其他人使用的库类/方法,您应该清楚地记录其行为。

另外:在“真实”代码中,实际上不应该有任何理由指定合并排序是使用的实现。调用者应该关心它做了什么,而不是它是怎么做的——所以名称通常不会是 mergeSort()、insertionSort() 等。

(*) 在一些较新的 JVM 语言中,有意识地远离可变数据。Clojure 完全没有可变状态,因为它是一种纯函数式编程语言(至少在正常的单线程应用程序开发中)。Scala 提供了一组并行的集合库,它们不会改变集合的状态。这在多线程、多处理器应用程序中具有主要优势。由于集合使用了聪明的算法,这并不像天真的预期的那样耗费时间/空间。

于 2013-09-18T16:10:07.187 回答
0

可变对象应在函数中进行操作。喜欢Arrays#sort

但是不可变对象(如字符串)只能返回“新”对象。喜欢String#replace

于 2013-09-18T15:42:22.777 回答
0

在您的特定情况下,修改“实际”数据更有效。您正在对数据进行排序,据观察,处理已排序的数据而不是未排序的数据更有效。所以,我不明白为什么要保留未排序的数据。查看为什么处理排序数组比处理未排序数组更快?

于 2013-09-18T15:36:43.113 回答