java中有没有类似StringBuilder的class,唯一的区别就是它有固定的长度?
Is there a class in java similar to StringBuilder with the only difference that it has a fixed length?
像这样:
MyFixedLengthStringBuilder sb = new MyFixedLengthStringBuilder(2);
sb.append("123"); // <=== throws ArrayIndexOfOutBoundsException!
其余的完全一样。基本上我需要一个永远不会增长的StringBuilder
。
我看到 StringBuilder
是 final,因此无法扩展。授权听起来像是我在这里的唯一途径。你看到我需要的其他 hack/idea/solution 了吗?
你可以这样。您仍然需要一些重载方法来处理不同的参数计数和类型,但不必是完全委托。这只是一个简单的例子。它可以被加工成 class。编辑:修改以处理大多数方法。
interface TriConsumer<T,R,S> {
public void accept(T t, R r, S s);
}
public class StringBuilderSol {
static int size = 20;
static StringBuilder sb = new StringBuilder(size);
public static void main(String[] args) {
execute(sb::append, "This is fun!");
System.out.println(sb);
execute(sb::append, "Java!");
System.out.println(sb);
execute(sb::delete, 0,3);
execute(sb::replace,0,1,"I");
execute(sb::insert, 1, " like ");
execute(sb::delete, 7,15);
System.out.println(sb);
execute(sb::append, "time to crash");
}
public static <T> void execute(Consumer<T> con,
T v) {
con.accept(v);
checkLength();
}
public static <T,R> void execute(
BiConsumer<T, R> biCon,
T index, R val) {
biCon.accept(index, val);
checkLength();
}
public static <T,R,S> void execute(
TriConsumer<T, R, S> triCon,
T index, R arg1, S arg2) {
triCon.accept(index, arg1, arg2);
checkLength();
}
public static void checkLength() {
if (sb.length() > size) {
throw new IndexOutOfBoundsException();
}
}
}
版画
This is fun!
This is fun!Java!
I like Java!
Exception in thread "main" java.lang.IndexOutOfBoundsException
at Whosebug.StringBuilderSol.checkLength(StringBuilderSol.java:50)
at Whosebug.StringBuilderSol.execute(StringBuilderSol.java:32)
at Whosebug.StringBuilderSol.main(StringBuilderSol.java:25)
另一种选择(但也有其自身的问题)是设置一个定时器来定期检查 StringBuilder 的大小。
首先,客户要求没有明确说明:他们是在请求与 StringBuilder
分配兼容的 class,还是只是在请求具有特定任务的 class功能?
前者在技术上是不可能的,因为 StringBuilder
被声明为 final
,因此任何 StringBuilder
类型的变量将始终具有相同的行为。
后者允许您使用自己的方法指定自己的新 class。至于需求,客户可能会指定“我只需要 StringBuilder
的所有东西。”,因为他们懒得去实际检查他们需要什么。我认为如果你们双方都投入一些工作来缩小需求范围,那么你们很可能能够仅通过几种适合客户需求的方法来制作 class。
是的,正如您已经提到的,在这种情况下,使用具有原始 StringBuilder
class.
的构图是个好主意
当你要求 hack 时,理论上你可以编写自己的 java.lang.StringBuilder
实现并提供自定义 ClassLoader
来加载你的实现而不是标准 java 实现。不过,我希望这显然不是一个好的做法。
如果我可以创建自己的 class,它会是这样的,并且可以根据需要添加更多内容
public class MyFixedLengthStringBuilder {
StringBuilder sb;
int size;
public MyFixedLengthStringBuilder(int size) {
if(size < 0)
throw new IllegalArgumentException();
this.size = size;
sb = new StringBuilder(size);
}
public void append(String str) {
sb.append(str);
if(sb.length() > size) {
sb.setLength(size);
throw new ArrayIndexOutOfBoundsException();
}
}
}
像这样:
MyFixedLengthStringBuilder sb = new MyFixedLengthStringBuilder(2);
sb.append("123"); // <=== throws ArrayIndexOfOutBoundsException!
其余的完全一样。基本上我需要一个永远不会增长的StringBuilder
。
我看到 StringBuilder
是 final,因此无法扩展。授权听起来像是我在这里的唯一途径。你看到我需要的其他 hack/idea/solution 了吗?
你可以这样。您仍然需要一些重载方法来处理不同的参数计数和类型,但不必是完全委托。这只是一个简单的例子。它可以被加工成 class。编辑:修改以处理大多数方法。
interface TriConsumer<T,R,S> {
public void accept(T t, R r, S s);
}
public class StringBuilderSol {
static int size = 20;
static StringBuilder sb = new StringBuilder(size);
public static void main(String[] args) {
execute(sb::append, "This is fun!");
System.out.println(sb);
execute(sb::append, "Java!");
System.out.println(sb);
execute(sb::delete, 0,3);
execute(sb::replace,0,1,"I");
execute(sb::insert, 1, " like ");
execute(sb::delete, 7,15);
System.out.println(sb);
execute(sb::append, "time to crash");
}
public static <T> void execute(Consumer<T> con,
T v) {
con.accept(v);
checkLength();
}
public static <T,R> void execute(
BiConsumer<T, R> biCon,
T index, R val) {
biCon.accept(index, val);
checkLength();
}
public static <T,R,S> void execute(
TriConsumer<T, R, S> triCon,
T index, R arg1, S arg2) {
triCon.accept(index, arg1, arg2);
checkLength();
}
public static void checkLength() {
if (sb.length() > size) {
throw new IndexOutOfBoundsException();
}
}
}
版画
This is fun!
This is fun!Java!
I like Java!
Exception in thread "main" java.lang.IndexOutOfBoundsException
at Whosebug.StringBuilderSol.checkLength(StringBuilderSol.java:50)
at Whosebug.StringBuilderSol.execute(StringBuilderSol.java:32)
at Whosebug.StringBuilderSol.main(StringBuilderSol.java:25)
另一种选择(但也有其自身的问题)是设置一个定时器来定期检查 StringBuilder 的大小。
首先,客户要求没有明确说明:他们是在请求与 StringBuilder
分配兼容的 class,还是只是在请求具有特定任务的 class功能?
前者在技术上是不可能的,因为 StringBuilder
被声明为 final
,因此任何 StringBuilder
类型的变量将始终具有相同的行为。
后者允许您使用自己的方法指定自己的新 class。至于需求,客户可能会指定“我只需要 StringBuilder
的所有东西。”,因为他们懒得去实际检查他们需要什么。我认为如果你们双方都投入一些工作来缩小需求范围,那么你们很可能能够仅通过几种适合客户需求的方法来制作 class。
是的,正如您已经提到的,在这种情况下,使用具有原始 StringBuilder
class.
当你要求 hack 时,理论上你可以编写自己的 java.lang.StringBuilder
实现并提供自定义 ClassLoader
来加载你的实现而不是标准 java 实现。不过,我希望这显然不是一个好的做法。
如果我可以创建自己的 class,它会是这样的,并且可以根据需要添加更多内容
public class MyFixedLengthStringBuilder {
StringBuilder sb;
int size;
public MyFixedLengthStringBuilder(int size) {
if(size < 0)
throw new IllegalArgumentException();
this.size = size;
sb = new StringBuilder(size);
}
public void append(String str) {
sb.append(str);
if(sb.length() > size) {
sb.setLength(size);
throw new ArrayIndexOutOfBoundsException();
}
}
}