我有一个for循环和这样的结构:
for(....)
....
....
if(isTrue)
... do something..
.. method to be executed once (doTrick) is declared outside for loop.
....endif
endfor
public void doTrick()
...
...
..end
for循环中的方法只能执行一次吗?
答案 0 :(得分:39)
当然!..
if(!alreadyExecuted) {
doTrick();
alreadyExecuted = true;
}
答案 1 :(得分:7)
您可以使用AtomicBoolean
确保只在第一次调用该任务:
public class Once {
private AtomicBoolean done = new AtomicBoolean();
public void run(Runnable task) {
if (done.get()) return;
if (done.compareAndSet(false, true)) {
task.run();
}
}
}
用法:
Once once = new Once();
once.run(new Runnable() {
@Override
public void run() {
foo();
}
});
// or java 8
once.run(() -> foo());
答案 2 :(得分:5)
您可以通过使用此技巧来避免if()
:
private Runnable once;
private final static Runnable NOP = new Runnable () {
public void run () {
// Do nothing
}
}
public void method () {
once = new Runnable () {
public void run () {
doTrick();
once = NOP;
}
}
for (...) {
...
once.run();
...
}
}
答案 3 :(得分:3)
在Java 8中,您可以使用自动记忆来有效地执行此操作,如下所述:Do it in Java 8: Automatic memoization
我承认,对于"运行一次"可能会被认为是过度杀戮。场景,但它是以前答案中描述的一些相当干净的替代方案。
例如:
public void doSomething() { ... }
Map<Boolean, Boolean> cache = new ConcurrentHashMap<>();
public void doSomethingOnce() {
cache.computeIfAbsent(true, x -> {
doSomething();
return true;
});
}
答案 4 :(得分:3)
如果您使用Kotlin,则可以执行以下操作:
val execOnce by lazy {
print("hello, world")
}
答案 5 :(得分:2)
或许break关键字是你需要的?运行方法后调用break;对不起,我不清楚你的问题是什么意思。
从sun docs看看here
答案 6 :(得分:2)
另一种矫枉过正的解决方案:
根据您的目的,可以使用静态初始化块。
public class YourKlass{
public void yourMethod(){
DoTrick trick;
for( int i = 0; condition; i++){
// ... (1)
trick = new DoTrick(); // or any kind of accessing DoTrick
// ... (2)
}
}
}
public class DoTrick{
static{
// Whatever should be executed only once
}
}
简单解决方案:
或者,您只想执行循环外的第一部分:
int i = 0;
if( condition ){
// ... (1)
// do trick
// ... (2)
}
for(i = 1; condition; i++){
// ... (1)
// ... (2)
}
答案 7 :(得分:1)
import java.util.ArrayList;
class RemoveDuplicate {
public static void main(String[] args) {
ArrayList<String> originalList = new ArrayList<String>();
originalList.add("foo");
originalList.add("bar");
originalList.add("bat");
originalList.add("baz");
originalList.add("bar");
originalList.add("bar");
String str="bar";
ArrayList<String> duplicateList = new ArrayList<String>();
// adding duplicates to duplicateList
for(String currentString : originalList) {
if(currentString.startsWith(str)) {
duplicateList.add(currentString);
}
}
// removing duplicates in duplicatesList
for(String removeString : duplicateList) {
originalList.remove(removeString);
}
// finally adding duplicateElement
originalList.add(str);
for(String currEntry : originalList) {
System.out.println(currEntry);
}
}
}
答案 8 :(得分:1)
我想做些更复杂的事情。在多线程环境中,请确保仅运行一种方法(上述方法已通过Hover Ruan的答案解决了),而且还要阻止任何线程,以便在该方法完成之前不会返回任何线程。
我的解决方案是使用信号量进行阻止。
function GetFrameBytes(detectionSettings, streamSource, frameNumber, callback)
{
detectionSettings["streamSource"] = streamSource;
detectionSettings["frameNumber"] = frameNumber;
client.GetFrame(detectionSettings, (error, response) =>
{
if(!error){
callback(response)
}
else
{
console.error(error);
}
});
}
程序应暂停,等待第一个线程完成,然后所有其他线程应完成打印第一次运行时存储的结果。
答案 9 :(得分:1)
或使用共享偏好:
sharedpref = PreferenceManager.getDefaultSharedPreferences(this);
isFirstRun = sharedpref.getBoolean("FIRSTRUN", true);
if (isFirstRun)
{
// Do your unique code magic here
SharedPreferences.Editor editor = wmbPreference.edit();
editor.putBoolean("FIRSTRUN", false);
editor.commit();
}else{
//this will repeat everytime
}
答案 10 :(得分:0)
我的应用中的示例:
boolean alreadyExecuted = false;
然后:
private void startMyService() {
if(!alreadyExecuted) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 4 seconds
context.startService(new Intent(context, myService.class));
alreadyExecuted = true;
}
}, 4000);
}
答案 11 :(得分:0)
这是一个示例方法。只需使用“ new Getlineonce();”
class Getlineonce {
static int[] linesRun = new int[0];
public Getlineonce() {
boolean lineRan = false;
int line = Thread.currentThread().getStackTrace()[2].getLineNumber();
for(int i = 0; i < linesRun.length; i++) {
if(line == linesRun[i]) {
lineRan = true; //Dont print
}
}
if(!lineRan) {
add(line);
System.out.println(line + " ran!");
}
}
public void add(int line) {
int newSize = linesRun.length+1;
int[] linesRunBuff = new int[newSize];
for(int i = 0; i < newSize-1; i++) {
linesRunBuff[i] = linesRun[i];
}
linesRunBuff[newSize-1] = line;
linesRun = linesRunBuff;
}
}