首页 > 解决方案 > 更有效地从控制台读取 int 值

问题描述

我怎样才能比这更有效地(从内存)从控制台读取 int 值:

BufferedReader in ...
number = Integer.parseInt(in.readLine());

当我使用readLine()并将其解析为 int 时,java 会创建许多 String 对象并消耗内存。我尝试使用Scannerand 方法nextInt(),但这种方法也不是那么有效。

PS 我需要读取 > 1000_000 个值并且我有内存限制。

编辑任务的完整代码

import java.io.*;

public class Duplicate {

    public static void main(String[] args) throws IOException {

        int last = 0;
        boolean b = false;

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(reader.readLine());

        for (int i = 0; i < n; i++) {
            int number =Integer.parseInt(reader.readLine());
            if (number == 0 && !b) {
                System.out.println(0);
                b = true;
            }
            if (number == last) continue;
            last = number;
            System.out.print(last);
        }
    }
}

并重写变体:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

public class Duplicate {

    public static void main(String[] args) throws IOException {

        int last = 0;
        boolean b = false;

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int nextInt = getNextInt(reader);

        for (int i = 0; i < nextInt; i++) {
            int number = getNextInt(reader);
            if (number == 0 && !b) {
                System.out.println(0);
                b = true;
            }
            if (number == last) continue;
            b = true;
            last = number;
            System.out.println(last);
        }
    }

    static int getNextInt(Reader in) throws IOException {
        int c;
        boolean negative = false;
        do {
            c = in.read();
            if (!Character.isDigit(c)) {
                negative = c == '-';
            }
        } while (c != -1 && !Character.isDigit(c));
        if (c == -1) return Integer.MIN_VALUE;

        int num = Character.getNumericValue(c);
        while ((c = in.read()) != -1 && Character.isDigit(c)) {
            num = 10 * num + Character.getNumericValue(c);
        }
        return negative ? -num : num;
    }
}

两个选项都不会从内存中传递(((

在此处输入图像描述

EDIT2我尝试分析

nt number = getRandom();从 1000000 开始

在此处输入图像描述

再次推出相同的 在此处输入图像描述

和飞溅GC

在此处输入图像描述

标签: javainputuser-input

解决方案


您可以一次读取in一个字符,检查它是否为数字,然后将其累积成一个数字。就像是:

int getNextInt(Reader in) throws IOException {
  int c;
  boolean negative = false;
  do {
    c = in.read();
    if (!Character.isDigit(c)) { negative = c == '-' };
  } while (c != -1 && !Character.isDigit(c));
  if (c == -1) return Integer.MIN_VALUE;  // Some sentinel to indicate nothing found.

  int num = Character.getNumericValue(c);
  while ((c = in.read()) != -1 && Character.isDigit(c)) {
    num = 10 * num + Character.getNumericValue(c);
  }
  return negative ? -num : num;
}

Ideone 演示

当然,这是非常原始的解析。但是您也许可以将此代码作为基础并根据需要对其进行调整。


推荐阅读