Build code by using Concatenation? - java

Is there a way i can create code build code by using Concatenation in Android studio/eclipse?
In other words i have 2 sets of strings one for each country i am dealing with ZA and KE. They have 2 different EULA's.
So i would like to pull the string related to the respective country.
String message = mContext.getString(R.string.eula_string_za);
above is an example of the output code. is there someway i can go about "creating" that based on If statements?
String str = "mContext.getString(R.string.eula_string_";
if (something = "ZA") {
str += "za);";
} else {
str += "ke);";
}
so if the country selected is ZA then the output code should be
mContext.getString(R.string.eula_string_za);
and if its KE it should be
mContext.getString(R.string.eula_string_ke);
and then the result will then pull the correct string from strings.xml?

Java is a compiled code, not an executed one,you can't write code this way like in an interpreted language.
The best way to manage different languages in android is to use a string.xml file for each language.
Take a look at this tutorial, it will help you a lot :
Supporting different languages in android

If you want to go this route you could try to use reflection. Have a look at Class.getField(…) if you want to use reflection.
Instead of first building a code string using a if statement you can also use the same if statement to find the correct string:
String str;
if (something.equals("ZA")) {
str = mContext.getString(R.string.eula_string_za);
} else {
str = mContext.getString(R.string.eula_string_ke);
}
Note that your condition something = "ZA" does not do what you think it does: It assigns something the string "ZA" and then evaluates itself to "ZA", so this would not even compile. The correct way would be something == "ZA", but even this does not work in the general case. You need to use String.equals(…). Some even argue you should use it the other way around (i.e. "ZA".equals(something)) to avoid a NullPointerException…
Another possibility would be to first build a Map from county to the corresponding string ID for all the EULAs you have and then asking the Map to return the correct one.
But probably the cleanest solution would be to use Androids built in mechanism, as hkN suggests.

Related

How to find specific substrings (that can be very similar) and do different things with them in java

I am writing a program that takes in a file and extracts data from a single string within the file. I run into a problem when I try to separate the substrings in the way that I want. The goal is to separate the larger chunks of the line from other large chunks without separating the smaller chunks within the larger chunk (separated by commas).
An example of the file contents would be this: (Although it is slightly long, the files I have may vary from short lists like this to 50 or even to 100 blocks of item sets)
{"timeStamp":1477474644345,"itemSets":[{"mode":"any","sortrank":4999,"type":"custom","priority":false,"isGlobalForMaps":true,"uid":"LOL_D957E9EC-39E4-943E-C55E-52B63E05D99C","isGlobalForChampions":false,"associatedMaps":[],"associatedChampions":[40],"blocks":[{"type":"starting","items":[{"id":"3303","count":1},{"id":"2031","count":1},{"id":"1082","count":1},{"id":"3340","count":1},{"id":"3363","count":1},{"id":"2043","count":1},{"id":"3364","count":1}]},{"type":"Support Build Items","items":[{"id":"2049","count":1},{"id":"1001","count":1},{"id":"3165","count":1},{"id":"3117","count":1},{"id":"2301","count":1},{"id":"3089","count":1},{"id":"3135","count":1},{"id":"3504","count":1}]},{"type":"AP Build Items","items":[{"id":"3165","count":1},{"id":"3020","count":1},{"id":"3089","count":1},{"id":"3135","count":1},{"id":"3285","count":1},{"id":"3116","count":1}]},{"type":"Other Items (Situational Items)","items":[{"id":"3026","count":1},{"id":"3285","count":1},{"id":"3174","count":1},{"id":"3001","count":1},{"id":"3504","count":1}]}],"title":"Janna Items","map":"any"},{"mode":"any","sortrank":0,"type":"custom","priority":false,"isGlobalForMaps":false,"uid":"LOL_F265D25A-EA44-5B86-E37A-C91BD73ACB4F","isGlobalForChampions":true,"associatedMaps":[10],"associatedChampions":[],"blocks":[{"type":"Searching","items":[{"id":"3508","count":1},{"id":"3031","count":1},{"id":"3124","count":1},{"id":"3072","count":1},{"id":"3078","count":1},{"id":"3089","count":1}]}],"title":"TEST","map":"any"}]}
The code I have attempted to write tries to separate this into meaningful chunks, here is what I have written so far:
cutString = dataFromFile.substring(dataFromFile.indexOf("itemSets\":") + 11, dataFromFile.indexOf("},{"));
stringContinue = dataFromFile.substring(cutString.length());
while(stringContinue.contains("},{"))
{
//Do string manipulation to cut every part and re-attach it, then re-check to find if this ("},{\"id") is not there
if(stringContinue.contains("},{\"id"))
{
//if(stringContinue.equals(anObject))
cutString = cutString + stringContinue.substring(0, stringContinue.indexOf("},{\"id"));
}
else if(stringContinue.contains("},{\"count"))
{
cutString = cutString + stringContinue.substring(0, stringContinue.indexOf("},{\"count"));
}
else if(stringContinue.contains("},{"))
{
cutString = cutString + stringContinue.substring(0, stringContinue.indexOf("},{"));
}
stringContinue = stringContinue.substring(cutString.length());
//Check if we see a string pattern that is the cut off point
//if()
//System.out.println(stringContinue);
System.out.println(cutString);
}
But when I run it, I get an output like this:
{"mode":"any","sortrank":4999,"type":"custom","priority":false,"isGlobalForMaps":true,"uid":"LOL_D957E9EC-39E4-943E-C55E-52B63E05D99C","isGlobalForChampions":false,"associatedMaps":[],"associatedChampions":[40],"blocks":[{"type":"starting","items":[{"id":"3303","count":1arting","items":[{"id":"3303","count":1
The output I want to achieve is this:
{"mode":"any","sortrank":4999,"type":"custom","priority":false,"isGlobalForMaps":true,"uid":"LOL_D957E9EC-39E4-943E-C55E-52B63E05D99C","isGlobalForChampions":false,"associatedMaps":[],"associatedChampions":[40],"blocks":[{"type":"starting","items":[{"id":"3303","count":1},{"id":"2031","count":1},{"id":"1082","count":1},{"id":"3340","count":1},{"id":"3363","count":1},{"id":"2043","count":1},{"id":"3364","count":1}]},{"type":"Support Build Items","items":[{"id":"2049","count":1},{"id":"1001","count":1},{"id":"3165","count":1},{"id":"3117","count":1},{"id":"2301","count":1},{"id":"3089","count":1},{"id":"3135","count":1},{"id":"3504","count":1}]},{"type":"AP Build Items","items":[{"id":"3165","count":1},{"id":"3020","count":1},{"id":"3089","count":1},{"id":"3135","count":1},{"id":"3285","count":1},{"id":"3116","count":1}]},{"type":"Other Items (Situational Items)","items":[{"id":"3026","count":1},{"id":"3285","count":1},{"id":"3174","count":1},{"id":"3001","count":1},{"id":"3504","count":1}]}],"title":"Janna Items","map":"any"}
{"mode":"any","sortrank":0,"type":"custom","priority":false,"isGlobalForMaps":false,"uid":"LOL_F265D25A-EA44-5B86-E37A-C91BD73ACB4F","isGlobalForChampions":true,"associatedMaps":[10],"associatedChampions":[],"blocks":[{"type":"Searching","items":[{"id":"3508","count":1},{"id":"3031","count":1},{"id":"3124","count":1},{"id":"3072","count":1},{"id":"3078","count":1},{"id":"3089","count":1}]}],"title":"TEST","map":"any"}
So then my question is how do I check for the point where I can separate the blocks without getting java to detect the same pattern that it uses to separate the smaller chunks? Basically I am looking for a pattern like this ("},{"), but not this ("},{\"id:") or this ("},{\count:"). Is there any other things that the String Class can offer for functionality that is similar that i am not aware of?
Edit: Although using a json parser would make things easier and convenient for this type of problem, another one rises because it would make the program only take in json files. This question is more for string manipulation and trying to find a part of the string that can separate the large blocks of information without touching or changing (very minimally as possible) the smaller blocks that have the same way of separation. So far regex and splitting strings to be re-attached later seems to be the way to go unless there is a more clear-cut answer.
You could split the string into an array based on regex like this:
//fileString is the String you get from your file
String[] chunksIWant = fileString.split("\\},\\{");
This will return the String array chunksIWant split in the chunks you want. It does get rid of the regex itself, in this case "},{", so if you would need the symbols for some reason you will have to add them back afterwards.
You are getting this data from file in Json format.
So when you get that data on java side use JsonParser to convert data in JsonArray format.
Then you can iterate that JsonArray to get as JsonObject by using String name.
You can use value of JsonObject as required.

Format specific section of String

I have a String: a%sb%sc%s. I need to format b before I format a or c, but I'm not sure how or even if I can specify only to format b while keeping the rest of the String unformatted.
In other words, I'm trying to do this:
String.format(foo, "test");
With the outcome:
a%sbtestc%s
Is it possible to manipulate a String like this or should I just use String.replace instead?
A little more detail. The ultimate String will look something like: aA-PARMbB-PARMcC-PARM and then used to fetch some data. a and c are much more dynamic than b, so I'm trying to format b before hand.
So, again. I'm trying to achieve the following:
String.format(foo, "B-PARM");
With the results:
a%sbB-PARMc%s
Then format the rest:
String.format(formattedFoo, "A-PARM", "C-PARM");
You could do your formatting in steps,
String aString = String.format("something %s something else", "a string");
String bString = String.format("...%s...", "test");
String cString = // ....
String completeString = String.format("a%sb%sc%s", aString, bString, cString);
but again, I have to wonder what is going on, and whether this represents an XY Problem, one that is best solved by a completely different approach. Consider giving us the details of the overall problem that you're trying to solve and perhaps not the code tactics that you're using to try to solve it.

Is there an equivalent to Java's String intern function in Go?

Is there an equivalent to Java's String intern function in Go?
I am parsing a lot of text input that has repeating patterns (tags). I would like to be memory efficient about it and store pointers to a single string for each tag, instead of multiple strings for each occurrence of a tag.
No such function exists that I know of. However, you can make your own very easily using maps. The string type itself is a uintptr and a length. So, a string assigned from another string takes up only two words. Therefore, all you need to do is ensure that there are no two strings with redundant content.
Here is an example of what I mean.
type Interner map[string]string
func NewInterner() Interner {
return Interner(make(map[string]string))
}
func (m Interner) Intern(s string) string {
if ret, ok := m[s]; ok {
return ret
}
m[s] = s
return s
}
This code will deduplicate redundant strings whenever you do the following:
str = interner.Intern(str)
EDIT: As jnml mentioned, my answer could pin memory depending on the string it is given. There are two ways to solve this problem. Both of these should be inserted before m[s] = s in my previous example. The first copies the string twice, the second uses unsafe. Neither are ideal.
Double copy:
b := []byte(s)
s = string(b)
Unsafe (use at your own risk. Works with current version of gc compiler):
b := []byte(s)
s = *(*string)(unsafe.Pointer(&b))
I think that for example Pool and GoPool may fulfill your needs. That code solves one thing which Stephen's solution ignores. In Go, a string value may be a slice of a bigger string. Scenarios are where it doesn't matter and scenarios are where that is a show stopper. The linked functions attempt to be on the safe side.

Coverting string to java code

I have a string constructed at run time like
str = "a+dataValue(i)";
where 'a' is a variable, 'dataValue(i)' is a function with argument i
Now I have a function where I want to use string str as part of code. For example
public void func()
{
for(int i=0;i<n;i++)
Sytem.out.println(converted_to_java_source(str)); //(i.e.) a+dataValue(i); it should be converted at runtime not compile time
}
I need output like as follows:
when a = 2; dataValue(i) returns i; n = 5
On call to func it should print
2 3 4 5 6 7
Thank you.
You are looking for the Java equivalent of the eval function / method in dynamically typed languages like JavaScript, Perl, Python and so on. Unfortunately there isn't one.
There are various ways to do this kind of thing in Java, but they are all expensive, and come with a variety of other down-sides.
My advice is to look for another (easier / cheaper) way to meet your requirement.
If you really need to go down the eval route, then here are some related Q/A's which give a reasonable coverage of the options.:
Is there an eval() function in Java?
Is there a java equivalent of the python eval function?
You could take a look at the Byte Code Engineering Libraray (BCEL) or ASM. In either case, things can get messy and overcomplicated so I would recommend what Stephen suggested and try to look for another way.
You could, for instance, use som if else statements to call your function in the usual manner, maybe something like:
String functionName = "...";
if (functionName.toLowerCase().equals("someMethodName")
{
someMethodName(someParams);
}

What ways can you create a string with 2000 "spaces"

For various reasons I am trying to set a string to 2000 spaces. Currently I am using:
String s = String.format("%1$-2000s"," ");
This is great for Java 5, however, some of the developers in our department are using 1.4 and this does not work.
I was wondering, are any other ways of achieving the same result? I know I can do things like a for loop adding a space at a time, but I am looking for something simple like the format option.
For those that may be interested in why I need this, it is because we have an XML type on a dataobject that on insert into the DB is null. It then gets updated with the XML string, usually around 2000 characters in size. In Oracle pre-reserving this space can prevent row migration, therefore, increasing performance.
Thanks!
char[] spacesArray = new char[2000];
Arrays.fill(spacesArray, ' ');
String spaces = new String(spacesArray);
the simplest answer: (scroll to see all the codes)
String s = " "; // 2000 spaces
You can use lpad(' ',2000,' ') in the insert statement directly to tell Oracle to create the value you want.
In fact, you can set the field in question to have this as the default, which could prevent you from needing to change it in multiple places (if your code is explicitly sending null as the value for the field, that will override the default).
A StringBuffer and then add a space 2000 times in a loop, and toString() afterwards. I don't think there are any "simpler" ways to do it which doesn't end up doing this anyway under the covers.
If you do this a lot, it would make a good library function.
A random function I found in my personal library:
public static String whiteSpace2(int l) {
if (l==0) return "";
String half=whiteSpace2(l/2);
if ((l&1)!=0) {
return half+" "+half;
} else {
return half+half;
}
}
Not claiming it is the fastest possible way to generate whitespace, but it works :-)
StringUtils.repeat(" ", 2000) (from commons-lang)
However, I'm not sure whether such micro-optimizations should be made with the cost of code that would require a 5 line comment to explain why is this needed. If you do it - be sure to add an extensive comment, otherwise imagine the reaction of those reading your code.
If nothing else works:
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 2000; ++i)
sb.append(" ");
String str = new String(sb);
See this other question.
Can I multiply strings in Java to repeat sequences?
Both Apache Commons StringUtils and Google Guava libraries have commands to multiply (repeat) strings.

Categories

Resources