转换技巧:在 Java 中灵活运用数组与字符串的互换操作
英文标题【Array to String Conversions】
概述
本页面中的内容对 Array 和 String 之间互相进行转换的方法进行一些说明。
我们可以使用 原生 Java(vanilla Java) 或者一些第三方的 Java 工具类来实现这个转换。ies.
将 Array 转换为 String
在有时候我们希望将字符串的数字或者整数类型的数组转换为字符串。但是如果我们直接使用 toString() 来进行转换的话,你可能会得到类似下面 Ljava.lang.String;@74a10858 的字符串。
上面的字符串显示的是对象的类型和当前这个对象的哈希代码。
但是, java.util.Arrays 工具类也能够支持一些 toString() 的方法来将 Array 转换为 String。
Arrays.toString() 将输入的数组转换为字符串,在转换后的字符串将会使用逗号分隔符,同时在字符串的前后会添加一个方括号 []。
可以考察下面的代码:
String[] strArray = {"one", "two", "three"};
String joinedString = Arrays.toString(strArray);
assertEquals("[one, two, three]", joinedString);
int[] intArray = {1, 2, 3, 4, 5};
joinedString = Arrays.toString(intArray);
assertEquals("[1, 2, 3, 4, 5]", joinedString);
StringBuilder 的 append() 方法
这个是基于 Java 的原生实现,你可以对需要转换的数组进行遍历,然后将遍历的结果使用 append() 方法添加到字符串后面。
String[] strArray = {"Convert", "Array", "With", "Java"};
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < strArray.length; i++) {
stringBuilder.append(strArray[i]);
}
String joinedString = stringBuilder.toString();
assertEquals("ConvertArrayWithJava", joinedString);
另外,如果你的数组中存储的数据是整形的话,那么你可以使用方法转换函数,首先将整数类型转换为字符串后再添加。
Java Streams API
从 Java 8 及其以上的版本,你可以使用 String.join() 方法将给出的数组元素使用不同的连接字符串连接在一起,在我们使用案例中,我们使用空白字符进行连接。
String joinedString = String.join("", new String[]{"Convert", "With", "Java", "Streams"});
assertEquals("ConvertWithJavaStreams", joinedString);
更多的是,我们可以使用 Java Streams API 中的 Collectors.joining() 方法来进行连接,这个连接的方法将会保留和输入数据相同的顺序。
String joinedString = Arrays
.stream(new String[]{"Convert", "With", "Java", "Streams"})
.collect(Collectors.joining());
assertEquals("ConvertWithJavaStreams", joinedString);
StringUtils.join()
Apache Commons Lang 为字符串处理提供了非常好的方法,能够很好的帮我们解决上面的问题。
这个 join 的方法可以通过输入的数据进行自动进行合并,合并的结果与你输入数据的顺序相同。
String joinedString = StringUtils.join(new String[]{"Convert", "With", "Apache", "Commons"});
assertEquals("ConvertWithApacheCommons", joinedString);
Joiner.join()
同样的 Guava 也提供了同样的工具类来使用。
例如,我们可以使用下面的代码来对数组进行连接。
String joinedString = Joiner.on("")
.skipNulls()
.join(new String[]{ "Convert", "With", "Guava", null });
assertEquals("ConvertWithGuava", joinedString);
将字符串转换为数组
同样的,在有些时候,我们希望能够将字符串转换为数组。
最常用的情况就是有一个输入的字符串,使用特定的分隔符,我们需要按照分隔符的位置将字符串拆分为数组。
String.split()
这个是最简单的方法了,可以直接把字符串中的字符使用给定的字符进行拆分,如下面的代码:
String[] strArray = "loremipsum".split("");
上面的代码将会生成下面的输出,因为我们没有给定任何分隔符,所以这个方法将会按照字符进行拆分。
["l", "o", "r", "e", "m", "i", "p", "s", "u", "m"]
StringUtils.split()
另外,可能用得最多的就是 Apache 的 Commons 中的 StringUtils ,这个能够对指定的字符串进行拆分。
如果使用 String 的方法进行拆分的话,可能会遇到空对象的问题,例如你输入的字符串可能是空字符串,这个时候 String 自带的原生方法将会抛出空异常。
如果使用 StringUtils 方法的话,可以有效的避免空对象的异常,因此这个工具类是非常常用的。在默认的情况下,这个方法使用的是空格作为分隔符。
String[] splitted = StringUtils.split("lorem ipsum dolor sit amet");
上面的方法将会输出下面的数组。
["lorem", "ipsum", "dolor", "sit", "amet"]
Splitter.split()
最后,你还可以使用 Guava 的拆分 API,如果 Apache Commons 提供的方法,通常 Guava 也能提供类似的。
例如我们可以使用下面的方法进行拆分,可以看到的是,我们在拆分的时候可以同时对结果进行处理。
List<String> resultList = Splitter.on(' ')
.trimResults()
.omitEmptyStrings()
.splitToList("lorem ipsum dolor sit amet");
String[] strArray = resultList.toArray(new String[0]);
上面的代码能够生成下面的结果:
["lorem", "ipsum", "dolor", "sit", "amet"]
结论
本页面对 String 和 Array 之间的转换方法进行了一些说明。一般来说可以使用原生方法进行转换,但是我们通常不建议使用,主要是方法功能比较差,同时还非常容易出现空对象异常。
因此建议使用 Apache Commons 或者 Guava 的相关方法进行转换。
https://www.ossez.com/t/java-array-string/13685
推荐阅读
-
一种结构设计模式,允许在对象中动态添加新行为。它通过创建一个封装器来实现这一目的,即把对象放入一个装饰器类中,然后把这个装饰器类放入另一个装饰器类中,以此类推,形成一个封装器链。这样,我们就可以在不改变原始对象的情况下动态添加新行为或修改原始行为。 在 Java 中,实现装饰器设计模式的步骤如下: 定义一个接口或抽象类作为被装饰对象的基类。 公共接口 Component { void operation; } } 在本例中,我们定义了一个名为 Component 的接口,该接口包含一个名为 operation 的抽象方法,该方法定义了被装饰对象的基本行为。 定义一个实现基类方法的具体装饰对象。 公共类 ConcreteComponent 实现 Component { public class ConcreteComponent implements Component { @Override public void operation { System.out.println("ConcreteComponent is doing something...") ; } } 定义一个抽象装饰器类,该类继承于基类,并将装饰对象作为一个属性。 公共抽象类装饰器实现组件 { protected Component 组件 public Decorator(Component component) { this.component = component; } } @Override public void operation { component.operation; } } } 在这个示例中,我们定义了一个名为 Decorator 的抽象类,它继承了 Component 接口,并将被装饰对象作为一个属性。在操作方法中,我们调用了被装饰对象上的同名方法。 定义一个具体的装饰器类,继承自抽象装饰器类并实现增强逻辑。 公共类 ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component 组件) { super(component); } } public void operation { super.operation System.out.println("ConcreteDecoratorA 正在添加新行为......") ; } } 在本例中,我们定义了一个名为 ConcreteDecoratorA 的具体装饰器类,它继承自装饰器抽象类,并实现了操作方法的增强逻辑。在操作方法中,我们首先调用被装饰对象上的同名方法,然后添加新行为。 使用装饰器增强被装饰对象。 公共类 Main { public static void main(String args) { Component 组件 = new ConcreteComponent; component = new ConcreteDecoratorA(component); 组件操作 } } 在这个示例中,我们首先创建了一个被装饰对象 ConcreteComponent,然后通过 ConcreteDecoratorA 类创建了一个装饰器,并将被装饰对象作为参数传递。最后,调用装饰器的操作方法,实现对被装饰对象的增强。 使用场景 在 Java 中,装饰器模式被广泛使用,尤其是在 I/O 中。Java 中的 I/O 库使用装饰器模式实现了不同数据流之间的转换和增强。 让我们打开文件 a.txt,从中读取数据。InputStream 是一个抽象类,FileInputStream 是专门用于读取文件流的子类。BufferedInputStream 是一个支持缓存的数据读取类,可以提高数据读取的效率,具体代码如下: @Test public void testIO throws Exception { InputStream inputStream = new FileInputStream("C:/bbb/a.txt"); // 实现包装 inputStream = new BufferedInputStream(inputStream); byte bytes = new byte[1024]; int len; while((len = inputStream.read(bytes)) != -1){ System.out.println(new String(bytes, 0, len)); } } } } 其中 BufferedInputStream 对读取数据进行了增强。 这样看来,装饰器设计模式和代理模式似乎有点相似,接下来让我们讨论一下它们之间的区别。 第三,与代理模式的区别: 代理模式的目的是控制对对象的访问,它在对象外部提供一个代理对象来控制对原对象的访问。代理对象和原始对象通常实现相同的接口或继承相同的类,以确保两者可以相互替换。 装饰器模式的目的是动态增强对象的功能,而这是通过对象内部的包装器来实现的。在装饰器模式中,装饰器类和被装饰对象通常实现相同的接口或继承自相同的类,以确保两者可以相互替代。装饰器模式也被称为封装器模式。 在代理模式中,代理类附加了与原类无关的功能。
-
南邮OJ Web任务大揭秘:层层挑战剖析 1. 挑战一:迷宫般的目录探索 题目作者似乎穷举了所有可能的目录组合,最终在404.php中的