Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.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_Binary - Fatal编程技术网

Java 字符串中的字符替换需要花费很多时间

Java 字符串中的字符替换需要花费很多时间,java,binary,Java,Binary,我试图替换字符串中的单个字符(位),这是一个二进制数。对于位替换,我设计了一种方法,它使用string.substring()method根据给定的索引对字符串进行简单的分区,然后将所有字符串连接起来。下面是方法- /* *Method will replace the index-th bit with bitToInsert in the given str */ String str = "11000110100110011111"; int

我试图替换字符串中的单个字符(位),这是一个二进制数。对于位替换,我设计了一种方法,它使用
string.substring()
method根据给定的索引对字符串进行简单的分区,然后将所有字符串连接起来。下面是方法-

    /*
     *Method will replace the index-th bit with bitToInsert in the given str
     */
    String str = "11000110100110011111"; 
    int index = 5;
    int bitToInsert = 0;
    if (index == 0) {
        str = str.substring(0, str.length() - 1) + bitToInsert;
    } else {
        str = str.substring(0, str.length() - index - 1) + bitToInsert + str.substring(str.length() - index);
    }

这可以很好地工作,但是当给定的str非常大时,需要花费很多时间来替换位。与上述方法相比,是否有其他方法可以在更短的时间内替换任何位?

如果使用
StringBuffer
而不是
String
,则可以执行以下操作:

StringBuffer sb = new StringBuffer("11000110100110011111");
sb.setCharAt(index, '0');

你可以这样做,但我不知道是否会更快

String temp = "1111111111111";
char[] array = temp.toCharArray();
array[5] = '0';
temp = new String(array);

您看到的性能问题是因为Java字符串是不可变的。换句话说,字符串一旦创建就不能更改。因此,要更改字符串中的一个字符,JVM必须复制整个字符串,如果它是一个大字符串,则需要一段时间

在上面的代码中,它实际上甚至比这更糟糕,因为您正在复制字符串的第一部分和字符串的第二部分(除了一个字符),然后必须将这些副本复制到最终结果中。如果上面的代码需要构建目标字符串,那么只需复制一次,就可以提高性能

如果你真的在处理一个长二进制数,你应该考虑一下。这对您的效果将取决于您在翻转某些位后对数据所做的操作

 String str = "11000110100110011111"; 
 BitSet bitSet = new BitSet(str.length());

 //All bits are unset at first so set any that correspond to a '1' in the String
 for (int i = 0; i < str.length(); i++) {
   if (str.charAt(i) == '1') {
     bitSet.set(i);
   }
 }

 int index = 5;
 boolean bitToInsert = false; //i.e. 0
 bitSet.set(index, bitToInsert);
String str=“110001100110011111”;
BitSet BitSet=新的位集(str.length());
//首先,所有位都未设置,因此设置与字符串中的“1”对应的任何位
对于(int i=0;i
使用位集和StringBuffer是个好主意。但是,我有另一个建议针对低内存和高速度进行了优化
根据二进制数的长度,使用int或long。 如果它不能适合长时间使用,请使用int/long数组,以更好地满足您的需要

我将在这里演示如何使用字节类型的数组存储110001100110011111:

 byte [] bits = new byte[1000];
 String str = "11000110100110011111";

 int arrayIndex=0; //position in array
 int bitIndex=0; //which bit at bits[arrayIndex] is it

 //put your bits into a byte array
 for (int i=0; i<str.length(); i++){
     arrayIndex = i / 8;
     bitIndex = i % 8; //you can have max 8 bits in a byte

     bits[arrayIndex]=  (byte) (bits[arrayIndex] | ((Byte.parseByte(""+str.charAt(i)) << bitIndex)));
 }
byte[]位=新字节[1000];
字符串str=“110001100110011111”;
int-arrayIndex=0//阵列中的位置
int-bitIndex=0//它是位[arrayIndex]上的哪个位
//将您的位放入字节数组

对于(int i=0;iCool,我以前不知道位集。不过,一个可能的问题是,如果OP需要反复将其转换为字符串表示形式或从字符串表示形式转换为字符串表示形式,这有点痛苦。我同意。正如我在回答中所说,
BitSet
在这里的效果将取决于对数据所做的操作。如果它需要再次作为
字符串
立即转换为
位集
的开销可能太大,但如果代码只需要检查和更改数据,
位集
可能是理想的选择。如果位串仅由一个线程访问,则使用StringBuilder而不是StringBuffer会更快,因为它可以避免不必要的同步很好的暗示。
 //for replacing bit bitNumber with bitValue (where bitValue is 0 or 1)
 void changeBit(int bitNumber, byte bitValue){
     int arrayIndex= bitNumber / 8;
     int bitIndex= bitNumber % 8;

     //clear bit first
     byte crtBit = (byte)(1 << bitIndex);
     crtBit = (byte) ~crtBit;
     bits[arrayIndex]= (byte) (bits[arrayIndex] & crtBit);
     //set bit to new value
     bits[arrayIndex]= (byte) (bits[arrayIndex] | (bitValue << bitIndex));
 }