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 5 years ago.
Improve this question
Would like to know , how to convert two nested FOR loops using java 1.8 stream .
Scenario:
variable usrAccountId - sent by User and
variable accountDetailsinRedis- actually accounts presents in database.
I am actually comparing accountId sent by user is same as accountId in the database.
This is below code , I have two nested FOR loops , I want to convert it into Java 1.8 using Stream . Anyone has any idea.
for (int usrAccountId : acctIDstoValidate) {
for (Account account : accountDetailsinRedis) {
According to your actual logic, you pass multiple ids to match.
So you could have multiple matchings.
Stream on acctIDstoValidate, then chain it with a flatMap() on accountDetailsinRedis to do the filter on the id.
Collection<Integer> acctIDstoValidate = ...;
Collection<Account> accountDetailsinRedis = ...;
List<Account> matching = acctIDstoValidate.stream()
.flatMap(idToValidate-> accountDetailsinRedis.stream()
.filter(b-> b.getId() == idToValidate))
.collect(Collectors.toList());
Can you give more detail about what are you doing inside loop?
For me, I don't what are you doing here, therefore that I just suggest You can use like this:
acctIDstoValidate.forEach(item -> {
accountDetailsinRedis.forEach({
//TODO
})
});
some thing like below code snippet
With a bot of guesswork, assuming both variables you have in your example are collections, this might be what you are after:
acctIDstoValidate.removeAll(
accountDetailsinRedis.stream()
.map(Account::getId)
.collect(Collectors.toList())
)
And you end up with invlid ids left in: acctIDstoValidate
Also note that your variable naming xan be improved, to consistently use account instead of sometimes shortening it to acct, and not capitalizing ID for better camel casing: accountIdsToValidate
Related
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.
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 details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have been preparing for technical interview. So in one thing I am just not sure. If I write for example
try {
...
} catch (InterruptedException ie) {
throw new IllegalStateException(String.format("Player [%s]: failed to reply message [%s]"), ie);
}
Does this prevent already String injection? or Do I have to write like following:
String errorMsg = String.format("Player [%s]: failed to reply message [%s]");
throw new IllegalStateException(errorMsg, ie);
There is no difference between the two snippets. Neither protects against 'string injection'.
There are only 4 non-boneheaded mitigations against string injection attacks:
Ensure that where-ever the strings end up, it is impossible for this to be a security issue in any way or form. For example, if your data is going to a binary file where all system operators are aware the contents are straight from the web, it doesn't matter what's uploaded.
Do not render the string at all. Throwing the baby out with the bathwater.
Use a whitelist. If the string consists solely of these allowed things, allow it. By default, do not allow it.
Use escapers.
Honourable mention for the concept of blacklisting: Have a list of known-malicious stuff, and allow all strings unless they contain something on the blacklist. This is bone headed and should never be used. For example, if you scan incoming data for <script>, you messed up. Don't do this. It doesn't work. Blacklists are trivially bypassed. Whitelists are what you're looking for.
The vastly most common strategy is the 4th: Escapers. For example, when you have a web server that takes in a username and a user's telephone number and a user's full name, and then renders all this information back out on their public website, then:
The phone number should be mitigated using the whitelist strategy. A single +, digits in the range 0-9, spaces, dashes, and nothing else. If that's what the input is like, allow it. Otherwise don't.
The user's real name should be mitigated with escaping: Take the data as provided and inject it verbatim into your database, but treat this data as tainted in all interactions with that data: For example, when rendering that public page, the 'full name' string needs to be washed through an HTML escaper which e.g. replaces all < with <.
Your code doesn't do any of these 4 things (either version of it).
In general it is an extremely bad idea to consider the string returned by an exception's .getMessage() to be already 'safe' (escaped / passed the whitelist verifier). Instead, the code that invokes .getMessage() needs to apply one of the 4 mitigations as explained above.
This question already has an answer here:
When to use CoProcess Function in Flink?
(1 answer)
Closed 2 years ago.
let's say that I have a function that process a DataStream<X> and sent the return to DB, but I need to read from another source and when process this new DataStream I will need to find into the states that I could generate before store the DataStream<X> into the DB and find one Id that it is coming into the DataStream<Y> and then trigger an action.
My question is:
Is possible by using for example a Co-ProcessFunction in Flink to process the result of the transformation in DataStream<X> and creates the states there and at the same time process the DataStream<Y> to have the states and the new stream in the same operator?
if the first question is totally wrong, which could be possible, Is there anyhow to do what I need to do?
Hoping someone can understands what I need to do.
This is the graphic idea of what I need to do.
Yes, it is possible to connect two streams of different types, and process them together using shared state.
In order to connect Stream<X> with Stream<Y>, and to have them share state, you will have to define key selector functions that return equivalent keys for both streams. (Just as in SQL, where in order to join two tables, you have to describe how they can be joined.)
In this pseudocode, anotherFlinkFunction is a RichCoFlatMapFunction. I've assumed that both streams have an id field that has the same value when items from stream X and stream Y should be combined.
x = env.addSource(...);
xTransformed = x.flatMap(...);
xTransformed.addSink(DB);
y = env.addSource(...);
z = xTransformed
.connect(y)
.keyBy(xt->xt.id, y->y.id)
.flatMap(new anotherFlinkFunction());
z.addSink(...);
You'll find related examples in the Apache Flink training tutorials at https://ci.apache.org/projects/flink/flink-docs-stable/learn-flink/etl.html#example and in the accompanying exercise at https://github.com/apache/flink-training/tree/master/rides-and-fares.
Full answer here:
Strem<X> streamX = fromSource();
Strem<Y> streamY = fromSource();
ConnectedStreams<X, Y> connectedStreams = streamX.connect(streamY).keyBy(x-> x.id, y-> y.id);
/*JoinStreamsFunction will receive X and Y and get Z as output*/
SingleOutputStreamOperator<Z> out = connectedStreams.flatMap(new JoinStreamsFunction());
out.addSink(new SinkFunctionHere());
I'm trying to create a multiple choice game with 4 possible answers for each question.
During the main part of the game the player will be asked a question and will be prompted to input an answer.
In my code, along with the question and answer String, I will somehow need to be able to tell which is the correct answer and maybe even flag the question so as to not be repeated in later rounds. Also the possible answers need to be in randomized/different order between "playthroughs".
I'm trying to figure out what data structure to use to store all of the above, as to be able to write the code appropriately.
My first choice would be to have a main Hashmap<String, HashMap> and a second HashMap<String, Boolean>* that is stored into the first one. The first map will store the question strings as keys and the second HashMap(s) as values. The second HashMap will store the answers as keys and a boolean for each key, indicating which one is the correct answer, as value.
Kind of complicated but at least in theory it seems to work, although I still don't have a way to mark a question as "already asked".
My second choice would be a two dimensional array whose lines will represent a question, the 0 column being the question Strings, the 1,2,3,4 columns storing the answer strings, the 5 column storing the correct answer string, and maybe have a 7th column (6) storing a flag, marking if the question hasn't been asked already.
Although simpler in theory I fear this method would be really confusing to actually code with.
If there are better/easier ways to do this please tell me and maybe even elaborate on their benefits.
Java is an Object-Oriented language. You should use it.
Example: Create a class representing a question and the possible answers.
public class Question {
private String question;
private String correctAnswer;
private List<String> answerList;
}
Now, you can create a good useful constructor, where you give the question first, then all the answers using varargs, with the correct answer first:
new Question("How satisfied are you with this answer?",
"Extremely satisfied",
"Very satisfied",
"Somewhat satisfied",
"Not so satisfied");
Your constructor could then build the answers list and call Collections.shuffle(this.answers) to randomize them.
You then add all the questions to a List<Question> and call shuffle on that, so questions will be asked in random order, and only once.
Since this is all theoretical, you should consider using objects.
Make a Question class. Having it store your question strings along with an answer string.
You could store as many question strings as you want, say in an array. The answer could just be an integer representing the index of the correct answer.
As far as Hashmaps are concerned, you can use them, if you want to store unique ID values to each question, and look them up, but that's not really necessary.
You can store these Question objects in an Arraylist, add freely shuffle and iterate over them