So I'm supposed to write a method to print the elements of an array. This is how I did it:
public static void join(String phrase[])
{
for (int i = 0; i < phrase.length; i++)
{
System.out.print(phrase[i] + " ");
}
}
This code works, but the prof says we must return a String with this method, and I don't know how to do it this way. I tried:
public static String join(String phrase[])
{
for (int i = 0; i < phrase.length; i++)
{
String sentence = System.out.print(phrase[i] + " ");
return sentence;
}
}
Error: incompatible types: void cannot be converted to java.lang.String
I know I cannot use .print because the method is not void. But then, how do I print?
Any ideas? This is a beginner Java class, so I don't know any other way.
This would also work:
public static String join(String phrase[])
{
String sentence = "";
for (int i = 0; i < phrase.length; i++)
{
sentence += phrase[i] + " ";
}
return sentence;
}
Here is what I'm doing:
1) Creating an empty string outside the for loop that will be used to hold all the values of the array
2) Adding each element of array (with a space after) to the string with sentence += phrase[i] + " ";
3) Once the for loop adds all the elements to the string, return it!
System.out.println return void
You can't assign void to a String variable. You simply want to assign the concatenated value, not print it.
String sentence = phrase[i] + " "
You declare sentence each iteration
You need to concatenate each cells, so declare a variable before the loop and append the String in the loop
String sentence = "";
for (int i = 0; i < phrase.length; i++){
sentence += phrase[i] + " "; //same as sentence = sentence + phrase[i] + " ";
return sentence;
}
You return a value inside the loop...
The loop will end at the return, so only the first value will be present in the String. Only return the value after it is fully done, after the loop.
String sentence = "";
for (int i = 0; i < phrase.length; i++){
sentence += phrase[i] + " ";
}
return sentence;
FYI: In the same issues, if the array is empty, no value are returned, so it will also be a problem since a method should return a String in every cases (or throw an exception`.
Shorter solution :
This loop can be done simply with String.join since Java 8
return String.join(" ", phrase);
Please do the following:
public static String join(String phrase[]){
StringBuilder str = new StringBuilder();
for(String s: phrase){
str.append(s);
}
System.out.println(str);
return str.toString();
}
Dont use += and add the values of the string array to another string as it will create a new object every time you add a new string to the preprocessed string. Instead use StringBuilder which is more memory efficient.
You can also do the following:
public static String join(String phrase[]){
String str = Arrays.toString(phrase);
System.out.println(str);
return str;
}
This will print each elements and return the entire result :
public static String printElements(String phrase[]) {
String result = "";
for (int i = 0; i < phrase.length; i++)
{
System.out.print(phrase[i] + " ");
result += phrase[i];
if( i != phrase.length - 1)
{
result += " ";
}
}
return result;
}
Related
input: "Who lives in a pineapple under the sea?"
expected output: "Who sevil in a elppaenip rednu the sea?" (reverse size 5 and above words)
I think the if statement is the problem but I don't know why it's not working. I tried using the code from the if statement block inside the main method and it works fine.
public class Testing {
public static void main(String[] args) {
String sentence = "Who lives in a pineapple under the sea?";
System.out.println(spinWords(sentence));
}
public static String spinWords(String sentence) {
String[] words = sentence.split(" ");
int length = words.length;
String spinned = "";
for (int i = 0; i < length; i++) {
String word = words[i];
int wlength = word.length();
if (wlength > 4) {
String reversed = "";
for (i = wlength - 1; i >= 0; i--) {
reversed += "" + word.charAt(i);
}
spinned += reversed + " ";
} else {
spinned += word + " ";
}
}
spinned = spinned.trim();
return spinned;
}
}
This is my first stack overflow question btw and I don't really know what I'm doing.
I would also love to see better implementations of this code ( for learning purposes ), thanks.
Replace the "if" block with below code. You were using the variable "i" which is used by the first "for" loop. This caused the infinite loop.
if (wlength > 4) {
String reversed = "";
for(int j = 0; j < wlength; j++) {
reversed = word.charAt(j) + reversed;
}
spinned += reversed + " ";
} else {
spinned += word + " ";
}
The issue in your code is the duplicate use of the local variable i as others have pointed out. Typically you never want a nested loop counter to use the same variable name as the outer loop counter.
There is a reason why for (int i = wlength - 1; i >= 0; i--) is a compilation error (with the int declaration added). Instead simply use another variable name:
for (int j = wlength - 1; j >= 0; j--)
This will fix the error in the code. However, since you asked for other implementations I thought I would show another option using StringBuilder, which I believe is easier to read:
public static void main(String[] args) {
String sentence = "Who lives in a pineapple under the sea?";
System.out.println(spinWords(sentence));
}
public static String spinWords(String sentence) {
String[] words = sentence.split(" ");
StringBuilder sb = new StringBuilder();
for (String str : words) {
if (str.length() >= 5) {
sb.append(new StringBuilder(str).reverse());
} else {
sb.append(str);
}
sb.append(" ");
}
return sb.toString().trim();
}
StringBuilder is often used when concatenating a String inside of a loop, see this answer.
Additionally, StringBuilder has the reverse() method which you can use to reverse individual words instead of using a nested loop. You then just use toString to convert the StringBuilder object into a String.
Lastly, I used an enhanced for loop of for (String str : words) which allows you to loop directly on the String values instead of needing to use a loop counter.
Here's a one-liner:
public static String spinWords(String sentence) {
return Arrays.stream(sentence.split(" "))
.map(word -> word.length() < 5 ? word : new StringBuilder(word).reverse().toString())
.collect(Collectors.joining(" "));
}
See live demo.
can anyone please tell me how to write test case in the below code
public static String reverseWord(String str) {
String a[] = str.split(" ");
try {
for (int i = a.length - 1; i >= 0; i--) {
System.out.print(a[i] + " ");
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
I have written the below test case but it is failed
#Test
public void testReverseWord() {
assertEquals("world hello", Logic.reverseWord("hello world"));
}
You return exactly the same String as you get as argument, changes that you are doing are printed to the console instead of being returned.
Try this code instead. I am creating StringBuilder (you can read more about it here https://docs.oracle.com/javase/tutorial/java/data/buffers.html) which is used for String concatenation. Note that I am adding space only if it is not the last word - so that your returned String doesn't have space at the end. At the end by calling toString() on StringBuilder object I am returning new reversed String, exactly what you wanted.
public static String reverseWord(String str) {
String a[] = str.split(" ");
StringBuilder builder = new StringBuilder();
try {
for (int i = a.length - 1; i >= 0; i--) {
builder.append(a[i]);
if (i != 0) {
builder.append(" ");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
Your test case is correct, but the method itself is wrong, you are splitting the string then just printing out values instead of creating a new string and concatenating those values there, so instead of System.out.print(a[i] + " "); introduce a new String outside the loop String result = "" and concatenate the values:
String a[] = str.split(" ");
String result = "";
for (int i = a.length - 1; i >= 0; i--) {
result += a[i];
if (i != 0)
result += " ";
}
return result;
A more optimized way is using a StringBuilder since a String is immutable every time you append to it, a new instance is created - also no need for a try-catch block
Your function return the same input, so you need to modify it, you can easily use StringBuilder class
public static String reverseWord(String str) {
String[] words = str.split(" ");
StringBuilder builder = new StringBuilder(str.length());
for (int i = words.length - 1; i >= 0; i--) {
builder.append(words[i]).append(" ");
}
return builder.toString().trim();
}
Why does my toString method return 0? I have to concatenate an randomly generated integer onto a String and when I print the result it is always 0. What should I do?
class Cozi:
public String toString(){
String concat="";
Clienti ob = new Clienti();
for(int i=1;i <= Clienti.getNrClienti();i++){
concat = " <" + ob.getRandomInt2() + ">";
System.out.print(concat);
}
return concat;
}
class Clienti:
public int serviceTime(){
System.out.print("\n");
Random randomServ = new Random();
for (int idx = 1; idx <= nrClienti; ++idx){
randomInt2 = randomServ.nextInt(maxServ);
System.out.println("Generated : " + randomInt2);
}
return randomInt2;
}
I have also the methods get and set randomInt2.
I foud out why I was getting only 0. Because randomInt2 was declared int in class Clienti, instead of private static int. Now the problem I got is that my concat object gets only the last value for randomInt2. Any suggestions?
If you have an empty String "" as a return value, then it means you do not enter the for loop. Check if the condition i <= Clienti.getNrClienti() is met for any i.
And there is a bug in the for loop, you have to modify:
concat=" <"+ob.getRandomInt2()+">";
By
concat += " <"+ob.getRandomInt2()+">";
Note: when you want to concatenate Strings you can use StringBuilder which is more performant.
String s = "a";
s = "b";
System.out.println(s); // b
You want to concat if I got that right:
String s = "a";
s = s + "b";
System.out.println(s); // ab
I am trying to get the first letter of every word in a String:
String recInf = recursos.getString(nombre);
char[] tipoAbreviado = recInf.toCharArray();
tipoAbreviado[0] = Character.toUpperCase(tipoAbreviado[0]);
for (int i = 0; i < recInf.length() - 2; i++) {
// Es 'palabra'
if (tipoAbreviado[i] == ' ' || tipoAbreviado[i] == '.' || tipoAbreviado[i] == ',') {
// Reemplazamos
tipoAbreviado[i + 1] = Character.toUpperCase(tipoAbreviado[i + 1]);
}
nombre = tipoAbreviado.toString();
}
Finally the value of nombre is [C#3b1938ea, not the first letter of every word in recInf
You can use Arrays.toSting(your_array) to print your Array.
Take a look what toString() in Arrays do
public static String toString(long[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
But when you use tipoAbreviado.toString(); it will call toString() method in Object class.
What toString() method in Object class do?
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
That's why you are getting your current out put.
Instead of using toString on an Array which prints the memory address representation, you should create a String from char[] using new String(char[])
nombre = new String(tipoAbreviado);
You can use string's .split() with the correct regex and then just pick the first char:
String[] words = "Your String & !+ and some extraodrinary others".split("[^a-zA-Z]+");
for (String word: words ){
System.out.println(word.charAt(0));
}
You can try to fetch them with a Regular Expression.
When I use the RegEx (\w)\w+ on the string Hallo Welt, ich bin ein String, I get an array with H, W, i, b, e, S. Note: You have to run the expression as global expression (more than once).
Assuming the String object you want to process is recInf i would recommend to do it as follows:
String recInf = new String(text.replaceAll("[^\\p{L}\\p{Nd} ]+"," ")
.replaceAll("[\\s]+", " "));
String[] words = recInf.split(" ");
String[] firstLetters = new String[words.length];
for(int i=0; i<words.length;i++){
firstLetters[i]=words[i].getCharAt(0);
}
You could try this
nombre = (new StringBuilder(tipoAbreviado)).toString();
I have this code:
String s = "A very long string containing " +
"many many words and characters. " +
"Newlines will be entered at spaces.";
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
The output of the code is:
A very long string containing
many many words and
characters. Newlines
will be entered at spaces.
The above code is wrapping the string after the next space of every 30 characters, but I need to wrap the string after the previous space of every 30 characters, like for the first line it will be:
A very long string
And the 2nd line will be
containing many
Please give some proper solution.
You can use Apache-common's WordUtils.wrap().
Use lastIndexOf instead of indexOf, e.g.
StringBuilder sb = new StringBuilder(s);
int i = 0;
while (i + 20 < sb.length() && (i = sb.lastIndexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
This will produce the following output:
A very long string
containing many
many words and
characters.
Newlines will be
entered at spaces.
You can try the following:
public static String wrapString(String s, String deliminator, int length) {
String result = "";
int lastdelimPos = 0;
for (String token : s.split(" ", -1)) {
if (result.length() - lastdelimPos + token.length() > length) {
result = result + deliminator + token;
lastdelimPos = result.length() + 1;
}
else {
result += (result.isEmpty() ? "" : " ") + token;
}
}
return result;
}
call as wrapString("asd xyz afz","\n",5)
I know it's an old question, but . . . Based on another answer I found here, but can't remember the posters name. Kuddos to him/her for pointing me in the right direction.
public String truncate(final String content, final int lastIndex) {
String result = "";
String retResult = "";
//Check for empty so we don't throw null pointer exception
if (!TextUtils.isEmpty(content)) {
result = content.substring(0, lastIndex);
if (content.charAt(lastIndex) != ' ') {
//Try the split, but catch OutOfBounds in case string is an
//uninterrupted string with no spaces
try {
result = result.substring(0, result.lastIndexOf(" "));
} catch (StringIndexOutOfBoundsException e) {
//if no spaces, force a break
result = content.substring(0, lastIndex);
}
//See if we need to repeat the process again
if (content.length() - result.length() > lastIndex) {
retResult = truncate(content.substring(result.length(), content.length()), lastIndex);
} else {
return result.concat("\n").concat(content.substring(result.length(), content.length()));
}
}
//Return the result concatenating a newline character on the end
return result.concat("\n").concat(retResult);;
//May need to use this depending on your app
//return result.concat("\r\n").concat(retResult);;
} else {
return content;
}
}
public static void main(String args[]) {
String s1="This is my world. This has to be broken.";
StringBuffer buffer=new StringBuffer();
int length=s1.length();
int thrshld=5; //this valueis threshold , which you can use
int a=length/thrshld;
if (a<=1) {
System.out.println(s1);
}else{
String split[]=s1.split(" ");
for (int j = 0; j < split.length; j++) {
buffer.append(split[j]+" ");
if (buffer.length()>=thrshld) {
int lastindex=buffer.lastIndexOf(" ");
if (lastindex<buffer.length()) {
buffer.subSequence(lastindex, buffer.length()-1);
System.out.println(buffer.toString());
buffer=null;
buffer=new StringBuffer();
}
}
}
}
}
this can be one way to achieve
"\n" makes a wordwrap.
String s = "A very long string containing \n" +
"many many words and characters. \n" +
"Newlines will be entered at spaces.";
this will solve your problem