I figured out a a problem in my Code. First the code:
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
String[] blablubb = { "a", "b", "c" };
for(String s : blablubb) {
s = "over";
}
printArray(blablubb);
for (int i = 0; i < blablubb.length; i++) {
blablubb[i] = "over";
}
printArray(blablubb);
}
public static void printArray(String[] arr) {
for( String s : arr ) {
System.out.println(s);
}
}
}
The output is:
a
b
c
over
over
over
I assumed the first loop would also overwrite the String in the array. So the output would be over in any case. It seems it creates a copy of the value instead creating a reference.
I never perceived this. Am I doing it wrong? Is there an option to create a reference instead?
//Edit:
Seems like everybody knows about that except me. I'm from C background and doesn't pay enough attention to the term reference which is very different to C.
Fortunately it took me just 10 minutes to figure this out (this time).
This:
for (String s : blablubb) {
s = "over";
}
Is equal to this:
for (int i = 0; i < blablubb.length; i++) {
String s = blablubb[i];
s = "over";
}
This creates a temporary String with a copy of the value from array and you change only the copy. That's why blablubb[] content stays untouched.
If you want to change values in the array, just use your second option:
for (int i = 0; i < blablubb.length; i++) {
blablubb[i] = "over";
}
And, by the way, you can print an array with just one line:
System.out.println(Arrays.toString(blablubb));
Your for(String s : blablubb) loop is equivalent to the following code:
for(int i = 0; i < blablubb.length; i++ ) {
String s = blablubb[i];
s = "over";
}
Hopefully, from this you can see that all you are doing is reassigning a different value to s without changing blablubb[i]. This explains the output you see.
The for-each loop don't modify the objects contained in the Collection of objects it's iterating over. It's passing the value not the reference.
s = "over";
just changes the reference of s and not the String in the array.
blablubb[i] = "over";
changes the value stored at ith location in the array
for(String s : StringArray)
{
}
is like
for(int i = 0; i < StringArray.length; i++)
{
String s = StringArray[i];
}
When you want to do a low level optimization, know how, you have to look inside Java code and inside byte-code either(compiled code)
for(String s : blablubb) {
s = "over";
}
is equals with:
for (int i = 0; i < blablubb.length; i++) {
String s = blablubb[i];
s = "over";
}
and that's why the output as how it is.
Related
I've worked with arrays and know how to sort arrays that work with number values (double and int), but I have to make the same application using String arrays. My professor does not allow me to be "creative", or work with other static classes that might help to do the work.
I have to find the greatest value (in ASCII terms) of an array of String.
This is what I did:
public static String getGreatestValue(String[] StringArray) {
String greatestValue = StringArray[0];
for (int i = 0; i < StringArray.length; i++){
for (int index= i+1; index < StringArray.length -1; index++) {
if (StringArray[i].compareTo(StringArray[index]) == 1)
greatestValue = StringArray[i];
}
}
return greatestValue;
The list that I am working with in my Main Class looks like this:
package legacy;
public class Main {
public static void main(String[]args){
String[] names = {"D", "A", "B", "F"};
String greatestValue = StringArray.getGreatestValue(names);
System.out.println(greatestValue);
}
}
When I run the program it returns:
D
In this list the greatest value should be F.
I will be glad if someone finds a solution with this.
You don't need a nested loop. You should be comparing StringArray[i] to greatestValue (not to StringArray[index]). And you can start at 1 since you initialized greatestValue to StringArray[0]. Like,
String greatestValue = StringArray[0];
for (int i = 1; i < StringArray.length; i++){
if (StringArray[i].compareTo(greatestValue) > 0) { // <-- or < 0 as appropriate
greatestValue = StringArray[i];
}
}
return greatestValue;
Finally, please respect Java variable naming conventions (StringArray looks like a class name, variables typically start with a lower case letter).
Your problem is made because of two things. First of all you don't need nested loop. Second thing, is that you are checking if comparision is equal to 1. While you should check if it is higher or lower then 0 (depending on what you are comparing).
Here is working code:
public static String getGreatestValue(String[] StringArray) {
String greatestValue = StringArray[0];
for (int i = 0; i < StringArray.length; i++) {
System.out.println(StringArray[i]);
if (greatestValue.compareTo(StringArray[i]) < 0)
greatestValue = StringArray[i];
}
return greatestValue;
}
Here you got examples how compareTo works with String:
System.out.println("A".compareTo("B")); //prints -1
System.out.println("A".compareTo("C")); //prints -2
You're code does look a little bit too complicated. And it is recommned to begin variables with a lowercase character.
To your function, try:
public static String determineGreatest(String[] list) {
String greatest = list[0];
for (String cur: list) {
if (cur.compareTo(greatest) >= 1) greatest = list[0];
}
return greatest;
}
You can use a similar method for determining the least string.
Java 8 provides a great way to do it:
System.out.println(Arrays.stream(names).max(Comparator.naturalOrder()).get());
I'm stuck on an assignment in which we have to replace every output comming from an array of "yes" with "no", and leave any other output untouched.
I keep getting the error cannot convert from String to String[], and I'm unsure of how to work around this, because I haven't been able to find any String to String[] conversion in the Javadoc.
I've been trying to find a solution for a while, so I just need a push in the right direction.
String[] makeItANegativeArray(String[] inputArray) {
String x = "no";
if (inputArray.equals("yes")) {
return x;
} else {
return inputArray;
}
}
Let's take a look at the code
//Start the function
String[] makeItANegativeArray( String [] inputArray ) {
// function needs String[] as input
// function suspects String[] as output (or return)
// initialise the variable x
String x = "no";
// if the input array is equal to the string VALUE "yes"
// (which is WEIRD because it's an ARRAY not a VALUE)
if (inputArray.equals("yes"))
{
//return A VALUE
//so here we return a VALUE while the function is suspecting an ARRAY
//this causes the error
return x;
}
else
{
//return an array
//(hence if this happens, the function terminates at the first iteration)
return inputArray;
}
}
Clearly, your input is an array and your output should be an array as well.
Hence you will have to loop over each element of the input array and construct and output array before returning anything.
For example:
String[] makeItANegativeArray( String[] inputArray ) {
String x = "yes";
String y = "no";
for (int i = 0; i < inputArray.length; i++)
{
if (inputArray[i].equals("yes"))
{
inputArray[i] = y;
}
else
{
inputArray[i] = x;
}
}
return inputArray;
}
What this does is turn every "yes" in the array into a "no" and every "no" into a "yes".
So it sort of "inverts" the array.
Is this what it is supposed to do?
Alternatively,
If you just want to turn the whole array into an array of only "no's", then do the following:
String[] makeItANegativeArray( String[] inputArray ) {
String x = "no";
for (int i = 0; i < inputArray.length; i++)
{
if (inputArray[i].equals("yes"))
{
inputArray[i] = x;
}
}
return inputArray;
}
NOTE: You are dealing with an array.
inputArray.equals("yes") is what causing the error. You are supposed to get each element in the Array and compare it to "yes".
What the error is telling you is you cannot compare an array of String with a String.
You should do sth like this
String [] makeItANegativeArray( String [] inputArray )
{
for(int i = 0; i < inputArray.Length; i++)
{
if (inputArray[i].equals("yes"))
{
inputArray[i] = "no";
}
}
return inputArray;
}
When you say inputArray.equals it compares array with string and it gives error.You have to iterate through all elements in array and set yes to no and return the edited array.
What are you trying to do with your String[] inputArray. Because you are comparing it's value as if it were a String object, not a String array. If you want to access the first element of the inputArray and then compare the value of that, then that would be within the makeItNegativeArray(String[]):
String[] outputArray = new String[inputArray.length];
for (int i = 0; i < inputArray.length; i++)
{
if (inputArray[i].equals("yes"))
{
outputArray[i] = "no";
}
else
{
outputArray[i] = "yes"
}
}
return outputArray;
I would suggest that you have a look at the use of Arrays in Java and how they differ from single objects. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html as that may give you a real grasp of the usage of arrays and how they can be accessed. Arrays are a really important concept in programming and if you can master it, you will take another step into becoming a star.
Just simple reverse string method.
FYI, correct methods are reverseString1 and reverseString2,
but revereStirng3() doesn't give me correct output.
I think this is because of method args and return values are stored in the Stack and related with this concept. But I don't clearly understand why revereStirng3() doesn't work correctly.
Please let me know whey this is not working.
This is what I understand, and please correct me if I'm wrong.
1. main() calls revereStirng3(A) where this passing argument array A is stored in the stack frame for the main().
revereStirng3(char[] A) where this passed argument array A is stored in revereStirng3's method frame which means main's A[] is copied to revereStirng3's stack frame's method argument A[].
After reverse, revereStirng3 creates new String(A) for return String.
Then, I thought, in the main, returned new String(A) is correctly print reversed string, but actually not.
// Given a string "abcdef", reverse it. so output should be "fedcba"
import java.util.*;
public class ReverseString {
static String revereStirng3(char[] A) {
int n = A.length;
for(int i=0; i<n/2; i++) {
char temp = A[n-i-1];
A[n-i-1] = A[i];
A[i] = temp;
}
return new String(A);
}
static void revereStirng1(char[] A) {
int n = A.length;
for(int i=0; i<n/2; i++) {
char temp = A[n-i-1];
A[n-i-1] = A[i];
A[i] = temp;
}
}
static String revereStirng2(String str) {
char[] A = str.toCharArray();
int n = A.length;
for(int i=0; i<n/2; i++) {
char temp = A[n-i-1];
A[n-i-1] = A[i];
A[i] = temp;
}
return String.valueOf(A);
}
public static void main(String[] args) {
String s = "abcdef";
char[] A = s.toCharArray();
System.out.print( revereStirng3(A) + "\n" ); **// print out "abcdef"**
System.out.println( "" );
revereStirng1(A); // print out "fedcba"
for(int i=0; i<A.length; i++)
System.out.print( A[i] );
System.out.println( "" );
System.out.print( revereStirng2(s) + "\n" ); // print out "fedcba"
System.out.println( "" );
}
}
Ok, given that zenbeni has got the real results, here is what is happening.
An array in Java is an object, so in revereString1 and revereString3 you get a copy of the reference to the array. So, your changes modify the original array, which (after the first method execution) has been reversed. Of course, the second execution reverses it again, so you get the reverse of the reverse, which is the original String.
Try using a new, locally defined array to create the reversed String and everything will work fine.
From apache commons:
StringUtil.reverse(str);
I have copied your method and executed it
System.out.println(revereStirng3("abcdef".toCharArray()));
on the result was
fedcba.
The problem is located in the main function:
public static void main(String[] args) {
String s = "abcdef";
char[] A = s.toCharArray();
System.out.println( revereStirng3(A)); // print out "abcdef"**
revereStirng1(A);
System.out.print(Arrays.toString(A)); // print out "fedcba"
System.out.println(revereStirng2(s)); // print out "fedcba"
}
Your comments do not show the true.
The valid output for it would be
fedcba
[a,b,c,d,e,f]
fedcba
And this is because you operate on the same array for three test cases. In the second step you pass allready reversed array as input. This results that the order has not changed.
I'm making this method remove() which takes a String word as argument, to delete from a global Array "words", but I keep getting a NullPointerException for some reason I cannot find, been stuck for hours.
Basically I check for if the word is in the first position, else if is in the last position, or else if it is in neither so I check all the array, and add the first half before the position of the word, and then add the second half after the position of the word in the array, as to skip it and "delete it". But I'm getting a NullPointerException in the for loop looking for the position of the word in the array. Code for the method is here:
public void remove(String a){
String[] temp_arr = new String[words.length-1]; // make array with 1 less length for deleted
if(words[0].equals(a)){ // if the word is the first in the array
for(int x=0, z=1; x<temp_arr.length; x++,z++)
temp_arr[x]=words[z];
words = temp_arr;
} else if(words[words.length-1].equals(a)){ // if the word is in the last position of the array
for(int x=0, z=0; x<temp_arr.length; x++,z++)
temp_arr[x] = words[z];
words = temp_arr;
} else{ // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop, in the if(words[k].equals(a))
int k=0;
for (; k<words.length; k++){ // find the position of the word to delete
if (words[k].equals(a)) {
break;
}
}
for (int i = 0; i < k-1; i++){ // add first part of array before the word
temp_arr[i] = words[i];
}
for(int c = k, b = k+1; c< temp_arr.length; c++,b++){
temp_arr[c] = words[b];
}
words = temp_arr; // assign the new values to global array
}
}
Also, if theres any suggestions for good coding practice would be appreciated, thanks!
** I can only use Arrays as my data structure for this method.
Modify the condition like this
a.equals(words[0])
because you know the string value a. But dont know what value will come from array. So even null value comes from the array it does allow the null pointer exception.
I run your code and find a few errors, I correct somethings without changing the core idea:
} else { // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop.
int k = -1;
for (int i = 0; i < words.length; i++) { // find the position of the word to delete
if (words[i].equals(a)) {
k=i;
break;
}
}
if(k<0)//if not exists
return;
for (int i = 0; i < k /*- 1*/; i++) { // add first part of array before the word
temp_arr[i] = words[i];
}
for (int i = k; i < temp_arr.length; i++) {
temp_arr[i] = words[i+1];
}
words = temp_arr; // assign the new values to global array
}
If the original array could't have null elements I would do like this:
public static String[] remove(String words[] , String a) {
int counter = 0;
for (int i = 0; i < words.length; i++) {
if( a.equals(words[i]) ){
words[i] = null;
counter++;
}
}
if(counter==0){
return words;
}
String[] words2 = new String[words.length - counter];
int i=0;
for (String string : words) {
if(string!=null){
words2[i++]=string;
}
}
return words2;
}
I would do that like this:
public void remove(String a) {
List<String> tmp = new ArrayList<String>();
for (String word : words) {
if ((word != null) && (word.equals(a))) {
continue;
}
tmp.add(word);
}
words = tmp.toArray(new String[]);
}
I have a question for you:
Why oh why are you using an array? You should always use a collection (eg a List) unless you absolutely have to use an array (which is rare indeed).
If it were a List, you wouldn't even need this method, because List has the remove() method that does all this for you!
class anEvent{
String number;
String dueTime;
}
public static void main(String args[]) {
int x = args.length / 2;
int y = args.length;
anEvent [] order = new anEvent [x];
for(int i=0; i<x; i++){
if(i==0){
order[i].number = args[0]; //Line(#)
order[i].dueTime = args[1];
} else if ( i % 2 == 0){
order[i].number = args[i];
order[i].dueTime = args[i];
} else if ( i % 2 != 0){
order[i].number = args[i+1];
order[i].dueTime = args[i+1];
} else if ( i == x -1){
order[i].number = args[x-1];
order[i].dueTime = args[x-1];
}
}
Java complains that a Null Pointer exceptuion is present at line # in the above snippet.
What's the matter?
ps: I know that the snippet can be cleaned up but there should be no problem at all on line #
When an array is created, all the array elements are null. In your case, you need to fill the array with new anEvent() instances.
Make the first line of your for-loop:
order[i] = new anEvent();
As is, you are not initializing anything in the array (they're all null), so when you try to access the fields you get that exception.
Since you mention that it "can be cleaned up", I took the liberty of so doing:
public class Thing {
private String number;
private String dueTime;
public Thing(String number, String dueTime) {
this.number = number;
this.dueTime = dueTime;
}
public static void main(String args[]) {
int x = args.length / 2;
Thing[] order = new Thing[x];
for (int i = 0; i < x; i++) {
if (i == 0) {
order[i] = new Thing(args[0], args[1]);
} else if (i % 2 == 0) {
order[i] = new Thing(args[i], args[i]);
} else if (i % 2 != 0) {
order[i] = new Thing(args[i + 1], args[i + 1]);
}
}
}
}
"anEvent" doesn't conform to the capitalized camel-case Java standard, so I renamed it. "Thing" isn't particularly meaningful, but there isn't much to work with here. The final else if clause can never be reached, because i % 2 either is or is not equal to zero, so I dropped it. And, of course, I'm creating new Things, which avoids the problem of the nulls. Enjoy.
NullPointerException means that you attempted to add a value or execute a method to something that turn out to be a null.
In Java object references can have assigned ... well, objects and null
When they have null assigned this exception is thrown:
Object o = null;
o.toString(); // <- NullPointerException ( think of null.toString() )
Arrays, are objects also. When you create an array with a size, all the "boxes" inside the array contain null as reference.
So:
Object[] array = new Object[10];
Creates something similar to the following:
[null,null,null,null,null,null,null,null,null,null]
That's why, when you execute:
array[0].toString(); // or order[i].number in your specific example...
You get that exception, because the effect is exactly the same as:
null.toString(); // or null.number <-- NullPointerException.
To solve this problem, you have to assign a valid object reference to that position into the array:
for(int i=0; i<x; i++){
order[i] = new anEvent();
...
...
I hope this helps.
Final note. In Java classes names start with upper case, so your class should've really be:
class AnEvent {
....
And finally, most of the java source code is indented using 4 spaces.
You hasn't created any anEvent instance, defining an array (order[]) you are not creating default values for it.
and also there are more simple array for your case:
List events = new ArrayList(x);
for(int i=0; i<y; i+=2){
anEvent event = new anEvent();
anEvent.number = args[i];
anEvent.dueTime = args[i+1];
events.add(event);
}
anEvent[] order = events.toArray();