Use substring for every element of Hashtable JSP - java

I'm working on my first project in JSP. I have a istance of Hashtable (hParamsRecherche) that get some values from a form.
I have to substring every element of this Hashtable :
hParamsRecherche.get("INVERSE_GEO").toString()
That contains values like:
'95','14','300','165'
I have to substring all the element that have a length bigger than 2 char, et take the first two number.
'95','14','30','16'
I think that i have to do this with a loop, but i m open to others suggestions ! Thank you !

If you want to process all strings in way that they are at most 2 digits long, you can use the following approach.
It uses streams instead of a loop, which is more elegant solution, because it uses less lines of code to solve the same problem as a loop, without sacrificing code readability.
// ... contains a list like '95','764', etc ..
// getListOfStrings() is the method, which wraps hParamsRecherche.get
var stringsToCut = getListOfString()
// The result variable now contains the list of strings, which are at most 2 digits long
var result = stringsToCut.stream
.map(s -> s.length() <= 2 ? s :s.substring(0,2))
.collect(Collectors.toList())

Related

Count elements in array

I am trying to count an element in an array of objects.
long number = Stream.of(jobTitle).count();
System.out.println("There are " + number + " employees.");
What happens is that it will print out the message as many times as many employees have the same job title. Yet "number" stays always 1.
Any guiding would be much appreciated.
long number = Stream.of(jobTitle).count();
Counts the elements in a stream that contains one element.
It is not surprising that this operation always ends up with the exact same result.
Your code is equivalent to:
List<Whatever> titels = new ArrayList<>();
titels.put(oneEntry);
... print titels.size()
Long story short: that statement is nonsensical. What you probably meant was:
if (arbetstitel.equalsIgnoreCase(jobCount)){
g++;
or something alikw. Of course g is a rather bad name for a counter.
But the real answer here is: step back. Think what the problem is you intend to solve, and what the elements are you need to look at. The code you are showing here is simply not making (much) sense. I can't tell you how to fix it, because, as said: it is not clear what you try to achieve here.
A streamish way of counting:
long usersWithMatchingTitle = Arrays.stream(employees).filter(e -> e.getJobTitle().equalsIgnoreCase(jobTitleFromUser)).count();
Meaning: instead of manually iterating your array, you can turn the whole array into a stream, and then filter/count whatever you want to.
Please note: your code seems to only care about the first 30 elements in that array. If that is really what you want, you will need ...stream(employees).limit(30)...
You need to change the stream of command to define a proper Predicate for filter option.
Stream.of(employees).filter(e -> e.getJobTitle().equals(jobTitle)).count();

about java recursion to create combination of string

The question was asking me to return set containing all the possible combination of strings made up of "cc" and "ddd" for given length n.
so for example if the length given was 5 then set would include "ccddd" and "dddcc".
and length 6 would return set containing "cccccc","dddddd"
and length 7 would return set contating "ccdddcc","dddcccc","ccccddd"
and length 12 will return 12 different combination and so on
However, set returned is empty.
Can you please help?
"Please understand extremeply poor coding style"
public static Set<String> set = new HashSet<String>();
public static Set<String> generateset(int n) {
String s = strings(n,n,"");
return set; // change this
}
public static String strings(int n,int size, String s){
if(n == 3){
s = s + ("cc");
return "";}
if(n == 2){
s = s + ("ddd");
return "";}
if(s.length() == size)
set.add(s);
return strings(n-3,size,s) + strings(n-2,size,s);
}
I think you'll need to rethink your approach. This is not an easy problem, so if you're extremely new to Java (and not extremely familiar with other programming languages), you may want to try some easier problems involving sets, lists, or other collections, before you tackle something like this.
Assuming you want to try it anyway: recursive problems like this require very clear thinking about how you want to accomplish the task. I think you have a general idea, but it needs to be much clearer. Here's how I would approach the problem:
(1) You want a method that returns a list (or set) of strings of length N. Your recursive method returns a single String, and as far as I can tell, you don't have a clear definition of what the resulting string is. (Clear definitions are very important in programming, but probably even more so when solving a complex recursive problem.)
(2) The strings will either begin with "cc" or "ddd". Thus, to form your resulting list, you need to:
(2a) Find all strings of length N-2. This is where you need a recursive call to get all strings of that length. Go through all strings in that list, and add "cc" to the front of each string.
(2b) Similarly, find all strings of length N-3 with a recursive call; go through all the strings in that list, and add "ddd" to the front.
(2c) The resulting list will be all the strings from steps (2a) and (2b).
(3) You need base cases. If N is 0 or 1, the resulting list will be empty. If N==2, it will have just one string, "cc"; if N==3, it will have just one string, "ddd".
You can use a Set instead of a list if you want, since the order won't matter.
Note that it's a bad idea to use a global list or set to hold the results. When a method is calling itself recursively, and every invocation of the method touches the same list or set, you will go insane trying to get everything to work. It's much easier if you let each recursive invocation hold its own local list with the results. Edit: This needs to be clarified. Using a global (i.e. instance field that is shared by all recursive invocations) collection to hold the final results is OK. But the approach I've outlined above involves a lot of intermediate results--i.e. if you want to find all strings whose length is 8, you will also be finding strings whose length is 6, 5, 4, ...; using a global to hold all of those would be painful.
The answer to why set is returned empty is simply follow the logic. Say you execute generateset(5); which will execute strings(5,5,"");:
First iteration strings(5,5,""); : (s.length() == size) is false hence nothing added to set
Second iteration strings(2,5,""); : (n == 2) is true, hence nothing added to set
Third iteration strings(3,5,""); : (n == 3) is true, hence nothing added
to set
So set remains un changed.

iteration of a dictionary in java

I have a big amount of data that I have saved in interfaces (55 to be exact). combined they contain almost 170000 strings in string arrays.
What I want to do is match the input element to the strings in given interface and return all the elements that match the pattern of the input element.
I have saved the elements in string arrays eg.
String[] array = {"element 1", "element 2".....};
for every input I have to iterate the string array whole in order to find all the matching elements in the list.
I am currently doing this:
for(int innerIterator = 0; innerIterator < dictionaryArrayLength; innerIterator++){
if (dictionaryArray[innerIterator].matches(""+input[iterator]+"\\D*")) {
matchedWordList.add(dictionaryArray[innerIterator]);
}
}
as the length of the array is in thousands so its taking a bit of time to answer.
I would like this code to perform better. I am currently thinking to change the data structure I have used for the dictionaries. But is there any better way to iterate through the list and find all the matching elements
If you are using Java 8 you could try with the new Stream api:
Pattern inputPatter = Pattern.compile(input[iterator] + "\\D*");
List<String> matchingWords = Arrays.stream(dictionaryArray).parallel()
.filter(word -> inputPatter.matcher(word).matches()).collect(Collectors.toList());
matchedWordList.addAll(matchingWords);
With the first line (Pattern inputPatter = Pattern.compile(input[iterator] + "\\D*");) you avoid
The creation of the regex string at every cycle iteration
The creation of the relative Pattern object at every iteration (see the source code of String.matches)
With Arrays.stream you create a stream from an array.
With .parallel you parallelize the stream in order to distribute the following operations among multiple threads (with huge sets of data it can improve performances considerably).
With .filter(word -> inputPatter.matcher(word).matches()) you select only the words matching your pattern.
With .collect(Collectors.toList()) you collect your results in a list.

How do you recursively replace occurences of a string in an array

So consider a class A with two String variables "name" and "value"
class B contains a variable which is Set of A
Set<A> allVariables
is a set that would look like this
A.name="$var1"
A.value = "x+10>2"
A.name="$var2"
A.value="11+y%10==0"
A.name="$var3"
A.value="$var1 && $var2"
What I need to do is evaluate these expressions. I'm using jexl for this. I need to iterate through the Set and replace these variable names with their respective values.
In this case, the object with name $var3 needs to be replaced with "x+10>2 && 11+y%10==0"
How do I do this?
You create 2 Hashmap, translated and toTranslate.
You parse your Set.
For each A in your Set, you look at value. If value contains any number of $element (started by $ sign), you look for this $element in your translated Hashmap keys.
If it's in there, you replace the occurrences of $element by the value found in your translated hashmap.
You do this for each different $element you found in your A object.
If all $element have been translated, you add your object A into the translated hashmap (key = name, value = value).
Else, you add it to your toTranslate hashmap.
Once all your Set has been parsed, you've got 2 hashmaps.
You create a while loop: while toTranslate hashmap is not empty, you take each value, and try to translate the $element within it by the ones in your translate hashmap.
Be careful, you may end with an infinite loop. One good thing to do would be to make sure that each time you loop on the toTranslate hashmap, the numbers of its elements is reduced. If not you're in an infinite loop.
I don't think it needs to be recursive. I think just this would work:
bool madeReplacement;
do:
bool madeReplacement = false
For each member of the set, X:
For each other member of the set, Y:
Replace all instances of Y.name with Y.value in X.value. If you replaced anything, madeReplacement = true.
while (madeReplacement)
Example:
$var1 is value 1
$var2 is value $var1
$var3 is value $var2 + 2
$var3.value contains $var2, replace $var2 with $var1 -> $var1 + 2
$var2.value contains $var1, replace $var1 with 1 -> 1
$var3.value contains $var1, replace $var1 with 1 -> 1 + 2
No value contains any other name, execution finished.
Even though we 'evaluated out of order' we eventually got the right answer anyway. However, this algorithm can be O(n^3) in the worst case (imagine if you had n variables that referenced each other in a long chain, and you started the replacement on the wrong end). One way to solve this would be to, when you X.value contains Y.name, first evaluate Y.value recursively (by doing the same loop-over-the-rest-of-the-set). This makes it O(n^2) worst case, so your suspicion that a recursive approach is appropriate may be correct ;)
(I wasn't sure if variable names were guaranteed to start with $, so I wrote it so it would not matter)

Help me understand question related to HashMap in Java

Im given a task which i am a little confused to understand. Here is the question statement:
The following program should read a file and store all its tokens in a member variable.
Your task is to write a single method that returns the number of items in tokenMap, the average length (as double value) of the elements in tokenMap, and the number of tokens starting with character "a".
Here the tokenMap is an object of type HashMap<String, Integer>;
I do have some idea about HashMap but what i want to know the "key value" for HashMap required is a single character or the whole word?? that i should store in tokenMap.
Also how can i compute the average length?
Looks like you have to use the entire word as the key.
The average length of tokens can be computed by summing the lengths of each token and dividing by the number of tokens.
In Java, you can find the number of tokens in the HashMap by tokenMap.size().
You can write loops that visit each member of the map like this:
for(String t: tokenMap.values()){
//t is a token
}
and if you look up String in the Java API docs you will see that it is easy to find the length of a String.
To compute the average length of the items in a hash map, you'll have to iterate over them all and count the length and calculate the average.
As for your other question about what to use for a key, how are we supposed to know? A hashmap can use practically any* value for a key.
*The value must be hashable, which is defined differently for different languages.
Reading the question closely, it seems that you have to read a file, extract each word and use it as the key value, and store the length of each key as the integer:
an example line
leads to a HashMap like this
an : 2
example : 7
line : 4
After you've built your map (made of keys mapping to entries, or seemingly elements in the question), you'll need to run some statistics over it to find
the number of keys (look at HashMap)
the average length of all keys (again, simple enough)
the number beginning with "a" (just look at the String)
Then make a value object containing these values and return it from the method that does the statistics.
I know I've given more information that you require, but someone else may benefit from a little extra help.
Guys there is some confusion. Im not asking for a solution. Im just confused for one thing.
For the time being, im gonna use String type as the key type.
The only confusion i have is once i read the file line by line, should i split it based upon words or based upon each character. So that the key value should be a single character type string or a String of whole word.
If you can go through the question statement, what do you suggest. That's all im asking.
should i split it based upon words or
based upon each character
The requirement is to make tokens, so you should split them based on words. Each word becomes a unique String key. It would make sense for the value to be the count of each token.
If the file you are reading has these three lines:
int alpha;
int beta;
float delta;
Then you should have something like
<"int", 2>
<";", 3>
<"alpha", 1>
<"beta", 1>
<"float", 1>
<"delta", 1>
(The semicolon may or may not be considered a token.)
Your average length would be ( 3x2 + 3x1 + 5 + 4 + 5 + 5) / 6.
Your length of tokens starting with "a" would be 5.0.
Look elsewhere on this forum for keySet and you should be good to go.

Categories