Map entry key in java - java

I'm trying to debug a problem I've on a script, I'm newly to Java I think it's a simplest thing but I need to understand. This :
for( Map.Entry<String,int[]> entry : this.indexMap.entrySet())
{
if( !entry.getKey().equals("nickname"))
{
System.out.print("'"+ entry.getKey() +"' contains "+ entry.getKey().length() +" chars");
System.out.print("'"+ name +"' contains "+ name.length() +" chars");
}
else if( entry.getKey().trim().equals("nickname") )
{
System.out.print("Yes are sames");
}
}
For a String name = "nickname", displays me that :
18:56:15 [INFOS] 'nickname' contains 94 chars
18:56:15 [INFOS] 'nickname' contains 8 chars
I'm trying to understand this.
The problem is entry.getKey() returns the same thing as my string name, but not really the same. In first test, we saw the two vars are different, so the print is did, but the twos vars have the same value, and not the same length. In the else-if, I tried to remove spaces but not printed so where are from these 94 chars?
https://code.google.com/p/imdbparsers/source/browse/trunk/imdb+parsers/src/imdb/parsers/xmltosql/NamedParameterStatement.java?r=6
Is the code, methods concerned are
private String parse(String query)
private int[] getIndexes(String name)
line 161 et 89
This for loop i've in mine is only to debug the
int[] indexes = (int[]) indexMap.get(name);
Returns always null
The query string is :
SELECT COUNT(`account_id`) AS `total` FROM `game_accounts` WHERE `nickname`=:nickname

The difference between
entry.getKey().equals("nickname")
and
entry.getKey().trim().equals("nickname")
is trim().
The first take in account the spaces and the second not.
It's because they are a loop on a map: to find the 'bad' keys...

I think that if you reverse your if clauses you might get something that behaves more like what you are expecting, although it is somewhat unclear what you are asking. Comparing keys as the first clause in the if block makes the code simpler.
if( entry.getKey().trim().equals("nickname") )
{
System.out.print("Yes are sames");
}
else
{
System.out.print("'"+ entry.getKey() +"' contains "+ entry.getKey().length() +" chars");
System.out.print("'"+ name +"' contains "+ name.length() +" chars");
}

Related

Map with optional variables as Keys and multiple if elseif condition

Need your help because I'm overthinking a bit. :P
I'm doing a development in apex where we build a Map based on certain keys. Those keys are a mix of multiple variables and so when building a map we have something like:
for(rule){
key = String.isBlank(rule.CompanyRisk) ? '' : rule.CompanyRisk;
key += String.isBlank(rule.PriceType) ? '' : rule.PriceType;
key += String.isBlank(rule.Product) ? '' : rule.Product;
key += String.isBlank(rule.CompanySize) ? '' : rule.CompanySize;
//..
map.put(Key, rule.Value);
}
return map;
//and later to get the correct value
for(offerRecord){
String accRisk = offerRecord.CompanyRisk;
String price = offerRecord.PriceType;
String product= offerRecord.Product;
String accSize = offerRecord.CompanySize;
if(map.contains(accRisk + price + product + accSize)){
key = accRisk + price + product + accSize;
}else if(map.contains( accRisk + price + product + '')){
key = accRisk + price + product + '';
}else if(map.contains(accRisk + price + '' + accSize)){
key = accRisk + price + '' + accSize,
}else if.. //16 conditions now (4 variables as optional)
}
return map.get(key);
Issue:
Some fields on the key are optional and that happens so the users dont need to create all the rules for all the combinatorions. and when those optional fields are empty/null it's because it applies for all values of the field.
Example: We can have a rule as (LowRisk + Indexed + Computer + Small) with Value=4 and a rule for (Low + Indexed + Computer + '' ) with Value=5 , meaning if the company is small applies the 1st rule but if it it's medium/big/top it applies the one without. Same for the other fields. I can have just one saying (HighRisk + + +) with a value of 0 without the need of specifying all the other criteriums and it applies for all of them.
Because we need to always checking first rules/keys with the optional fields filled, it will become a mess due to a lot of if else.
The conditions are like (ABCD, ABC, ABD, AB, ACD, AC, AD, A, BCD, BC, BD, B, CD, C, D ,'' )
Is there any better solution that could improve this?
I was trying now building some Wrapper class that would return a List for the all combinations and then have a specific method getRuleForRecord() which based on the List (ordered) creates a key from the values of record and checks if map has that key. Not a much prettier aproach. The worst now is building the listOfCombinations on the order I want
List<String> keyList = singleton.listOfCombinations;
for (String fieldList : keyList) {
String mapKey = '';
for (String field : fieldList.split('_')) {
mapKey += recordToGetInfoFrom.get(field);
}
if (singleton.ruleMap.containsKey(mapKey)) {
return singleton.remRules.get(mapKey);
}
}

Printing out a TreeMap<String, TreeSet<String>> Key and Mapped Values

I have a TreeMap <String, TreeSet <String>>
{Heat = [Bosh, Lebron, Wade], Nets =[DWill, KG], Sonics = null, Warriors = [Curry,Iggy,Thompson]}
and I want to print out.
Heat Bosh Lebron Wade
Nets DWill KG
Sonics
Warriors Curry Iggy Thompson
I've tried
for ( String w : listNBA){
System.out.print( w + " ");
if (treemap.containsKey(w))
System.out.println(treemap.get(w));
else
System.out.println( "" ); // print nothing if team doesn't exist
But this isn't quite right either, and it's output is...
Heat [Bosh, Lebron, Wade]
Nets [DWill, KG]
Sonics null
Warriors [Curry,Iggy,Thompson]
So, my question is: Is there any easy way to convert a TreeSet to a String in my print method?
You can do something like this :
StringBuilder stringBuilder = new StringBuilder();
for (Entry<String, TreeSet<String>> mapEntry : treemap.entrySet()) {
stringBuilder.append(mapEntry.getKey());
if (mapEntry.getValue() != null) {
for (String setEntry : mapEntry.getValue()) {
stringBuilder.append(" ").append(setEntry);
}
}
stringBuilder.append("\n");
}
System.out.println(stringBuilder.toString());
Java 8 has a String.join method that works great for this:
for ( String w : listNBA){
System.out.print( w + " ");
if (treemap.containsKey(w) && treemap.get(w) != null)
System.out.println(String.join(" ",treemap.get(w)));
else
System.out.println( "" ); // print nothing if team doesn't exist
}
Note that while your original System.out.println(treemap.get(w)) printed out null if the get method returned null, String.join will throw a NullPointerException if it gets a null parameter. Thus, I've added a null check to the previous if.
join's first parameter is a string that will be inserted between each input string. It can either take a variable number of String (or any other CharSequence) arguments, or an array of String (or other CharSequence).
You can iterate through the entry set and print out the key and the corresponsing value.
for(Map.Entry<String, TreeSet <String>> entry : treemap.entrySet())
{
System.out.print( entry.getKey() + " ");
System.out.print( entry.getValue());
}

Replacing certain characters in java

I have a SQL query passed to me in a text, here is a part of it:
WHERE
(t.STIME > CAST(SYSTIMESTAMP AS TIMESTAMP) + NUMTODSINTERVAL(-86400000 * 0.001, 'SECOND'))
) t ORDER BY
m_2 ASC, m_1 ASC, t.STIME ASC
What I want to do, is to simply modify it in a way that I will have:
WHERE
(t.STIME > CAST(SYSTIMESTAMP AS TIMESTAMP) + NUMTODSINTERVAL(-86400000 * 0.001, 'SECOND'))
ORDER BY
m_2 ASC, m_1 ASC, t.STIME ASC )
So, I need to somehow remove: ") t" from within the String, but how to do that? I always receive "unmatched ')' parenthesis and I really don't know why x/
Here is a method I wrote for replacing this string:
public static String replaceLast(String string, String toReplace, String replaceWith) {
int last = string.lastIndexOf(toReplace);
if (last < 0) return string;
String ending = string.substring(last).replaceFirst(toReplace, replaceWith);
return string.substring(0, last) + tail;
}
then I'm trying to use it this way:
if(sqlToTrim.lastIndexOf("\\) t") > 0){
replaceLast(sqlToTrim, "\\) t ", " ");
addLastParanthesis(sqlToTrim);
}
But it is not replaced, basicly nothing changes - replaceLast is never used. I assume I messed up with regex, I searched through stack overflow but it seems \ is the right combination that I should put before ). Thanks in advance for your help. Could anyone tell me what am I doing wrong?
If you need to know, why do I do that, why in this way - legacy code...
Strings are immutable. replaceLast(sqlToTrim, "\\) t ", " "); returns a new string. Do:
sqlToTrim = replaceLast(sqlToTrim, "\\) t ", " ");
and continue on from there. If addLastParenthesis modifies the string it should return it, i.e.
sqlToTrim = replaceLast(sqlToTrim, "\\) t ", " ");
sqlToTrim = addLastparenthesis(sqlToTrim);

In Java, how to find a string from an string array and why is the below example not working as expected

how to find a string from an string array and In the below example i am always get search failure except search for first string but not others like second or third , i even tried with [indexof !=1 condition instead of equals ] but it remains same result and why ? - please advise . Thanks
My Example :
String[] TEXT_ARRAY = {"first","second","third" };
String parameter ="second";
for (String string : TEXT_ARRAY) {
System.out.println("****** [containsScript ? ] IS EQUALS ? " + parameter.toString().toUpperCase().equals(string.toString().toUpperCase()));
}
Your script works as expected, printing:
[containsScript ? ] IS EQUALS ? false
[containsScript ? ] IS EQUALS ? true
[containsScript ? ] IS EQUALS ? false
You have lots of redundant code though, your condition could be rewritten as:
System.out.println("****** [containsScript ? ] IS EQUALS ? " + parameter.equalsIgnoreCase(string));
Also, what exactly do you need to achieve? If you want to test if a given String exists in a set of Strings, then I would advise using a Set, instead of an array and iterating over it every time you need to do that check.
Your example works for me. The result will be
false
true
false
Note: I think toString() method is not necessary here.
Maybe it will help you. I wrote this method for searching user's name in the string array.
public static void poisk(String serchingname, String... names) {
for (int i = 0; i < names.length; i++) {
boolean notfound = false;
if (serchingname.equals(names[i])) {
System.out.println("User with name " + serchingname + " is found");
break;
}
while (i==names.length-1) {
if (serchingname.equals(names[names.length - 1]) == notfound) {
System.out.println("User with name " + serchingname + " is not found");
break;
Strings are actually immutable. If you have two strings that have the same content then they will be the same Object due to String interning.
So you should be able to do:
parameter.equals(string)
For your search, if it makes it easier you could do:
Arrays.asList(TEXT_ARRAY).contains(parameter)
That would work exactly the same as your loop.
Change the System.out to
System.out.println("** [containsScript ? ] IS EQUALS ? " +( parameter.toString().toUpperCase().equals(string.toString().toUpperCase())));

program to determine number of duplicates in a sentence

Code:public class duplicate
{
public static void main(String[] args)throws IOException
{
System.out.println("Enter words separated by spaces ('.' to quit):");
Set<String> s = new HashSet<String>();
Scanner input = new Scanner(System.in);
while (true)
{
String token = input.next();
if (".".equals(token))
break;
if (!s.add(token))
System.out.println("Duplicate detected: " + token);
}
System.out.println(s.size() + " distinct words:\n" + s);
Set<String> duplicatesnum = new HashSet<String>();
String token = input.next();
if (!s.add(token))
{
duplicatesnum.add(token);
System.out.println("Duplicate detected: " + token);
}
System.out.println(duplicatesnum.size());
}
}
the output is:
Enter words separated by spaces ('.' to quit):
one two one two .
Duplicate detected: one
Duplicate detected: two
2 distinct words:
[two, one]
I assume you want to know the number of different duplicate words. You can use another HashSet<String> for the duplicates.
//Outside the loop
Set<String> duplicates = new HashSet<String>();
//Inside the loop
if (!s.add(token))
{
duplicates.add(token);
System.out.println("Duplicate detected: " + token);
}
//Outside the loop
System.out.println(duplicates.size());
Also if you care for the occurences of each word declare a HashMap<String, Integer> as in others posts is mentioned.
But if you want the number of all duplicate words(not different) just declare a counter:
//Outside the loop
int duplicates = 0;
//Inside the loop
if (!s.add(token))
{
duplicates++;
System.out.println("Duplicate detected: " + token);
}
//Outside the loop
System.out.println(duplicates);
Instead of a HashSet, use a HashMap. A HashSet only stores the values. A HashMap maps a value to another value (see http://www.geekinterview.com/question_details/47545 for an explanation)
In your case, the key of the HashMap is your string (just as the key of the HashSet is the string). The value in the HashMap is the number of times you encountered this string.
When you find a new string, add it to the HashMap, and set the value of the entry to zero.
When you encounter the same string later, increment the value in the HashMap.
Because you are using a HashSet, you will not know how many duplicates you have. If you went with a HashMap<String, Integer>, you could increment whenever you found that your key was != null.
In the if (!s.add(token)), you can increment a counter and then display it's value at the end.
Your question is a bit misleading. Some people understand that you want:
Input: hello man, hello woman, say good by to your man.
Output:
Found duplicate: Hello
Found duplicate: Man
Duplicate count: 2
Others understood you wanted:
Input: hello man, hello woman, say hello to your man.
Output:
Found duplicate: Hello - 3 appearances
Found duplicate: Man - 2 appearances
Assuming you want the 1st option - go with Petar Minchev's solution
Assuming you want the 2nd option - go with Patrick's solution. Don't forget that when you use an Integer in a Map, you can get/put int as well, and Java will Automatically Box/Unbox it for you, but if you rely on this - you can get NPEs when asking the map for a key that does not exist:
Map<String,Integer> myMap = new HashMap<String,Integer>();
myMap.get("key that does not exist"); // NPE here <---
The NPE is caused since the return value from 'get' is null, and that value is being cast into an Integer after which the intValue() method will be invoked - thus triggering an NPE.
You can use Google collections library:
Multiset<String> words = HashMultiset.create();
while (true) {
String token = input.next();
if (".".equals(token))
break;
if (!words.add(token))
System.out.println("Duplicate detected: " + token);
}
System.out.println(words.elementSet().size() + " distinct words:\n" + words.elementSet());
Collection<Entry<String>> duplicateWords = Collections2.filter(words.entrySet(), new Predicate<Entry<String>>() {
public boolean apply(Entry<String> entry) {
return entry.getCount() > 1;
}
});
System.out.println("There are " + duplicateWords.size() + " duplicate words.");
System.out.println("The duplicate words are: " + Joiner.on(", ").join(duplicateWords));
Example of output:
Enter words separated by spaces ('.' to quit):
aaa bbb aaa ccc aaa bbb .
3 distinct words:
[aaa, ccc, bbb]
There are 2 duplicate words.
The duplicate words are: aaa x 3, bbb x 2

Categories