是否可以在不破坏逻辑的情况下减少行数?
Is it possible to reduce the number of lines without breaking the logic?
我需要进行测试 - 哪个列表更快。为此,我 运行 每个测试都在一个新线程中进行。我在单独的 class 中为每个线程创建 运行nable 方法。我得到一个相当单调的代码,这是一个 DRY 违规行为。也许有人知道我如何可以同时 运行 所有线程而不破坏 DRY?
public class ThreadsManager {
public static boolean stopThreads = false; //We change this variable MainActivity
public static long timeOfStartTest = 0;
public void startCollThreads() {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
new Thread(collRunnable.addBeg(new ArrayList())).start();
new Thread(collRunnable.addBeg(new LinkedList())).start();
new Thread(collRunnable.addBeg(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.addMid(new ArrayList())).start();
new Thread(collRunnable.addMid(new LinkedList())).start();
new Thread(collRunnable.addMid(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.addEnd(new ArrayList())).start();
new Thread(collRunnable.addEnd(new LinkedList())).start();
new Thread(collRunnable.addEnd(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.search(new ArrayList())).start();
new Thread(collRunnable.search(new LinkedList())).start();
new Thread(collRunnable.search(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeBeg(new ArrayList())).start();
new Thread(collRunnable.removeBeg(new LinkedList())).start();
new Thread(collRunnable.removeBeg(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeMid(new ArrayList())).start();
new Thread(collRunnable.removeMid(new LinkedList())).start();
new Thread(collRunnable.removeMid(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeEnd(new ArrayList())).start();
new Thread(collRunnable.removeEnd(new LinkedList())).start();
new Thread(collRunnable.removeEnd(new CopyOnWriteArrayList())).start();
}
}
public class CollRunnable {
//region Adding in the beginning
public Runnable addBeg(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add(0, "");
}
updateViewModelValue(1,"Adding \nin the beginning", list);
};
}
//endregion
//region Adding in the middle
public Runnable addMid(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add(0, "");
}
updateViewModelValue(2, "Adding \nin the middle", list);
};
}
//endregion
//region Adding in the end
public Runnable addEnd(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
}
updateViewModelValue(3, "Adding \nin the end", list);
};
}
//endregion
//region Search
public Runnable search(List list) {
return () -> {
list.add(0);
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.get(0);
}
updateViewModelValue(4, "Search \nby value", list);
};
}
//endregion
//region Removing in the beginning
public Runnable removeBeg(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(5, "Removing \nin the beginning", list);
};
}
//endregion
//region Removing in the middle
public Runnable removeMid(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(6, "Removing \nin the middle", list);
};
}
//endregion
//region removing in the end
public Runnable removeEnd(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(7, "Removing \nin the end", list);
};
}
//endregion
private void updateViewModelValue(int numberOfTest, String testName, List list) {
new Handler(Looper.getMainLooper()).post(() -> {
DataClass dataClass = new DataClass(numberOfTest,testName, list, new Date().getTime() - timeOfStartTest);
getCollInstance().viewModel.testResult.setValue(dataClass);
});
}
}
一种方法是分离列表的创建。例如在界面的帮助下:
@FunctionalInterface
public interface ListFactory {
List create();
}
// In ThreadsManager
public void orquestate() {
startCollThreads(() -> new ArrayList());
startCollThreads(() -> new LinkedList());
startCollThreads(() -> new CopyOnWriteArrayList());
}
private void startCollThreads(ListFactory listFactory) {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
new Thread(collRunnable.addBeg(listFactory.create())).start();
new Thread(collRunnable.addMid(listFactory.create())).start();
// Other steps
}
这与列表类型首先开始的步骤不完全相同,但我不知道这对您是否重要。
您可以利用 Supplier 功能界面。如下所示,提取一个方法,该方法将测试作为参数传递给列表类型的给定 函数:
private void run_test(Function<List, Runnable> collRunnable) {
new Thread(collRunnable.apply(new ArrayList())).start();
new Thread(collRunnable.apply(new LinkedList())).start();
new Thread(collRunnable.apply(new CopyOnWriteArrayList())).start();
}
然后调整您的 startCollThreads
方法:
public void startCollThreads() {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
run_test(collRunnable::addBeg);
run_test(collRunnable::addMid);
run_test(collRunnable::addEnd);
run_test(collRunnable::search);
run_test(collRunnable::removeBeg);
run_test(collRunnable::removeMid);
run_test(collRunnable::removeEnd);
}
旁注
您正在使用 Raw 类型,您应该避免这种情况,see this source to see why。
您还可以通过参数化作为参数传递的列表来使其更通用:
private void run_test(Function<List, Runnable> collRunnable, Supplier<List>... lists) {
for (Supplier<List> list : lists) {
new Thread(collRunnable.apply(list.get())).start();
}
}
然后你可以调用不同列表的方法:
run_test(collRunnable::addBeg, ArrayList::new, LinkedList::new, CopyOnWriteArrayList::new);
或
run_test(collRunnable::addBeg, ArrayList::new);
您可以为此建议使用线程池 API。例如ExecutorService.html.invokeAll
例如:
try {
Runnable routine = (List<?> args) -> { // add your thread routine implementation }
// you can use same routine for all tasks, or make any combination such as 3 different routines in list etc
Runnable[] allTasks = new Runnable[8];
Arrays.fill(allTasks, routine);
ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// invoke all tasks from array in thread pool
pool.invokeAll( Arrays.asList(allTasks) );
// stop pool and await for it termination
pool.shutdown();
if (!pool.awaitTermination(60, TimeUnit.MINUTES)) {
pool.shutdownNow();
}
}
} catch (InterruptedException ie) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}
我需要进行测试 - 哪个列表更快。为此,我 运行 每个测试都在一个新线程中进行。我在单独的 class 中为每个线程创建 运行nable 方法。我得到一个相当单调的代码,这是一个 DRY 违规行为。也许有人知道我如何可以同时 运行 所有线程而不破坏 DRY?
public class ThreadsManager {
public static boolean stopThreads = false; //We change this variable MainActivity
public static long timeOfStartTest = 0;
public void startCollThreads() {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
new Thread(collRunnable.addBeg(new ArrayList())).start();
new Thread(collRunnable.addBeg(new LinkedList())).start();
new Thread(collRunnable.addBeg(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.addMid(new ArrayList())).start();
new Thread(collRunnable.addMid(new LinkedList())).start();
new Thread(collRunnable.addMid(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.addEnd(new ArrayList())).start();
new Thread(collRunnable.addEnd(new LinkedList())).start();
new Thread(collRunnable.addEnd(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.search(new ArrayList())).start();
new Thread(collRunnable.search(new LinkedList())).start();
new Thread(collRunnable.search(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeBeg(new ArrayList())).start();
new Thread(collRunnable.removeBeg(new LinkedList())).start();
new Thread(collRunnable.removeBeg(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeMid(new ArrayList())).start();
new Thread(collRunnable.removeMid(new LinkedList())).start();
new Thread(collRunnable.removeMid(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeEnd(new ArrayList())).start();
new Thread(collRunnable.removeEnd(new LinkedList())).start();
new Thread(collRunnable.removeEnd(new CopyOnWriteArrayList())).start();
}
}
public class CollRunnable {
//region Adding in the beginning
public Runnable addBeg(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add(0, "");
}
updateViewModelValue(1,"Adding \nin the beginning", list);
};
}
//endregion
//region Adding in the middle
public Runnable addMid(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add(0, "");
}
updateViewModelValue(2, "Adding \nin the middle", list);
};
}
//endregion
//region Adding in the end
public Runnable addEnd(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
}
updateViewModelValue(3, "Adding \nin the end", list);
};
}
//endregion
//region Search
public Runnable search(List list) {
return () -> {
list.add(0);
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.get(0);
}
updateViewModelValue(4, "Search \nby value", list);
};
}
//endregion
//region Removing in the beginning
public Runnable removeBeg(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(5, "Removing \nin the beginning", list);
};
}
//endregion
//region Removing in the middle
public Runnable removeMid(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(6, "Removing \nin the middle", list);
};
}
//endregion
//region removing in the end
public Runnable removeEnd(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(7, "Removing \nin the end", list);
};
}
//endregion
private void updateViewModelValue(int numberOfTest, String testName, List list) {
new Handler(Looper.getMainLooper()).post(() -> {
DataClass dataClass = new DataClass(numberOfTest,testName, list, new Date().getTime() - timeOfStartTest);
getCollInstance().viewModel.testResult.setValue(dataClass);
});
}
}
一种方法是分离列表的创建。例如在界面的帮助下:
@FunctionalInterface
public interface ListFactory {
List create();
}
// In ThreadsManager
public void orquestate() {
startCollThreads(() -> new ArrayList());
startCollThreads(() -> new LinkedList());
startCollThreads(() -> new CopyOnWriteArrayList());
}
private void startCollThreads(ListFactory listFactory) {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
new Thread(collRunnable.addBeg(listFactory.create())).start();
new Thread(collRunnable.addMid(listFactory.create())).start();
// Other steps
}
这与列表类型首先开始的步骤不完全相同,但我不知道这对您是否重要。
您可以利用 Supplier 功能界面。如下所示,提取一个方法,该方法将测试作为参数传递给列表类型的给定 函数:
private void run_test(Function<List, Runnable> collRunnable) {
new Thread(collRunnable.apply(new ArrayList())).start();
new Thread(collRunnable.apply(new LinkedList())).start();
new Thread(collRunnable.apply(new CopyOnWriteArrayList())).start();
}
然后调整您的 startCollThreads
方法:
public void startCollThreads() {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
run_test(collRunnable::addBeg);
run_test(collRunnable::addMid);
run_test(collRunnable::addEnd);
run_test(collRunnable::search);
run_test(collRunnable::removeBeg);
run_test(collRunnable::removeMid);
run_test(collRunnable::removeEnd);
}
旁注
您正在使用 Raw 类型,您应该避免这种情况,see this source to see why。
您还可以通过参数化作为参数传递的列表来使其更通用:
private void run_test(Function<List, Runnable> collRunnable, Supplier<List>... lists) {
for (Supplier<List> list : lists) {
new Thread(collRunnable.apply(list.get())).start();
}
}
然后你可以调用不同列表的方法:
run_test(collRunnable::addBeg, ArrayList::new, LinkedList::new, CopyOnWriteArrayList::new);
或
run_test(collRunnable::addBeg, ArrayList::new);
您可以为此建议使用线程池 API。例如ExecutorService.html.invokeAll
例如:
try {
Runnable routine = (List<?> args) -> { // add your thread routine implementation }
// you can use same routine for all tasks, or make any combination such as 3 different routines in list etc
Runnable[] allTasks = new Runnable[8];
Arrays.fill(allTasks, routine);
ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// invoke all tasks from array in thread pool
pool.invokeAll( Arrays.asList(allTasks) );
// stop pool and await for it termination
pool.shutdown();
if (!pool.awaitTermination(60, TimeUnit.MINUTES)) {
pool.shutdownNow();
}
}
} catch (InterruptedException ie) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}