i've a List<Polygon> polygons, where Polygon represents the geojson concept of polygon. In the class Polygon i defined a method toGeojson() that returns a string containing the geojson representation. I'd like to print all the list in a compact way instead of doing this:
String result = '';
for(Polygon p: polygons)
result += p.toGeojson();
I could do result = p.toString() but i cannot use toString() method because i use it for an other thing. Is there a way to call toGeojson() on a List just as you'd do with toString()?
Not sure if that answers your question, but you can use Stream api for that thing.
String result = polygons.stream()
.map(Polygon::toGeojson)
.collect(Collectors.joining(","));
There is no direct way to override behaviour of List.toString().
updated
There is Collectors#joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) method which accepts suffix and prefix. Using this method we can make our output look exactly like List.toSting with square brackets.
String result = polygons.stream()
.map(Polygon::toGeojson)
.collect(Collectors.joining(",", "[", "]")); // ["x","y"]
I am not sure I understand what you want, but I guess you are looking for a way to print the geoJson representation of each Polygon contained in your List. In that case I don't see a better way than a loop, but avoid String concatenation inside loops. Use StringBuilder instead which has much better performance.
StringBuilder result = new StringBuilder();
for (Polygon p: polygons) {
result.append(p.toGeojson());
}
Your solution is the best, i think... In Java there is no faster solution and the Array.toString method works the same way.
Related
Reversing a string can be done by concatenating the Original String through a reverse loop (from str.length-1->0)
but why is this not Working Correctly :
by adding the character by character from last positon to the 0th position:
int i = 0;
while(i<originalStr.length())
{
strRev.charAt(i)=originalStr.charAt(str.length()-1-i);
i++;
}
Strings are immutable in Java. You cannot edit them.
If you want to reverse a String for training purpose, you can create a char[], manipulate it then instantiate a String from the char[].
If you want to reverse a String for professional purpose, you can do it like this :
String reverse = new StringBuilder(originalStr).reverse().toString();
strRev.charAt(i) // use to Retrieve what value at Index. Not to Set the Character to the Index.
All we know that String is a immutable class in Java. Each time if you try to modify any String Object it will Create a new one.
eg :- String abc = "Vikrant"; //Create a String Object with "Vikrant"
abc += "Kashyap"; //Create again a new String Object with "VikrantKashyap"
// and refer to abc again to the new Object.
//"Vikrant" Will Removed by gc after executing this statement.
Better to Use StringBuffer or StringBuilder to perform reverse Operation. The only Difference between these two class is
A) StringBuffer is a Thread Safe (Synchronized). A little slow because each time need to check Thread Lock.
B) StringBuider is not Thread Safe. So, It gives you much faster Result Because it is Not Synchronized.
There are Several Third Party Jars which provides you a Features like Reverse and Many more String base Manipulation Methods
import org.apache.commons.lang.StringUtils; //Import Statement
String reversed = StringUtils.reverse(words);
In your test method, best practice is to use triple A pattern:
Arrange all necessary preconditions and inputs.
Act on the object or method under test.
Assert that the expected results have occurred.
#Test
public void test() {
String input = "abc";
String result = Util.reverse(input);
assertEquals("cba", result);
}
I do not know why I am getting an error at the yy.charAt(i) assignments. It says... Variable Expected... Not value.
static int subtract(int x,int y)
{
String yy=Integer.toBinaryString(y);
System.out.println(yy);
for(int i=0;i<yy.length();i++)
{
if(yy.charAt(i)==1)
{
yy.charAt(i)=0;
}
else
{
yy.charAt(i)
}
}
int t=Integer.parseInt(yy);
return(t);
}
You can't assign values to a string's index position, strings are immutable in Java. This will never work:
yy.charAt(i)=0;
If you need to modify a string, transform it to a char[] (using the toCharArray() method), modify the array and then build a new string from that array, using the String(char[]) constructor.
Alternatively, you could use a StringBuilder to modify the characters before returning a new string.
Use a StringBuilder instead.
The code would be almost identical to what you have now, except for these changes:
StringBuilder yy = new StringBuilder(Integer.toBinaryString(y));
...
yy.setChatAt(i, '0');
I think there are a few things that are not clear to you.
I think you mean the character '0' not the value 0.
The lines else { yy.charAt(i); } have absolutely no effect. You can simply omit them.
Strings are immutable in Java (i.e. they cannot be modified in place).
Even if they were, you're syntax is wrong. Something of the form class_name.method_name() is a call to a method of a class. It returns a value that you can store, it is not the same as a variable and trying to assign to a method call makes no sense at all.
To modify Strings in Java, the best way is probably to use a StringBuilder. You create a new StringBuilder using your String, make the necessary changes on that and then convert it back into a String.
So this would look something like this:
StringBuilder builder = new StringBuilder(yy); // StringBuilder from yy.
// rest of your code here
builder.setCharAt(i, '0');
// more code
yy = StringBuilder.toString(); // convert it back to a String.
Notice that even in a StringBuilder you have to call the appropriate method and pass in the value that you want to assign to it.
I am working on a section of code for an assignment I am doing atm, and I am completely stuck with 1 little bit.
I need to convert the contents of an array list into a string, or the form of a string, which will be able to be imput into toString() in order for it to be printed to the screen.
public String toString(){
String full;
full = (this.name + this.address + "\n" + "Student Number = " + this.studentId);
for (int i = 0; i < cs.size(); i++) {
full.append(cs[i]);
return full;
The piece of above code is where i attempt to combine 3 varaibles and the contents of an array list into a single string with formatting.
Unfortunatly it creates an error "The type of the expression must be an array type but it resolved to ArrayList"
Thanks for any help.
Jake
cs is array list, so you have to do get operation, not [] (which is for array access)
It should be like:
full.append(cs.get(i));
Not
full.append(cs[i]);
EDIT: As assylis said, full should be StringBuilder not just String, because String doesn't support append() method.
StringBuilder full = new StringBuilder();
Apache Commons StringUtils has different varieties of join() methods that mean you don't have to write this yourself. You can specify the separator and even the prefix/suffix.
I would recommend you look at Apache Commons, not just for this but for lots of other useful stuff.
You are attempting to access an ArrayList as though it is a primitive array (using the square brackets around the index). Try using the get(int index) method instead.
i.e.,
cs.get(i);
You cannot index an ArrayList like an array, you need the get(index) method. Even better, use the enhanced for loop, since it's not recommended to index over a list, as the implementation may change to LinkedList.
I also suggest using a StringBuilder for efficiency:
public String toString() {
StringBuilder full = new StringBuilder();
full.append(this.name);
full.append(this.address);
full.append("\n");
full.append("Student Number = ");
full.append(this.studentId);
for (String s: cs)
full.append(s);
return full.toString();
}
Just use
"cs.get(i)" in place of "cs[i]".
as cs is an ArrayList not an Array.
and also use
full = full + cs.get(i); and not full.append(cs.get(i));
as String type dont have a append method.
Just a note, since you don't put any spacers between each element of the ArrayList it might be unreadable. Consider using Guava's Joiner class.
So instead of
for (...)
s.append(y);
if would be
a.append(Joiner.on(" ").join(yourList));
The Joiner is also more efficient than the for loop since it uses a StringBuilder internally.
I'd like to ask that, how can i use ArrayList to store a toString(). I've got a class, with a toString at the end, and i have to store the toString from the class into the ArrayList.
Like this : Music name , author , release year , currently playing
String , String , int , boolean
hoping you have properly formatted text in your specific class's toString() method,
use
List<String> listDesired = new ArrayList<String>( 10 );
listDesired.add( myMusicDataClassInstance.toString() );
Question is unclear, but if your objects already have toString() method defined you don't need to store them separately in array list. Just add the objects to arrayList and do Collections.toString(yourList);
You can use the "" + x trick so as to avoid NullPointerException in case an x is null:
public List<String> musicToString(List<Music> musicList) {
final List<String> strings = new ArrayList<String>();
for (Music m : musicList) strings.add("" + m);
return strings;
}
This works because the concatenation operator + implicitly calls String.valueOf on all reference-typed operands.
You can also write String.valueOf explicitly, if that is your aesthetic preference. It also has the marginal benefit of definitely not instantiating a StringBuilder (although there's a good chance the compiler will avoid that anyway since it can see the empty string literal).
You should override the toString() for that class and in toString() method define the business logic that will convert that string into ArrayList object.
List<String> listDesired = new ArrayList<String>( 10 );
I want to ask you about the print vector array , the following one:
Vector[] routingTable = new Vector[connectivity.length];
I tried this method , but it doesn't work with me and it gives me protocol.Route#c17164
when I printed in the main, here is the code, so can you tell me why it doesn't print the correct value ?
public String printRT(int hop)
{
String s = "";
for (int i = 0; i < conf.routingTable[hop].size(); i++)
{
s= " ROUTING TABLE " + conf.routingTable[hop].get(i);
}
return s;
}
it looks like you need to implement the toString() method in protocol.Route.
class Route {
public String toString() {
return "some string that makes sense";
}
}
Either override the toString() method on the protocol.Route class, or get the desired properties from the Route object and append them to the String s inside your printRT method.
Many helpful suggestions, but I think everyone is overlooking something very simple- in each loop iteration you are overwriting the value of s. I think you mean to say something like the following instead:
s += " ROUTING TABLE " + conf.routingTable[hop].get(i);
Note the "+=" rather than simple assignment. Or use a StringBuilder, or whatever.
When you ask java to print an object for which no toString method is defined, then it will fall back on the default toString implementation in the Object class. From the javadocs:
The toString method for class Object
returns a string consisting of the
name of the class of which the object
is an instance, the at-sign character
`#', and the unsigned hexadecimal
representation of the hash code of the
object. In other words, this method
returns a string equal to the value
of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
In your example 'protocol.Route' would be the class name and 'c17164' is whatever the hashcode method returns as a hexString, which, unless hashCode has been overwritten, is probably the address of the object, although this is implementation dependent.
So, there are a few ways to fix your problem.
Write your own implementation of the toString method for the Route class that prints out the data you want. This is probably the most "correct" way to fix your problem. It keeps things nicely encapsulated within the class, meaning only the toString method inside of the class needs to know about the exact member variables that are to be printed.
If the situation is such that you cannot change the Route class, you could subclass your own version of the Route class that you could add a toString method to. However, depending on the design of the class, this may be difficult.
Have the current printRT method look inside each Route object and get the specific information that you want to append to the current string.
Also, note that with the current code, you have written the following in the inner loop:
s= " ROUTING TABLE " + conf.routingTable[hop].get(i);
This means that printRT will only return a string for the very last iteration of the loop. So most of the time in the for loop is spent creating strings, assigning them to a variable and then overwriting them the next time through the loop.
If you want to return a string representation for every iteration, you will need to change the above to something like the following:
s += " ROUTING TABLE " + conf.routingTable[hop].get(i);
Now the new information is being appended to s every time through the loop. However, depending on the number of string concatenations being performed, the StringBuilder class may be a better alternative (see a short summary and tutorial on it here).
Two options.
Either override the toString() method on the protocol.Route class.
public String toString() {
return someMethodorPropertyThatreturnsString;
}
or get the desired properties/methods from the Route object and append them to the String s inside your printRT method.
public String printRT(int hop)
{
String s = "";
for (int i = 0; i < conf.routingTable[hop].size(); i++)
{
s= " ROUTING TABLE " + conf.routingTable[hop].get(i).someMethodorPropertyThatreturnsString;
}
return s;
}
There are a number of issues here.
You should be specifying a type to put in your List with Generics. That way, you will make it more obvious to yourself and others what you are putting into and taking out of your List.
As mentioned by others, your List is a list of protocol.Route objects, not Strings. When you try to add a Route to s, Java doesn't know how to convert it into a String, so it uses the default Object#toString(). Override it in Route to do what you want.
It looks like you'll potentially be doing a lot of appending here. Use a StringBuilder.
It looks to me like printRT(int) should be a method inside of whatever conf is.
You should probably be using a different implementation of List; Vector is not really recommended to use anymore, so take a look at other options like ArrayList.