Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使java中的条件块只执行一次?_Java_If Statement - Fatal编程技术网

如何使java中的条件块只执行一次?

如何使java中的条件块只执行一次?,java,if-statement,Java,If Statement,考虑一个文件读取场景,其中第一行是头。当逐行循环文件时,将使用“if条件”检查当前行是否为第一行 for(Line line : Lines) { if(firstLine) { //parse the headers }else { //parse the body } } 现在,由于控件已进入“if块”内部,在所有其他情况下,检查“if条件”是浪费时间的 java中是否存在这样的概念:一旦执行之后,特定的

考虑一个文件读取场景,其中第一行是头。当逐行循环文件时,将使用“if条件”检查当前行是否为第一行

for(Line line : Lines)
{
     if(firstLine)
     {
         //parse the headers
     }else
     {
         //parse the body
     }
}
现在,由于控件已进入“if块”内部,在所有其他情况下,检查“if条件”是浪费时间的

java中是否存在这样的概念:一旦执行之后,特定的代码行就会消失

我认为这将是一个伟大的功能,如果介绍或它已经存在

编辑:谢谢你的回答。如我所见,有许多基于“划分数据集”的方法。因此,不是“第一行”,而是考虑有一条“特殊的线”…

for(Line line : Lines) //1 million lines
{
     if(specialLine)
     {
         //handle the special line
     }else
     {
         //handle the rest
     }
}

在上面的代码块中,假设只有一半到100万次迭代后才出现特殊行,您将如何有效地处理此场景?

稍微更改一下逻辑如何

因为头是第一行,所以您可以获取第一行并单独解析它,然后从第二行开始解析主体:

List firstLine = Lines.get(0);
//parse the headers        ^------------------Get the first line
for (int i = 1; i < Lines.size(); i++) {
    //       ^--------------------------------Parse the body starting from the 2nd line
    //parse the body
}

在这种情况下,您不需要任何验证。

稍微更改一下逻辑怎么样

因为头是第一行,所以您可以获取第一行并单独解析它,然后从第二行开始解析主体:

List firstLine = Lines.get(0);
//parse the headers        ^------------------Get the first line
for (int i = 1; i < Lines.size(); i++) {
    //       ^--------------------------------Parse the body starting from the 2nd line
    //parse the body
}

在这种情况下,您不需要任何验证。

您可以通过伪代码简单地反转:

// parse headers
for(Line line: remainingLines)
{
但接下来:您将使用一个简单的布尔标志进行检查。如果check几乎是免费的,甚至更多:当这个循环看到如此多的重复而值得优化时,JIT将启动并为它创建优化的代码

如果JIT不起作用,就不值得对此进行优化。当然,在硬件层面上也有分支预测——换句话说:你可以期待现代硬件/软件确保实现最佳结果。除了编写清晰、简单的代码之外,您不需要做很多其他事情


从这个意义上说,你的问题是一个典型的过早优化的例子。你担心的方面不对。专注于编写干净、简单的代码来完成任务。因为这就是使JIT能够发挥其运行时魔力的原因。在jave源代码级别应用的大多数优化在运行时并不重要。

您可以通过伪代码简单地反转:

// parse headers
for(Line line: remainingLines)
{
但接下来:您将使用一个简单的布尔标志进行检查。如果check几乎是免费的,甚至更多:当这个循环看到如此多的重复而值得优化时,JIT将启动并为它创建优化的代码

如果JIT不起作用,就不值得对此进行优化。当然,在硬件层面上也有分支预测——换句话说:你可以期待现代硬件/软件确保实现最佳结果。除了编写清晰、简单的代码之外,您不需要做很多其他事情


从这个意义上说,你的问题是一个典型的过早优化的例子。你担心的方面不对。专注于编写干净、简单的代码来完成任务。因为这就是使JIT能够发挥其运行时魔力的原因。在jave源代码级别应用的大多数优化在运行时并不重要。

尝试划分数据集

public List head(List list) {
    return list.subList(0, 1);
}

public List tail(List list) {
    return list.subList(1, list.size());
}

head(lines).foreach( lambda: //parse the header)
tail(lines).foreach( lambda: //parse the body)

尝试分割数据集

public List head(List list) {
    return list.subList(0, 1);
}

public List tail(List list) {
    return list.subList(1, list.size());
}

head(lines).foreach( lambda: //parse the header)
tail(lines).foreach( lambda: //parse the body)

将布尔标志置于if-else之外,并在方法中输入标志时更改其状态。还要评估此标志以及条件

boolean flag=true;

for(Line line: Lines)
{
     if(firstLine && flag)
     {
 flag=false;
         //parse the headers
     }else
     {
         //parse the body
     }
}

将布尔标志置于if-else之外,并在方法中输入标志时更改其状态。还要评估此标志以及条件

boolean flag=true;

for(Line line: Lines)
{
     if(firstLine && flag)
     {
 flag=false;
         //parse the headers
     }else
     {
         //parse the body
     }
}

最简单的答案是使用某种标志来确保只将第一行作为头解析一次

boolean isHeaderParsed = false

for(Line line: Lines)
{
 if(!isHeaderParsed && firstLine)
 {
     //parse the headers
     isHeaderParsed = true
 }else
 {
     //parse the body
 }
}
这将实现你想要的。但是,如果您正在寻找更华丽的东西,那么接口就是您所需要的

Parser parser = new HeaderParser()
for(Line line: Lines)
{
  parser = parser.parse();
}

// Implementations for Parser
public class HeaderParser implements Parser{
    public Parser parse() {
         // your business logic
         return new BodyParser();
    }
}

public class BodyParser implements Parser{
    public Parser parse() {
         // your logic
         return this;
    }
}

这些通常被称为

最简单的答案是使用某种标志,以确保只将第一行作为头解析一次

boolean isHeaderParsed = false

for(Line line: Lines)
{
 if(!isHeaderParsed && firstLine)
 {
     //parse the headers
     isHeaderParsed = true
 }else
 {
     //parse the body
 }
}
这将实现你想要的。但是,如果您正在寻找更华丽的东西,那么接口就是您所需要的

Parser parser = new HeaderParser()
for(Line line: Lines)
{
  parser = parser.parse();
}

// Implementations for Parser
public class HeaderParser implements Parser{
    public Parser parse() {
         // your business logic
         return new BodyParser();
    }
}

public class BodyParser implements Parser{
    public Parser parse() {
         // your logic
         return this;
    }
}

这些通常被称为

,因为其他人都在发布一些奇怪的答案。你可以有一个接口

interface StringConsumer{
    void consume(String s);
}
然后在第一次尝试后只需更改接口

StringConsumer firstLine = s->{System.out.printf("first line: %s\n", s);};
StringConsumer rest = s->{System.out.printf("more: %s\n", s);};

StringConsumer consumer = firstLine;

for(String line: lines){
    consumer.consume(line);
    consumer = rest;        
}
如果您不喜欢分配,可以将consumer设置为字段,并在firstConsumer方法中更改其值

class StringProvider{
    StringConsumer consumer;
    List<String> lines;
    //assume this is initialized and populated somewhere.

    void process(){
        StringConsumer rest = s->{System.out.printf("more: %s\n", s);};
        consumer = s->{
            System.out.printf("firstline: %s\n", s);
            consumer = rest;
        };
        for(String line: lines){
            consumer.consume(line);
        }
    }
}


现在,第一个消费呼叫将切换正在使用的消费者。随后的电话会打给“其他”消费者。

因为其他人都在发布一些奇怪的答案。你可以有一个接口

interface StringConsumer{
    void consume(String s);
}
然后在第一次尝试后只需更改接口

StringConsumer firstLine = s->{System.out.printf("first line: %s\n", s);};
StringConsumer rest = s->{System.out.printf("more: %s\n", s);};

StringConsumer consumer = firstLine;

for(String line: lines){
    consumer.consume(line);
    consumer = rest;        
}
如果您不喜欢分配,可以将consumer设置为字段,并在firstConsumer方法中更改其值

class StringProvider{
    StringConsumer consumer;
    List<String> lines;
    //assume this is initialized and populated somewhere.

    void process(){
        StringConsumer rest = s->{System.out.printf("more: %s\n", s);};
        consumer = s->{
            System.out.printf("firstline: %s\n", s);
            consumer = rest;
        };
        for(String line: lines){
            consumer.consume(line);
        }
    }
}

现在,第一个消费呼叫将切换消费者tha
t正在被使用。随后的调用将发送给“rest”消费者。

因为没有人这么说,我只想继续说,这个额外的if语句实际上非常便宜,性能也很好

在机器的最底层,有一种称为分支预测的东西。当硬件无法预测其结果时,if语句往往非常昂贵。但当它做对了,用if测试布尔值几乎是免费的。由于您的if 99.99%的计算结果为假,任何硬件都可以正常工作

所以不要太担心这个。你不是在那里浪费时间


回答你的问题。。。它已经存在了。它不会消失,但如果您正确地编码它,它应该非常接近消失,因为没有人这么说,我将继续说,这个额外的if语句实际上非常便宜,性能方面也很好

在机器的最底层,有一种称为分支预测的东西。当硬件无法预测其结果时,if语句往往非常昂贵。但当它做对了,用if测试布尔值几乎是免费的。由于您的if 99.99%的计算结果为假,任何硬件都可以正常工作

所以不要太担心这个。你不是在那里浪费时间



回答你的问题。。。它已经存在了。它不会消失,但是如果你正确地编码它,它应该非常接近消失

它与java无关一些基本逻辑只需要使用一个标志并反转上面写的条件。java中没有这样的东西。但是:如果你有一个标题行和2亿行正文,那么在for循环之外解析标题是明智的。如果您总共有20行,那么这并不重要,因为性能差异可以忽略不计。如果有必要,JIT也会对其进行优化。您可以在firstline执行时拆分lines数组,并从当前循环中断。并对另一个循环中剩余的拆分数组执行其他工作。使用此选项,您可以保存剩余阵列的条件执行。为什么要这样做?有一个分支预测,所以从性能角度看,它没有多大区别。我注意到你的问题仍然悬而未决——因为你没有接受答案。请看一看,然后决定是否要回答。或者让我知道是否有什么我可以做的,以加强我的投入,使其值得接受。接受帮助未来的读者确定问题是否得到解决,并对花时间回答你的人表示感谢。谢谢这与java无关一些基本的逻辑只是使用一个标志并反转上面写的条件。java中没有这样的东西。但是:如果你有一个标题行和2亿行正文,那么在for循环之外解析标题是明智的。如果您总共有20行,那么这并不重要,因为性能差异可以忽略不计。如果有必要,JIT也会对其进行优化。您可以在firstline执行时拆分lines数组,并从当前循环中断。并对另一个循环中剩余的拆分数组执行其他工作。使用此选项,您可以保存剩余阵列的条件执行。为什么要这样做?有一个分支预测,所以从性能角度看,它没有多大区别。我注意到你的问题仍然悬而未决——因为你没有接受答案。请看一看,然后决定是否要回答。或者让我知道是否有什么我可以做的,以加强我的投入,使其值得接受。接受帮助未来的读者确定问题是否得到解决,并对花时间回答你的人表示感谢。谢谢唯一正确的答案。JIT足够聪明,可以发现这样简单的优化。在绝大多数情况下,试图比他们更聪明并不会让你走得更远。也可以在你的答案中添加分支预测,以便人们可以进一步调查他们是否对此处潜在优化的内部工作机制感兴趣。唯一正确的答案。JIT足够聪明,可以发现这样简单的优化。在绝大多数情况下,试图比他们更聪明并不会让你走得更远。也可能在你的答案中添加分支预测,以便人们可以进一步调查他们是否对此处潜在优化的内部工作机制感兴趣。非常聪明!只需确保列表大小大于1。否则您将获得IndexOutofBoundsException此问题的上下文没有包含足够的引用来输入或输出数据以及更高的上下文。无论如何,我会在上面的某个层上验证数据集。你是什么意思?上下文是一个列表。在原始代码中,任何大小的列表都无法获得IndexOutOfBoundsException。一定要在这里检查尺寸。非常聪明!只需确保列表大小大于1。否则你会得到一个IndexOutOfBoun
DSException此问题的上下文没有包含足够的输入或输出数据以及更高上下文的引用。无论如何,我会在上面的某个层上验证数据集。你是什么意思?上下文是一个列表。在原始代码中,任何大小的列表都无法获得IndexOutOfBoundsException。这里绝对应该进行尺寸检查。第一行就是这样一个标志。。。这并没有改变任何事情。一旦进入if block,它就会改变。我说的是,firstLine已经是一个布尔值,它做的事情与您的布尔值完全相同。firstLine是一个旗子firstLine就是这样一个旗子。。。这并没有改变任何事情。一旦进入if block,它就会改变。我说的是,firstLine已经是一个布尔值,它做的事情与您的布尔值完全相同。第一线是一面旗帜。这能实现什么?你是说,这个吗?firstLine已经是这样一个布尔值了,就像解析的ISHEADERD一样。因此,您的第一块代码不会改变任何内容。但是您的第二个代码块很有趣。但是你不认为即使在这里,赋值块“parser=parser.parse”也会通过for循环,而不是“if块”?如果for循环要运行一百万次,一百万个任务……这能完成什么?你是说,这个吗?firstLine已经是这样一个布尔值了,就像解析的ISHEADERD一样。因此,您的第一块代码不会改变任何内容。但是您的第二个代码块很有趣。但是你不认为即使在这里,赋值块“parser=parser.parse”也会通过for循环,而不是“if块”?如果for循环要运行一百万次,一百万个赋值..这里是Upvote-你在编写特殊代码之间找到了一个很好的平衡。。。不要完全过火。我发现其他答案真的进入了过早的优化领域。在这里投票-你在编写特殊代码之间找到了一个很好的平衡。。。不要完全过火。我发现其他答案真的进入了过早的优化领域。我喜欢你的方法。但即使在那里,线消费者=休息;循环完成for循环。如果for循环运行了几百万行呢?@BalajiVignesh如果你执行这一行足够多,它可以带来性能的提升,那么它肯定会得到优化。我怀疑你能否设计出一个能可靠地显示差异的基准。我会添加一个字段,这样你就不需要在循环中赋值了。我喜欢你的方法。但即使在那里,线消费者=休息;循环完成for循环。如果for循环运行了几百万行呢?@BalajiVignesh如果你执行这一行足够多,它可以带来性能的提升,那么它肯定会得到优化。我怀疑你能否设计出一个能可靠地显示差异的基准。我会添加一个字段,这样你就不需要在循环中赋值了。