Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I am new to java. Trying to create a function to remove a given string "arg" from myString which is previously set and return a new string not affecting myString. I believe i could solve this problem if it was not for all non alphabetical character of arg should remain in the string. so if arg has a 7 in it that should still be included in the final string. characters being removed are case insensitive as well.
I have edited the previous code and post, i can now run my code but I am not getting the correct results, I am trying to remove all numbers from arg before using it to remove all the characters. myString method is previously defined and working properly to return a string.
For examplecurrent string "my lucky numbers are 6, 8, and 19.", calling remove("ra6") would return "my lucky numbes e 6, 8, nd 19."
or "my lucky numbers are 6, 8, and 19.", calling remove("6,.") would return "my lucky numbers are 6, 8, and 19."
thank you!
public String remove(String arg) {
char[] charArray=arg.toCharArray();
String result="";
String newString="";
for (int i = 0; i < charArray.length; i++) {
if (!Character.isDigit(charArray[i])) {
result = result + charArray[i];
return result;}}
if (myString==null || myString=="") {
this.myString="";}
if (myString!=null) {
newString= myString.replaceAll(result,"");}
return newString;
}
Here is one way using streams. Just create a stream of characters via the chars() method and allow only letters to pass thru. Then each character to a String and join them together. Then remove that result from the original passed string.
String myString = "abcdTLK123efgh";
String arg = "TLK###123";
String result = remove(arg, myString);
System.out.println("Result = " + result);
prints
Result = abcd123efgh
The method
I modified the method to accept two strings.
the one to remove characters(arg).
and the from which to remove modified arg from myString
it works by
streaming all the characters of arg.
filtering out all but letters and digits
joining them as a string.
and then removing that filtered string from the myString.
public static String remove(String arg, String myString) {
if (myString == null || myString.isBlank()) {
return "";
}
return arg.chars().filter(
ch -> Character.isLetter(ch))
.mapToObj(Character::toString)
.collect(Collectors.collectingAndThen(
Collectors.joining(),
str -> myString.replace(str, "")));
}
Note: If myString is null then assigning an empty string to it will contain nothing to change. Nor an initial empty string. So I just returned an empty String if those conditions existed.
I believe i could solve this problem if it was not for all non alphabetical character of arg should remain in the string.
The good news is that you can solve it yourself.
The bad news is that the code above is in such a mess that it would be difficult for you to fix it by yourself. (Given your current level understand of Java syntax, way of working, etcetera.)
(Also, there is a long more wrong than the "if it were not for ..." ...)
So here is what I advise you to do.
Save a copy of the current version of the (entire) class somewhere safe so that you can look it again if you need to, or revert to it.
Develop a model of what the method needs to do and how it will do it; see below.
Delete all lines of code between the first { and last } shown in the question. Yes. Delete them.
Compose the new version of the code, one line at a time. As follows:
Add a line.
Compile the code (or let the IDE compile it for you).
Read the compilation error(s) that just appeared.
Understand the compilation errors.
Make the necessary changes to fix the compilation errors. Don't rely on your IDE's facility for suggesting corrections. (The IDE doesn't understand your code, what you are going to add next, or what you are trying to achieve. Its suggestions are liable to be unhelpful or even wrong.)
Repeat until you have dealt with all of the compilation errors that were introduced.
Now you are ready to add another line.
Once you have a complete method, you can then try to run it.
You will most likely find that the code doesn't work. But at least it will be valid Java code. And in the process of doing 4. above, you will (hopefully!) have learned enough Java syntax to be able to read and understand the code that you wrote. And 2. will help you understand what the code you are writing should do.
My other observation is that it looks like you have been adding and removing statements to this code with no clear understanding of what they do or what needs to happen. Maybe you started with some code that did something else ... correctly ... but it is hard to tell now.
Changing things randomly to try to make the code work is not a sensible approach. It rarely works. You need to have a model (or plan) in your head or on paper (e.g. as pseudo-code or flowcharts) about how the code ought to work.
Programming is about 1) developing the model, then 2) translating the model into code. The first part is the hard (and interesting) part. But if you skip the first part, the second part is an essentially random process, and unlikely to succeed.
The problem with starting with someone else's code is that you risk not developing a mental model of how that code works. Let alone the model that you are aiming for.
Finally, a professional programmer will use a version control system for their source code, and make relatively frequent commits of their code to their repository. Among other things, that allows them to quickly "roll back" to an earlier version if they need to, or keep track of exactly what they changed.
It is probably too early for you to learn about (say) using Git ... but it would help you solve your problem if you could just "roll back" all of the changes where you were "messing" with the code to get it to work.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm trying the retrieve the last modified file name with a matching pattern starts with Order_ and there should not be any hidden files, however it throws compilation error.
try {
File dir = new File("< dir >");
if (!dir.isDirectory()) {
Optional<File> op = Arrays.stream(dir.listFiles(File::isFile))
.max((f1, f2) -> Long.compare(f1.lastModified(), f12lastModified()))
.filter(fl -> fl.getName().startsWith("Order_") && !fl.getCanonicalPath().endsWith("~"))
; // Unhandled exception compilation error for canonicalPath method
}
} catch (Exception e) {
}
Exception: Unhandled exception: java.io.IOException
Any ideas would be greatly appreciated.
This feels like lambda abuse (using a hammer to butter your toast instead of, you know, a butter knife, because you just bought it and it's all shiny and new).
.max() returns either 1, or 0, elements, in the form of an Optional. you then filter that optional to check if the naming is right.
In other words, if the most recently modified file so happens to not start with Order_, this all returns Optional.NONE which surely wasn't your intent. You want to flip your max and your filter line.
More generally, you don't want to do this with lambdas. Inline Lambdas are the lesser evil - they are not exception transparent, not mutable local variable transparent, and not control flow transparent.
These 3 properties are fantastic when a lambda represents code that will run in some other context (e.g. another thread or much later). They are downsides when the code is going to be run then and there.
That means that when a lambda-based strategy and a non-lambda-based strategy for an inline code concept are roughly equally good, then you should prefer the non-lambda-based strategy. This becomes particularly poignant here, as the code is using obsolete API (the old java.io.File API, instead of the newer java.nio.file API).
In this case, .getCanonicalPath() is slightly odd behaviour: The only functional difference between invoking fl.getName().endsWith(...) and fl.getCanonicalPath().endsWith(...) is that the latter will first follow the link if the referenced 'file' is a soft-link.
That sounds like soft-links matter, and if they matter, you don't want this API as it is wonky and ill defined in the face of soft-links. The new API deals with it better, you'd want to use that (java.nio.file.Files's walk method, for example). If soft linking doesn't matter, then it's easy: Replace .getCanonicalPath() with .getName() and all is well. Well, after you fix your bug and flip the filter and max lines back in their right positions.
Note also that .getCanonicalPath() is slow - it needs to hit the disk, or at least, it might. (It will if it is a soft-link; the API doesn't define whether it will in other cases. The JVM impl is free to hit disk on some OSes and not on others. It may run blazingly fast on your system and run dog slow on another, making it hard to test).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm just getting started with Java and while reading through this guide I noticed the following snippet, describing a recent update to the Junit framework.
We can now write assertion messages in a lambda in JUnit 5, allowing
the lazy evaluation to skip complex message construction until needed:
#Test
public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation() {
Assertions.assertTrue(
2 == 3,
() -> "Numbers " + 2 + " and " + 3 + " are not equal!");
}
As someone new to Java this feels like a large implementation just to get around string concatenation.
Are evaluating strings in Java really that slow (relative to other languages?). How does it compare to other compiled languages like C, Golang, etc..?
The point is: there is no lazy string formatting in Java.
Meaning, in languages like C you might see things such as:
#define debug_print...
( see some real world examples here )
The idea is to define a macro to which you pass a complicated string. But the compiler makes sure that code gets only generated for situations that actually that string to be present.
Meaning: when using debug_print(), that complicated string concat that is might be required to build the messages passed to the macro call only happens when the message is really needed! The message is concatenated lazily.
In Java, we simply have no way to express that. You always have to go
if (someCondition) {
then pull together that large string
which isn't nice, especially when doing it for tracing. Some people in our group write that code, and it is just overly annoying that each and any trace statement has that leading if statement. That renders your whole code much less readable.
Therefore: this is not at all about the cost of string concats. It is about only spending the required CPU cycles if that string is truly needed.
And to answer the actual question: in the end, when that code gets invoked often enough, the JIT will turn it into carefully optimized machine code anyway. Thus: the actual string concat is not the issue.
In other words: you don't think of "performance" for Java in terms of source code. What matters is what happens at runtime, by the JIT.
Here's the bottom line. Starting out in Java, don't worry about minor performance issues like String concatenation. It may be a small issue for a large application server where lots of String concatenation is done but the results are not used. An example would be logging, where the log level of causes the event to be ignored. Also, Java uses a StringBuilder to concatenate a series of literals separated by the "+' operator, which is reasonably performant.
I have a string that needs to be compared to the names that are on the website. So the first thing I do is get the number of rows (because some arrays have more or fewer than 2 people in them) and then put that size into an int. String[] names come from the names that selenium is supposed to find when it goes to the website to execute this statement assertTrue(assertion.getText().contains(names[i-1])); The problem is: if the names do not appear in the order in which they appear in the array it breaks. In other words, if Mick Jagger is in li[1] and Keith Richards is in li[2], everything runs as expected. But if Keith Richards appears in li[1] it breaks. Furthermore, I am supposed to use the assertTrue command to do this. I have tried sorting, pushing whats on the web into a new ArrayList and I keep getting errors. Anyone know a good way to ensure the order isn't important and still use the assertTrue command?
Thanks,
Scott
WebElement assertion = null;
List<WebElement> assignees = driver.findElements(By.xpath(".//*[#id='assignee']/li"));
int count = assignees.size();
String[] names = {"Mick", "Keith"};
for (int i = 1; i < count; i++)
{
assertion = driver.findElement(By.xpath(".//*[#id='assignee']/li["+i+"]"));
assertTrue(assertion.getText().contains(names[i-1]));
If names represents the full string, you can just flip it. Make sure the text in your assertion (probably should be named something like assignee instead of assertion) is contained in your collection:
assertTrue(Arrays.asList(names).contains(assertion.getText());
Let me know if this won't work because a name is actually a subset of the text in assertion and I'll adjust the answer.
If they don't exactly match (which you have indicated they don't), you could use linq in c# to match this. Since you're using java you can use an additional loop. There may be a more efficient way to do this in java that I'm not aware of.
String assigneeText = assertion.getText();
boolean nameFound = false;
for(String name: names)
{
nameFound = assigneeText.contains(name);
if(nameFound)
{
break;
}
}
assertTrue(nameFound, "None of the expected names were found in the following assignee text: " + assigneeText);
I'm in the final stages of testing before I release the alpha version of a program I am writing. This may be a silly question but I just can't seem to figure it out. I understand what drjava is telling me, that I'm missing a variable, but I also don't understand because I never made a variable under the name "()". I'm not even sure you can set any type of variable to a open-close parenthesis. Anyways I was testing and while it works, it doesn't the way I want it to. I entered into the scanner "Mr. B." without the quotes of course. The program did not print the B. I'm thinking it might be the space in between Mr. and B, because other inputs with a space did the same. I can not release a version of my program knowing there is a GIANT glitch in the code. I'm wondering why, and I tried to fix it by changing ownersname.next(); to ownersname.nextLine and ownersname.next and ownersname.nextScanner and ownername.nextScanner. This is where the error comes in, when it says it can't find the variable until I change it back to it's original code, which is below.
Scanner ownersname = new Scanner(System.in);
String sownersname = ownersname.next();
System.out.println(sownersname + "? That is a nice name.");
I'm in the final stages of testing before I release the alpha version of a program I am writing.
You're creating a professional application? Please do tell us more about this.
I understand what drjava is telling me, that I'm missing a variable, but I also don't understand because I never made a variable under the name "()". I'm not even sure you can set any type of variable to a open-close parenthesis.
When posting questions here, if you have an error message from the compiler, please post the entire error message with your question. Don't paraphrase it. And indicate by obvious comment in your code, i.e., // ****** error here ***** where the error is occurring.
Anyways I was testing and while it works, it doesn't the way I want it to. I entered into the scanner "Mr. B." without the quotes of course. The program did not print the B. I'm thinking it might be the space in between Mr. and B, because other inputs with a space did the same.
Don't use Scanner#next() which gets only the next token -- the next word before reaching whitespace (here, Mr.), and will not get the rest of the text on the line. Instead use Scanner#nextLine() which gets you the whole line.
For example:
Scanner ownersname = new Scanner(System.in);
// String sownersname = ownersname.next(); // *** not this ***
String sownersname = ownersname.nextLine(); // *** but rather this ***
System.out.println(sownersname + "? That is a nice name.");
I can not release a version of my program knowing there is a GIANT glitch in the code.
Seriously, you're creating a professional application? I'm not yet at that stage, which is why I ask.
I'm wondering why, and I tried to fix it by changing ownersname.next(); to ownersname.nextLine and ownersname.next and ownersname.nextScanner and ownername.nextScanner. This is where the error comes in, when it says it can't find the variable until I change it back to it's original code, which is below.
I'd be curious to see your nextLine() method attempt, because that is the solution. Perhaps you were trying to call the method without using the method parenthesis.
I also assume that you're familiar with the Java API and have looked up the Scanner entry for it. If you did, you would see right away that there is no nextScanner() method for this class. This is one reason I have to wonder about your making a professional application at your stage. Again, I don't feel that I'm at the stage yet to create one yet, so please don't take this as an insult, just a curiosity.
I'm still new to Java and I would like to understand Strings and Arrays so I got this idea of manipulating elements and place them according to my objective. The objective is that there will be Array of Strings "ABBCCCBBAA" and the "AA","BB" must be replaced into "A" , "BA","AB" into CC. "CC","BC" into B. I basically have no idea how to make it happen but I know it must have Arrays of String. Please help
Regular expression can be very handy for you. Code bellow can do, your job with the use of regular expression:
String mainStr = "ABBCCCBBAA";
Pattern p = Pattern.compile("(AA)|(BB)|(BA)|(AB)|(CC)|(BC)");
Matcher m = p.matcher(mainStr);
while (m.find()) {
String matchedStr = m.group(0);
if("AA".equals(matchedStr) || "BB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"X");
}
else if("BA".equals(matchedStr) || "AB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Y");
}
else if("CC".equals(matchedStr) || "BC".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Z");
}
}
mainStr = mainStr.replaceAll("X","A").replaceAll("Y","CC").replaceAll("Z","B");
System.out.println(mainStr);
Above code will handle your case of multiple occurrence of same pattern in a given string like:
ABBCCCBBAABBBBAA
will generate output:
CCBBAAAAA.
I am assuming that by "array of strings" you mean:
String[] myvariable = new String[number];
myvariable[0] = "ABBCCBBAA";
myvariable[1] = "some_other_string";
If you are new to Java I suggest you read a beginner's book like Head First Java and also look into java documentation; you don't even have to go that far if you are programming with a decent IDE, like Netbeans (thanks to its intelli-sense feature) is a source of documentation for what you seek (meaning that you can look at all the methods available for a string, read what they do, and see if they can help accomplish what you need).
I am assuming (from what you have said) that you want to replace "AA" for "A", and from that result replace "BB" for "BA", and from that result replace "AB" into "CC", and from that result "BC" into "B".
The code I am posting is REAL simple, and it will only work for this particular case (as I have understood it), if you want to create a method that does this for any string, you need to change some things, but I'll leave that to you.
String[] yourArrayOfStrings = new String[1];
yourArrayOfStrings[0] = "ABBCCBBAA";
String resultOfReplacement= yourArrayOfStrings[0].replaceFirst("AA", "A");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BB", "BA");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("AB", "CC");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BC", "BB");
System.out.println(resultOfReplacement); //debugging purposes
The only reason why I created a String[] was because that's what you stated in your question, otherwise I would have simple created a String variable like I did with resultOfReplacement. To access the first element in an array you do arrayVariable[index]. Here I use the replaceFirst function that comes with Java for variables of type String. If you look the method up, it'll tell you that it will look for the first match of the first parameter and replace it with the second parameter.
The System.out.println I have added are for debugging purposes, so you can see on the console what is clearly happening with each replacement. So, the first time I call replaceFirst(...) on the original string which is a[0].
This will happen:
The method will look in "ABBCCBBAA" for the FIRST AND ONLY THE FIRST time "AA" appears and replace it with "A". The result is "return" and you must assign it to a variable if you want access to it to do more actions upon it. In this case, I assign it to a new String variable. You could have just assigned back to a[0], which is likely what you want. (You'd do so like this: a[0]=ourArrayOfStrings[0].replaceFirst("AA", "A");)
For the second replacement, the method will look in "ABBCCBBA" for the first time "BB" appears and replace it for "BA".
See the pattern? This is just a start, and depending on what you want you might need other methods like replaceAll().
Most IDEs will tell you what methods are available for a variable when you access it via ".", so that when you are typing " variablename. " right at that moment a list of methods available for it should appear, if they donĀ“t you can go ahead and do a shortcut like ctrl+space for it to appear and navigate through the methods via the arrow keys so you can read what they do (at least for Eclpise and Netbeans, while programming in Java, it works). Documentation is power!