I have a code like this:
private static final String BR_TAG = "<br/>";
private ResourceBundle rb;
public String create(){
String result = addLine("some text");
result = addLine("some text");
result = addLine("some text");
....
}
public String addLine(String text){
return rb.getString(text) + BR_TAG;
}
This is my current code, but is it optimal? Maybe I shouldn't use separate method to add line to my result? I could to this like this without method addLine:
public String create(){
String result = rb.getString("some text") + BR_TAG;
result = rb.getString("some text") + BR_TAG;
result = rb.getString("some text") + BR_TAG;
....
}
Or I can think about third option with passing StringBuilder to my method:
public String create(){
StringBuilder sb = new StringBuilder();
addLine("some text", sb);
addLine("some text", sb);
....
}
public void addLine(String text, StringBuilder sb){
sb.append(rb.getString(text)).append(BR_TAG);
}
What do you think which option is the best?
Why not use another method?
IMO, neither is the best, in terms of the beauty of the code. But in terms of performance, the third is better because a StringBuilder takes less time than the + when used a lot of times.
To make your code look prettier, Maybe make use of the Builder Pattern?
public class LineBuilder {
private StringBuilder builder;
private static final String BR_TAG = "<br/>";
public LineBuilder() {
builder = new StringBuilder();
}
public LineBuilder addLine(String text) {
builder.append(text).append(BR_TAG);
return this;
}
public String build() {
return builder.toString();
}
}
You can also add other methods like addHeader or addStrong that adds in <h1> and <strong> tags.
And you can use it like this:
String result = new LineBuilder()
.addLine("Hello")
.addLine("World")
.addLine("Bye!")
.build();
That just looks better!
Related
Right, I understand that this question has more than likely been answered before however it won't work in my circumstance.
So I have a string that I need to get into another method, here's the code...
public String createColoredMinuses(int amount, ChatColor colorOne, ChatColor colorTwo)
{
StringBuilder builder = new StringBuilder();
builder.append(amount < 13);
if (amount % 2 == 0) {}
builder.append(ChatColor.BLUE + "-");
builder.append(ChatColor.DARK_BLUE + "-");
String string = builder.toString();
return string;
}
public boolean onCommand(CommandSender sender, Command cmd, String command, String[] args)
{
public static void createColoredMinuses()
{
Method1();
}
String b = builder.toString();
So what I want to happen is I want to be able to get the 'return string;' into the main part where all the commands go but into the 'String b=' part however I can't work out how to do it.
I hope this made sense to you! :P
Would it not be enough to have the builder as a private variable? I mean you literally want to use it privately in another method that you call later:
private StringBuilder builder = new StringBuilder();
public String createColoredMinuses(int amount, ChatColor colorOne, ChatColor colorTwo)
{
builder.append(amount < 13);
if (amount % 2 == 0) {}
builder.append(ChatColor.BLUE + "-");
builder.append(ChatColor.DARK_BLUE + "-");
String string = builder.toString();
return string;
}
public boolean onCommand(CommandSender sender, Command cmd, String command, String[] args) {
public static void createColoredMinuses ()
{
Method1();
}
String b = builder.toString();
}
Another noticeable thing is that you have this method:
public static void createColoredMinuses ()
{
Method1();
}
And it's inside the onCommand... this doesn't look right. You need to move this to somewhere else.
In the end, I just moved the StringBuilder as I couldn't work out how to call the method.
So that it was in the class with everything else.
I created a class of DocumentFilter type as follows:
public class CustomDocumentFilter extends DocumentFilter
{
private StyledDocument styledDocument;
private JTextPane panetxt;
public CustomDocumentFilter(JTextPane panetxt) {
this.panetxt = panetxt; // Not really necessary
this.styledDocument = panetxt.getStyledDocument();
}
private final StyleContext styleContext = StyleContext.getDefaultStyleContext();
Pattern pattern = buildPattern(mystring);
private Pattern buildPattern(String mystring)
{
StringBuilder sb = new StringBuilder();
String[] toke = StringUtils.split(mystring,",");
for (String token : toke) {
sb.append("\\b");
sb.append(token);
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
Pattern p = Pattern.compile(sb.toString());
return p;
}
My question is: how to include mystring within the call of CustomDocumentFilter?:
//String mystring="lalala";
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur));
EDIT:
Regarding the first way Jonathan suggests, I get this:
error: cannot find symbol Pattern pattern = buildPattern(mystring); ^ symbol: variable mystring location: class TextEditor.CustomDocumentFilter
I don't know if it has to do with the Pattern clause
Not 100% sure what is desired from the description. But I think your simply trying to ask how to get your local string value into your new CustomDocumentFilter object.
Well that is simple and you have choices! More than the two I show here.
first easy way is to add it to the constructor
public CustomDocumentFilter(JTextPane panetxt, String myString) {
...
pattern = buildPattern(mystring);
}
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur, myString));
another way is to use a method that returns the object
public CustomDocumentFilter myFunction(String myString) {
pattern = buildPattern(mystring);
return this;
}
((AbstractDocument) editeur.getDocument()).setDocumentFilter(new CustomDocumentFilter(editeur).myFunction(myString));
I want to generate custom getters and setter, so I can handle variables better when I will be saving these instances into SQL database. I want to generate something like:
public class Test extends SQLEntry {
private static final String NAME = "Name";
public String getName() {
return get(NAME);
}
public void setName(String name) {
set(NAME, name);
}
}
But as I can see in Eclipse it generates only the following code:
public class Test {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Is there some plugin, that can do it? Or am I missing something?
I have like 20 classes and I will not write this manually.
I dont know why you need this, but here is the approach to custom Getters and Setters.
You can update all generated setters and getters by going to preferences > java > Code Style > code Templates and selecting code then edit Getter body and Setter body and put this:
Getter body: return get(${field});
Setter body: set(${field}, ${param});
Let me know if that works
I recommend that instead of doing what you describe, you should use Spring Data. Specifically the BeanPropertyRowMapper class in the org.springframework.jdbc.core package will do what you want.
Read more in the Spring API documentation.
there is no other plugin available!
how can some plugin write code that is specific to your business logic!
you have to write the code manually for setters and getters in all the classes!
Try write-it-once. Template based code generator. You write custom template using Groovy, and generate file depending on java reflections. It's the simplest way to generate any file. You can make getters/settest/toString by generating AspectJ or java files, SQL based on JPA annotations, inserts / updates based on enums and so on.
On the end I found it that it is the best to do it your self...
If you like writing a code than you will enjoy this solution the most.
public class CodeGenerator {
private final static String ENCODING = "UTF-8";
private final static String FILE_NAME = "File.txt";
public static void main(String[] args) {
try {
ArrayList<Carriage> names = getNames();
for (Carriage c : names) {
createSetter(c.name, c.capitalName);
createGetter(c.name, c.capitalName);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
private static ArrayList<Carriage> getNames() throws FileNotFoundException {
File file = new File("/");
InputStream is = CodeGenerator.class.getResourceAsStream(FILE_NAME);
Scanner s = new java.util.Scanner(is, ENCODING).useDelimiter("\\A");
String content = s.next();
String[] lines = content.split(System.getProperty("line.separator"));
ArrayList<Carriage> ret = new ArrayList<Carriage>();
for (String line : lines) {
line = line.replaceAll("\\r", "");
int firstCapitalIndex = line.indexOf("String") + 7;
int secondCapitalIndex = line.indexOf(" ", firstCapitalIndex);
int firstIndex = line.indexOf("\"") + 1;
int secondIndex = line.indexOf("\"", firstIndex + 1);
Carriage c = new Carriage();
c.name = line.substring(firstIndex, secondIndex);
c.capitalName = line.substring(firstCapitalIndex, secondCapitalIndex);
ret.add(c);
}
return ret;
}
public static void createSetter(String name, String capitalName) {
String str = "public void set" + name + "(String val) {\n"
+ "\tset(" + capitalName + ", val);\n"
+ "}\n";
System.out.println(str);
}
public static void createGetter(String name, String capitalName) {
String str = "public String get" + name + "() {\n"
+ "\treturn (String) get(" + capitalName + ");\n"
+ "}\n";
System.out.println(str);
}
carriage:
package codegenerator;
public class Carriage {
public String name;
public String capitalName;
}
And to File.txt I just coppy all defined constants and run the generator...
public static final String NAME = "Name";
public static final String PHONE = "Phone";
public static final String EMAIL = "Email";
public static final String ADDRESS_1 = "Address1";
public static final String ADDRESS_2 = "Address2";
public static final String ADDRESS_3 = "Address3";
public static final String ICO = "Ico";
public static final String DIC = "Dic";
public static final String ADMIN_LOGIN = "AdminLogin";
public static final String ADMIN_PASSWORD = "AdminPassword";
public static final String LANGUAGE = "Language";
public static final String CODE = "CODE";
public static final String MONTHLY_PAYMENT = "MonthlyPayment";
This is a much simplified version of a class file I'm working on, I've just used these classes to show my problem.
public class Test {
private String string1 = null;
private String string2 = null;
private void setString(String s) {
s = "hello";
}
private void set() {
setString(string1);
setString(string2);
}
public void print() {
System.out.println(string1);
System.out.println(string2);
}
public void initialise() {
set();
print();
}
}
public class StringTest {
public static void main(String[] args) {
Test test = new Test();
test.initialise();
}
}
Anyway, basically, after this the two string variables are still null. What causes this problem? and how can I get around it? (Still learning the fundamentals of java - if that's relevant).
Any help/guidance is greatly appreciated.
Because a String is immutable, any change you make inside the method will be local to that method.
private void setString(String s) {
s = "hello";
}
s can't be changed.
I can think of two options.
Option 1
Make s an instance variable (field) and change your method.
public class Test {
private String string1 = null;
private String string2 = null;
private String s;
private void setString(String s) {
this.s = "hello";
}
Option 2
Pass in a StringBuilder/StringBuffer instead of String.
Your problem is that Java is pass by value, so your setString method does not do anything. To change the value of string1, you need to have string1 = xxxx; somewhere in your code. For example:
private void set() {
string1 = getDefaultString();
string2 = getDefaultString();
}
private String getDefaultString() {
return "hello";
}
You are setting the value of "s" not string1 or string2
try something like.
private void setString(String s) {
string1 = "hello";
string2 = "world";
}
By making this assignation
s = "hello";
weare creating a new object. It will have a different memory address than the one passed with setString(string1);
We would need to change the object received at
private void setString(StringBuilder s) { ... }
instead of creating a new one. We need to use exactly the same object we were passed in this method. Can't create a new one, as the caller method wouldn't notice (parameters in Java are never output parameters).
As Java's String is inmutable, we can't change its content: just create a new String object.
As #adarshr pointed out, we can use StringBuilder or StringBuffer, which are mutable, and change their content. But we can't just replace String with StringBuilderin you code. We have to make sure that:
The StringBuilder is initialized before being passed to setString().
The StringBuilder is not created again inside setString() (we are using the same one we were passed).
So, replacing this in your code should work:
private StringBuilder string1 = new StringBuilder();
private StringBuilder string2 = new StringBuilder();
private void setString(StringBuilder s) {
s.append("hello");
}
you misunderstand of java parameter passing, try public void setString1(String s) { string1 = s; }
What are you trying to initialize the values of string1 and string2 to? The two member variables start out being null.
If I were to treat Test class as a POJO (plain old Java object), I would add getter/setter methods as follows:
public class Test {
private String string1;
private String string2;
public String getString1() {
return this.string1;
}
public String getString2() {
return this.string2;
}
public void setString1(String s) {
this.string1 = s;
}
public void setString2(String s) {
this.string2 = s;
}
/*
* Additional methods
*/
public void set() {
setString1("hello");
setString2("world");
}
public void print() {
System.out.println(this.string1);
System.out.println(this.string2);
}
public void initialize() {
set();
print();
}
}
ur application is assigning the hello word in parameter s..but the variable s is a parameter type thats y the reflection of s will be in setString() method block...not anywhere else...use instance variable or static variable to see the reflection of ur assignment.
I have this very awkward question...
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
When main returns, the value is still "" and not "Hello world". Why is that?
Also, how do I make it work? Let's say I want my function changeString to change the string it got to "Hello world".
Everyone explained why it doesn't work, but nobody explained how to make it work. Your easiest option is to use:
String changeString() {
return "Hello world";
}
main() {
String myStr = new String("");
myStr = changeString();
}
Although the method name is a misnomer here. If you were to use your original idea, you'd need something like:
void changeString(ChangeableString str) {
str.changeTo("Hello world");
}
main() {
ChangeableString myStr = new ChangeableString("");
changeString(myStr);
}
Your ChangeableString class could be something like this:
class ChangeableString {
String str;
public ChangeableString(String str) {
this.str = str;
}
public void changeTo(String newStr) {
str = newStr;
}
public String toString() {
return str;
}
}
A quick lesson on references:
In Java method everything is passed by value. This includes references. This can be illustrated by these two different methods:
void doNothing(Thing obj) {
obj = new Something();
}
void doSomething(Thing obj) {
obj.changeMe();
}
If you call doNothing(obj) from main() (or anywhere for that matter), obj won't be changed in the callee because doNothing creates a new Thing and assigns that new reference to obj in the scope of the method.
On the other hand, in doSomething you are calling obj.changeMe(), and that dereferences obj - which was passed by value - and changes it.
Java uses a call by value startegy for evaluating calls.
That is, the value is copied to str, so if you assign to str that doesn't change the original value.
If the changing of your String happens very often you could also assign a StringBuffer or StringBuilder to your variable and change its contents and only convert it to a String when this is needed.
Expanding a bit on NullUserException's excellent answer, here's a more general solution:
public class Changeable<T> {
T value;
public Changeable(T value) {
this.value = value;
}
public String toString() {
return value.toString();
}
public boolean equals(Object other) {
if (other instanceof Changeable) {
return value.equals(((Changeable)other).value);
} else {
return value.equals(other);
}
}
public int hashCode() {
return value.hashCode();
}
}
Yura's original code can then be rewritten as:
void changeString(Changeable<String> str){
str.value = "Hello world":
}
void main() {
Changeable<String> myStr = new Changeable<String>("");
changeString(myStr);
}
And, just for fun, here it is in Scala:
class Changeable[T](var self: T) extends Proxy;
object Application {
def changeString(str: Changeable[String]): Unit = {
str.self = "Hello world";
}
def main(): Unit = {
val myStr = new Changeable("");
changeString(myStr);
}
}
Because the reference myStr is passed by value to the function changeString and the change is not reflected back to the calling function.
P.S : I am not a Java guy.
Bill, I have a solution to your problem which uses a List as a pointer in java!
void changeString(List<String> strPointer ){
String str = "Hello world";
strPointer.add(0, str);
}
main(){
LinkedList<String> list = new LinkedList<String>();
String myStr = new String("");
changeString(list);
myStr = list.get(0);
System.out.println( myStr );
}
This answer takes a little extra work to insert and get out the string from the list, however the final line will print "Hello world!"
I hope this can help others as well!
-Port Forward Podcast
Here's the one more solution by StringBuffer/StringBuilder worked for me.
static void changeValue(StringBuilder str){
str.append("newValue");
}
main(){
StringBuilder originalVal= new StringBuilder();
changeValue(originalVal);
System.out.println(originalVal.toString());
}