This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I am implementing a String matching algorithm for a username database. My method takes an existing Username database and a new username that the person wants and it checks to see if the username is taken. if it is taken the method is supposed to return the username with a number that isn't taken in the database.
Example:
"Justin","Justin1", "Justin2", "Justin3"
Enter "Justin"
return: "Justin4"
since Justin and Justin with the numbers 1 thru 3 are already taken.
In my code sample below, newMember returns Justin1 even though it already exists--where is the mistake?
public class UserName {
static int j = 0;
static String newMember(String[] existingNames, String newName){
boolean match = false;
for(int i = 0; i < existingNames.length; i++){
if(existingNames[i] == (newName)){
match = true;
}
}
if(match){
j++;
return newMember(existingNames, newName + j);
}
else{
return newName;
}
}
public static void main(String[] args){
String[] userNames = new String[9];
userNames[0] = "Justin1";
userNames[1] = "Justin2";
userNames[2] = "Justin3";
userNames[3] = "Justin";
System.out.println(newMember(userNames, "Justin"));
// I don't understand why it returns Justin1 when the name is already taken
// in the array.
}
}
This line:
if(existingNames[i] == (newName)){
Should become
if(existingNames[i].equals(newName)){
In general, always use equals instead of == for Strings in Java.
I would change your approach to this. I think it would be better to use a Map<String, Integer>. For example, the fact that "Justin" - "Justin3" are taken usernames can be represented by the map:
{"Justin": 3}
To check if a username is taken, check if it's a key in the map. To get the "next" username for a specific taken username, get the value corresponding to the name from the map and add 1. Something like this:
static String newMember(Map<String, Integer> existingNames, String newName) {
if (existingNames.containsKey(newName)) {
int newNum = existingNames.get(newName) + 1;
existingNames.put(newName, newNum);
return newName + newNum;
}
existingNames.put(newName, 0);
return newName;
}
Oh, and use .equals() instead of == when comparing strings :)
*Never ever compare equality of Strings with ==. use equals() *
Use .equals to compare strings in Java, not ==.
== will determine if the string references are the same which they almost certainly will not be. (There are rare cases when they may be due to the intern pool.)
.equals will determine if the content of the strings are the same.
When comparing strings in Java, you should generally use the equals() methods to do so.
Using == with strings compares the references, not the underlying objects. Use str.equals().
I guess you have a function somewhere in your application answering if a username already exists, I call this usernameExists(String username) returning true or false.
String getOkUsername (String wantedUsername) {
//if it's free, return it!
if(!usernameExists(wantedUsername)) {
return wantedUsername;
};
//OK, already taken, check for next available username
int i=1;
while(usernameExists(wantedUsername+Integer.toString(i))) {
i++;}
return wantedUsername + Integer.toString(i);
}
You're not comparing the strings correctly, and you're adding the integer 1 to a string. Comparing strings is done with .equals. In order to concatenate the integer onto the end of the string:
static Integer j=0;
return newMember(existingNames, newName + j.toString());
It is much easier to do it in SQL:
select ... where ... LIKE username%
Related
So I've been trying to figure this out on my own for the past couple of hours but I'm stuck.
I have an array that has a list of a person's name, age, height (in cm). I want to create a method where I use only the person's name as a parameter and searches for the name in the array; if there is no matching name, return null.
Looks like this:
data = new data[50];
data[0] = new data("Dan", 23, 179);
data[1] = new data("David", 20, 180);
data[2] = new data("Sharon", 19, 162);
data[3] = new data("Jessica", 22, 160);
data[4] = new data("Nancy", 25, 164);
...
numberData = 30; // this is the number of people that are in this array so far
This is what I've been trying so far..
public data findData(String name) {
for (int i = 0; i < numberData; i++) {
if (name == data[i]) {
return data[i];
} else {
return null;
}
}
}
I know it isn't right, but I can't seem to find a solution. Any ideas?
array is referencing the Data class with name parameter so we should compare with name parameter not directly with reference of data and for string comparisons always go for equals() method.
public Data findData(String name) {
for (int i = 0; i < numberData; i++) {
if (name.equals(data[i].getName())) {
return data[i];
}
}
return null;
}
Since you want to compare strings you must use the equals method.
Here's an example of how can you use java 8:
public Data findData(Data[] datas, String name) {
return Arrays.stream(datas).filter(data -> data.getName().equals(name)).findAny().orElse(null);
}
In case the loop doesn't execute at least once, you're missing return value.
== compares references, equals compares Strings.
Return null just in case, there is no such element in the array.
Class names should start with a capital letter. Please write Data instead of data.
Code:
public Data findData(String name) {
for (Data d : data) {
if (name.equals(d.getName())) {
return d;
}
}
return null;
}
is what you're looking for. In the original code, null was returned if the 0th element wasn't name.
OK, the above was a quick fix and now some theory:
The pseudo code for linear search in an array:
Loop through all elements in an array. If any matches with the one you're looking for, return it.
If nothing was returned, return the indicating value (null in our case).
Look, in the original code, on the 0th element, you decided whether to return that element or a null. Also, if the loop wasn't run at least once, there was no return statement to hit.
Use equals() to compare strings,
e.g.
if(name.equals(data[i].getName())) {
statements...
}
You should use equals() to compare strings. equals() checks the actual contents of the string, == checks if the object references are equal.
And also, as mentioned above, move return null outside the loop;
You can use following code. Assuming that your data class will have getName() method which returns the name value.
public data findData(String name) {
for (int i = 0; i < numberData; i++) {
if (name.equals(data[i].getName())) {
return data[i];
}
}
return null;
}
move the return null statement out of the loop.
Oh! and yes, use the equals() method instead of ==
I have to iterate over the elements of a string and in each iteration to perform some checks.
My question is:
What is better to use: String or StringBuilder?
Is there any difference in running time of String.charAt(i) or StringBuilder.charAt(i)?
I do NOT have to modify the string, I just have to iterate over all elements.
The only reason to use a StringBuilder is for modifications (as Strings are immutable). In this case you should be fine with iterating over the String itself.
StringBuilder is useful when you modify a string and String when you dont.
For your case String
Regarding Performance: It will be constant time for both or negligible [1]
Note:
When you modify a string when its defined as string, it creates new string instead of actually modifying it and thats why its better to use StringBuilder
e.g)
string a = "hello";
a = "hai";
a new world string is also created here along with hello already created in string pools
Additional: http://blog.vogella.com/2009/07/19/java-string-performanc/
As others have already said, there is no performance difference between the two. You can convince yourself of this by looking at the source. As you can see below, the two are nigh on identical.
String.charAt()
public char More ...charAt(int index) {
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
StrringBuilder.charAt()
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
In other words, use whatever you already have. If you have a String, use the String, if you have a StringBuilder, use the StringBuilder. The cost of converting from one object to the other will vastly outweigh any performance difference between these two methods.
String and StringBuilder both are classes in Java.
String is used to create a string constant.
StringBuilder name itself indicates to build the string. It means that we can easily do
modification using this class.
In your case you can simply use String class.
Strings are immutable in Java. This means that after each modification a new String is created with latest modified value.
String str = new String("AVINASH");
char check = 's';
int length=str.length();
for(int i=0; i <length ; i++) {
if (check==str.charAt(i)) {
System.out.println("Matched");
}
}
I currently have two arrays containing usernames and passwords.
String[] UsernameArray = {"John","Per","Daniel","Jonathan"};
String[] PasswordArray = {"Davis","Harring","Smith","West"};'
Now i have an if statement looking like this:
if(Arrays.asList(UsernameArray).contains(LoginPanel.Username)&& Arrays.asList(PasswordArray).contains(LoginPanel.Password)) {
//Do something
}
Everything is working fine, except for the fact i only want respective people to use their respective last names as passwords. I want for example the username to be "John" and the password to be "Davis" ONLY.
As of now if i enter John and then enter the second persons last name "Harring" i get "Success!" and is logged on. How can i change this so the persons passwords can only be their own lastname and not anyone else's?
You need to make sure that the strings are at the same index in their respective arrays. Use the indexOf method:
if (Arrays.asList(UsernameArray).contains(LoginPanel.Username) &&
Arrays.asList(PasswordArray).contains(LoginPanel.Password) &&
//this way me make sure the username and password are at the same position.
Arrays.asList(UsernameArray).indexOf(LoginPanel.Username) == Arrays.asList(PasswordArray).indexOf(LoginPanel.Password)
)
{
//Do something
}
You may want to use a few local variables to avoid so many calls to Arrays.asList, which will create a new list every time you call it.
You don't need ArrayLists for that purpose, it's a waste of memory, you can use just arrays.
Loop over the array and check if the username given is right, save the index of that username and check if the password at that index is the same entered by the user. Something like this:
for (int i=0; i<usernameArray.length; i++) {
if (LoginPanel.username.equals(usernameArray[i]) && LoginPanel.password.equals(passwordArray[i])) {
//right credentials
}
}
To be clear: inputUser and inputPassword are username and password entered by the user
Note: As you can see, i used usernameArray, passwordArray, LoginPanel.username and LoginPanel.password with lowercase u and p: this is because of java naming conventions, you should start variable names with a lowercase letter.
Use indexOf:
List<String> usernames = Arrays.asList(UsernameArray);
if (usernames.contains(LoginPanel.Username) &&
PasswordArray[usernames.indexOf(LoginPanel.Username)].equals(LoginPanel.Password)) {
// Do something
}
From the API documentation
boolean contains(Object o)
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
In your case, UsernameArray contains John and PasswordArray contains Harring and hence Arrays.asList(UsernameArray).contains(LoginPanel.Username)&& Arrays.asList(PasswordArray).contains(LoginPanel.Password) returns true.
You can use a Map of user name password like
Map<String,String> map = new HashMap<String,String>();
map.put("John","Davis");
and then this can be validated
String password= map.get(LoginPanel.Username);
if(LoginPanel.Password.equals(password0){
//Do something
}
Please note that in a real web application, password would be stored encrypted in some data store and not in a program.
you could do:
for(int i=0;i< UserNameArray.length; i++){
if(UserNameArray[i].equals(LoginPanel.Username)&& PasswordArray[i].equals(LoginPanel.Password)){
//do something
}
Easy way is that
public class LoginTestEasy {
public static void main(String[] args) {
String[] UsernameArray = {"John","Per","Daniel","Jonathan"};
String[] PasswordArray = {"Davis","Harring","Smith","West"};
String loginToCheck = "John";
String passwordToCheck = "Herring";
boolean loggedIn = false;
for(int i = 0; i < UsernameArray.length; i++) {
String currentLogin = UsernameArray[i];
String currentPass = PasswordArray[i];
if(currentLogin.equals(loginToCheck) && passwordToCheck.equals(currentPass)) {
loggedIn = true;
break;
}
}
System.out.println("Is logged in: " + loggedIn);
}
}
but the better way is to join login and password pair in single object. smth like
class LoginData {
String login;
String pass;
LoginData(String login, String pass) {
this.login = login;
this.pass = pass;
}
String getLogin() {
return login;
}
String getPass() {
return pass;
}
}
and then to loop among them.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java String.equals versus ==
I am using jcreator to practice java language. I came up with a conditional statement in which if the user input is = "test" it will print an "okay!" message. This is my code:
class conditional {
public static void main (String[] args) {
Scanner user_input = new Scanner(System.in);
String username;
System.out.print("username: ");
username = user_input.next();
if (username == "test") {
System.out.println("okay");
}
else {
System.out.println("not okay");
}
}
The above code does not show any error, it does not display the "okay" && "not okay" message either. I am not sure what's wrong with my logic.
Strings should be compared using .equals rather than ==. This is the case for all non-primitive comparisons. For example, you would compare two int fields with ==, but because Strings are not primitive, .equals is the correct choice.
if (username.equals("test")) {
You should use String.equals here.
if (username.equals("test")) {
Otherwise, you're comparing the identities of the objects rather than their semantics. In fact, you have two separate Strings here, which satisfy semantic equality.
as #veer said,
you can use equalsIgnoreCase / equals if (username.equals("test")) { ... }
Or
You can use compareToIgnoreCase / compareTo
if (username.compareTo("test")==0) { ... }
Or If you want to use == do username.intern(); Then you can use ==.
Note: Not a recommended approch just for FYI.
To compare string you need to use .equals() method and also if you need ignore the case of the letters in the String you can use .equalsIgnoreCase()
if (username.equals("test")){
}
else{
}
It will work if you do it like this:
import java.util.Scanner;
class Conditional {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
String username;
System.out.print("username: ");
username = user_input.next();
if (username.equals("test")) {
System.out.println("okay");
} else {
System.out.println("not okay");
}
user_input.close();
}
}
A few remarks:
Class names should start with an upper case.
Use equals to compare Strings.
You state that no result is printed at all. You will have to click in the console to type your answer and end the input with Enter.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I really don't know why the if statement below is not executing:
if (s == "/quit")
{
System.out.println("quitted");
}
Below is the whole class.
It is probably a really stupid logic problem but I have been pulling my hair out over here not being able to figure this out.
Thanks for looking :)
class TextParser extends Thread {
public void run() {
while (true) {
for(int i = 0; i < connectionList.size(); i++) {
try {
System.out.println("reading " + i);
Connection c = connectionList.elementAt(i);
Thread.sleep(200);
System.out.println("reading " + i);
String s = "";
if (c.in.ready() == true) {
s = c.in.readLine();
//System.out.println(i + "> "+ s);
if (s == "/quit") {
System.out.println("quitted");
}
if(! s.equals("")) {
for(int j = 0; j < connectionList.size(); j++) {
Connection c2 = connectionList.elementAt(j);
c2.out.println(s);
}
}
}
} catch(Exception e){
System.out.println("reading error");
}
}
}
}
}
In your example you are comparing the string objects, not their content.
Your comparison should be :
if (s.equals("/quit"))
Or if s string nullity doesn't mind / or you really don't like NPEs:
if ("/quit".equals(s))
To compare Strings for equality, don't use ==. The == operator checks to see if two objects are exactly the same object:
In Java there are many string comparisons.
String s = "something", t = "maybe something else";
if (s == t) // Legal, but usually WRONG.
if (s.equals(t)) // RIGHT
if (s > t) // ILLEGAL
if (s.compareTo(t) > 0) // also CORRECT>
Strings in java are objects, so when comparing with ==, you are comparing references, rather than values. The correct way is to use equals().
However, there is a way. If you want to compare String objects using the == operator, you can make use of the way the JVM copes with strings. For example:
String a = "aaa";
String b = "aaa";
boolean b = a == b;
b would be true. Why?
Because the JVM has a table of String constants. So whenever you use string literals (quotes "), the virtual machine returns the same objects, and therefore == returns true.
You can use the same "table" even with non-literal strings by using the intern() method. It returns the object that corresponds to the current string value from that table (or puts it there, if it is not). So:
String a = new String("aa");
String b = new String("aa");
boolean check1 = a == b; // false
boolean check1 = a.intern() == b.intern(); // true
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
You shouldn't do string comparisons with ==. That operator will only check to see if it is the same instance, not the same value. Use the .equals method to check for the same value.
You can use
if("/quit".equals(s))
...
or
if("/quit".compareTo(s) == 0)
...
The latter makes a lexicographic comparison, and will return 0 if the two strings are the same.
If you code in C++ as well as Java, it is better to remember that in C++, the string class has the == operator overloaded. But not so in Java. you need to use equals() or equalsIgnoreCase() for that.