简体   繁体   English

Java:尽管字符串不变,但如何“改变”字符串?

[英]Java: How to “mutate” a string, despite a string's immutability?

I am developing an API as a bit of a student hobby-project, and I'm using a url where different options can be added/subtracted to change the information received. 我正在开发一个API作为一个学生的爱好项目,我正在使用一个网址,可以添加/减少不同的选项来更改收到的信息。 I know strings are immutable, which has made things a bit challenging to work around neatly. 我知道字符串是不可变的,这使得整齐地解决问题变得有些困难。 I've come up with a few a messy ways, none that robust, to solve it, and I'm wondering if there is a standard approach. 我想出了一些混乱的方法,没有一个是强大的,解决它,我想知道是否有标准的方法。 I plan to have radio buttons (not assigned to a button a group; want all permutations) that will allow me to "include", "add", and "exclude" options. 我计划让单选按钮(未分配给一个按钮组;想要所有排列),这将允许我“包含”,“添加”和“排除”选项。

Thus, here is the string z?s=GOOG&t=7m&z=l&q=l&p=e50,m50&a=ss,sfs,vm,w14 used to interact with YahooFinance API. 因此,这里是用于与YahooFinance API交互的字符串z?s=GOOG&t=7m&z=l&q=l&p=e50,m50&a=ss,sfs,vm,w14 w14。 So, assume that I have some variable like this: 所以,假设我有一些像这样的变量:

 String options="z?s=GOOG&t=7m&z=l&q=l&p=e50,m50&a=ss,sfs,vm,w14"

Now, consider the part that says p=e50,m50 . 现在,考虑一下p=e50,m50 Suppose I have three radiobuttons 50 , 100 , 200 that I want to tick on/off to such that I'd have a string p=e50,m50,e100,m100,e200,m200 with all buttons on, and every possible other combination; 假设我有三个单选按钮50100200 ,我想剔开/关,使得我有一个字符串p=e50,m50,e100,m100,e200,m200与所有的按钮,和每一个可能的其它组合; ie with 100 off, it would look like: p=e50,m50,e200,m200 . 100关,它看起来像: p=e50,m50,e200,m200

Any thoughts? 有什么想法吗? I'd like to ultimately do the same with the other value ( ss,sfs , etc.) as well, however, let's just start with the moving averages. 我想最终对其他值( ss,sfs等)做同样的事情,但是,让我们从移动平均线开始。

Use a StringBuilder and the insert method. 使用StringBuilderinsert方法。

Java documentation page Java文档页面

Strings are only immutable in the sense that there is no way to change the contents of a particular instance of a string once it's created in the JVM. 字符串只是不可变的,因为在JVM中创建字符串后,无法更改字符串的特定实例的内容。 That said, that doesn't mean you can't construct strings on the fly that suit your needs. 也就是说,这并不意味着您无法动态构建符合您需求的字符串。 You could use simple concatenation and do something like... 您可以使用简单的连接并执行类似...

String options="z?s=GOOG&t=7m&z=l&q=l&p=" + eOption + ",m50&a=ss,sfs,vm,w14";

Technically, this creates three String instances, and a StringBuffer is used to append them all together. 从技术上讲,这会创建三个String实例,并使用StringBuffer将它们全部附加在一起。 You could use the StringBuffer API yourself and call .append() in the places you want to add options. 您可以自己使用StringBuffer API并在要添加选项的位置调用.append()。

Using mutable strings would just lead to messy code. 使用可变字符串只会导致代码混乱。 What you need is a data structure where it's easy to update the parameters, then traverse that data structure to create a string from it. 您需要的是一种数据结构,可以轻松更新参数,然后遍历该数据结构以从中创建字符串。 I'd store these parameters in a map and write a function that would create the string from the map by iterating through the map entries. 我将这些参数存储在一个映射中,并编写一个函数,通过迭代映射条目从地图创建字符串。

So you'd store your parameters in the map like: 因此,您将参数存储在地图中,如:

Map<String,String> map = new LinkedHashMap<>();
map.put("s", "GOOG");
map.put("t", "7m");

and generate the parameter string with something like: 并使用以下内容生成参数字符串:

public String createParameterString(Map<String, String> map) {
    StringBuilder builder = new StringBuilder("");
    for (Map.Entry mapEntry : map.entrySet()) {
        if (builder.length() != 0) builder.append("&");
        builder.append(mapEntry.key());
        builder.append("=")
        builder.append(mapEntry.value());
    }
    return builder.toString();
}

Usually, you break the string into parts, and assemble a new string. 通常,您将字符串分成几部分,然后组合一个新字符串。 The caller can then either maintain a reference to the old and new string, or simply discard the old one. 然后,调用者可以保持对旧字符串和新字符串的引用,或者只是丢弃旧字符串。

As a stupid example: 作为一个愚蠢的例子:

String hairySally = "hairy,sally";
String hairyFredSally = insertFred(hairySally);


String insertFred( String s) {
    String[] parts = s.split(",");
    return parts[0] + ",fred," + parts[1];
}

What you're looking for is formatted strings , for instance: 您正在寻找的是格式化字符串 ,例如:

String querystringFormat="z?s=GOOG&t=7m&z=l&q=l&p=%s&a=ss,sfs,vm,w14"

Note that e50,m50 has been replaced with %s , the format string code that indicates this part of the string will be replaced with another string. 请注意, e50,m50已替换为%s ,格式字符串代码表示该部分字符串将替换为另一个字符串。

Then, you would do whatever you do to build up your parameters, and do: 然后,您将执行任何操作来构建参数,并执行以下操作:

String params = "e50,m50,e100,m100,e200,m200", 
Formatter formatter = new Formatter();
formatter.format(querystringFormat, params);
String query = formatter.toString();

There's a lot of other options and details for using format strings, but that's the basic idea. 使用格式字符串还有很多其他选项和细节,但这是基本的想法。 The good part is that the unchanging part of the structure of your string is clear, and you only replace the parts that need replacing. 好的部分是字符串结构的不变部分是清晰的,您只需要替换需要替换的部分。

It'll also teach you how to use C and C++'s printf , which is never a bad thing :) 它还会教你如何使用C和C ++的printf ,这绝不是件坏事:)

Why do you want to mutate a string? 你为什么要变异字符串? And why do you approach this problem from the String perspective? 为什么从String的角度来看待这个问题呢? This question is not about text. 这个问题与文本无关。 What this sequence of characters 这个序列的字符是什么

?s=GOOG&t=7m&z=l&q=l&p=e50,m50&a=ss,sfs,vm,w14

represents it's just a map (also called a dictionary), ie a collection of key-value pairs, serialized according to the URI encoding scheme and appended to the URL of a HTTP request. 表示它只是一个映射(也称为字典),即一组键值对,根据URI编码方案序列化并附加到HTTP请求的URL。 You don't want to keep track of the serialized parts, especially because a URI accepts only a small subset of characters, so if you reason in terms of strings, you'll likely end up with non-working code. 您不希望跟踪序列化部分,特别是因为URI只接受一小部分字符,因此如果您根据字符串进行推理,您可能最终会得到非工作代码。

You need two methods: one to serialize a Map to the URI format, and one to get back a Map from its serialized form. 您需要两种方法:一种是将Map序列化为URI格式,另一种是从序列化形式中获取Map。 Note that the Yahoo protocol uses a comma to assign multiple values to the same key. 请注意,Yahoo协议使用逗号将多个值分配给同一个键。 You have to account for this, too, when serializing and deserializing. 在序列化和反序列化时,您也必须考虑到这一点。

I wrote a gist for you. 我为你写了一个要点 It's not thoroughly tested, but you get the idea. 它没有经过彻底的测试,但你明白了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM