Finding and replacing a value in HashMap? - java

I wrote a HashMap with the key as a String and the value as a LinkedList of Strings.
I want to write a method that consumes the key which is a string and value. Then I want find the key in the HashMap that match the given key then add the given String to the List of the Strings.
**thank guys but there is another error.
in this line "Likes.put(s,Likes.get(s).add(fav)); ." it says :
Error: no suitable method found for put(java.lang.String,boolean)
method java.util.HashMap.put(java.lang.String,java.util.LinkedList<java.lang.String>) is not applicable
(actual argument boolean cannot be converted to java.util.LinkedList<java.lang.String> by method invocation conversion)
method java.util.AbstractMap.put(java.lang.String,java.util.LinkedList<java.lang.String>) is not applicable
(actual argument boolean cannot be converted to java.util.LinkedList<java.lang.String> by method invocation conversion)
I can't tell why it says "the actual argument is Boolean"! I want to insert a LinkedList no a boolean
class Recomnder {
Recomnder(){
Likes.put("tom",new LinkedList() );
Recomnder.addLikes("tom","movie tovi");
}
HashMap<String,LinkedList<String>> Likes = new HashMap<String,LinkedList<String>>();
void addLikes (String name, String fav){
for (String s : Likes.keySet()) {
if (s.equals(name))
Likes.put(s,Likes.get(s).add(fav));
}
}
}

The problem is in this statement:
Recomnder.addLikes("tom","movie tovi");
That way you are telling the compiler that you want to access addLikes as a static method. However it is not defined as a static method. You can only call addLikes on an instance of Recomnder. So if you change it to:
addLikes("tom","movie tovi");
it should work.
btw. try adhering to Java naming conventions. Get used to always start instance variable names with a small case letter (e.g. likes instead of Likes). That way you spot such a mistake much easier.

Instance methods need to be called from an instance. Your addLikes method is an instance method (it doesn't have the modifier static). You need to create an instance of the class before you can call the method on it.

Apart from changing your method to static. Change the following statement.
Before
Likes.put(s,Likes.get(s).add(fav));
After
Likes.get(s).add(fav);
In the above code, Likes.get(s).add(fav) return boolean and this return value is being added to the Map. Hence the compiler giving the error.
Just adding the String to the Likes.get(s) will do the trick as java works on references. This will work as expected.

Related

Unable to send instance variable value to a sendkeys() method

Now I have a String variable declared as an instance variable, I'm defining the value to the variable inside a method, but when I try to use the value of the same variable inside another method I get this error:
Keys to send should be a not null CharSequence
Now I cannot event set the return type of first method as String because that method accepts an argument hence that is of no use.
This is my code:
String data;
#Keyword
def getFirstRecord(TestObject listData)
{
List<WebElement> firstRecord = WebUiCommonHelper.findWebElements(listData, 20);
data = firstRecord.get(0).getText();
}
#Keyword
def setSearchData(TestObject obj)
{
WebElement txtSearchBox = WebUiCommonHelper.findWebElement(obj, 20);
txtSearchBox.sendKeys(data);
}
I dont have the reputation to comment so Answering here with possibilities.
Please check below cases for your code to see if these things resolve the issue
Case 1) As mentioned by Nandan A in the comments, check if the method 2 is getting called before method 1.
--> If this is the case then please check your configuraiton for test cases and see why this is happening.
Case 2) If the method 2 is getting called after method 1 as expected by your code.
--> Then as per your coment replied I can see in method 2 the String value is still null. And hence it is possible that this framework is creating new instance of your class for executing your #Keyword implementations everytime. You can solve this in few different ways.
One easiest way to try is make your String variable as static. This way, the value will remain same for all instances, as the static variables are stored on the class level instead of instance level in Java.
Another one can be : from first method write the value in to a properties file, and from the second method read the same properties file and the same key's value.
Let me know if this helps you.

How to pass parameter in Supplier function with method reference operator(::)

Sorry, it seems to be very basic in functional programming but I am not getting this idea. Actually I have a method in my code which consumes a method and another param as a parameter.
private <R> CompletableFuture<R> retryRequest(Supplier<CompletableFuture<R>> supplier, int maxRetries)
I want to call this function and pass another method(anOtherMethod) which taking one integer parameter:
CompletableFuture<Boolean> retry = this.retryRequest(this:: anOtherMethod, 2);
Not getting this how I can call this retryRequest and give anOtherMethod(123)?
I know it can work like this:
CompletableFuture<Boolean> retry = this.retryRequest(()-> anOtherMethod(123), 2);
You cannot instantiate a lambda with a specific captured value like 123 in the pure method reference variant.. You need to write the explicit lambda version with arrow, if you want to pass captured values other than the instance to execute the method on. Read more on capturing values in lambdas in this answer: Enhanced 'for' loop and lambda expressions
The only exception is an object, which itself becomes the first parameter.
Assume a signature that expects a Consumer of a String:
public void something(Consumer<String> job) {
...
The above signature will enable you to write the following calls:
String myString = " Hey Jack ";
something(myString::trim);
something(s -> s.trim());
Both do the same, and this is maybe unintuitive, because one takes an argument (the instance reference myString) and one seem not to (but it actually does, too). This works, because the compiler tries two possible resolutions for a lambda method reference (the above version with ::). On one hand, the compiler can apply signatures, as if the called method did not have any parameters, and none need passing. This is the case for myString.trim. But the compiler will also check, whether there is a static method String.trim(myString) (which luckiely there is not). If you wanted to call a static method without any parameters, then you'd have to call the class identifier with the function reference like so:
something(String::trim); // this version of trim does not exist.
This is sometimes even a problem, because if a class offers a static version of a method and an instance-related one, you get ambiguity:
public void somethingElse(Function<Integer, String> transformation) {...}
// This will not compile:
somethingElse(Integer::toString);
The above example will not compile, because the toString method exists twice, once as static Integer.toString(someInt) and once as instance related someInteger.toString().

Using method references on a instance to be determined at runtime in Java

I was testing out rules of using method references, but the code I wrote would not compile. The compiler keeps giving telling me that I cannot reference a non-static method from a static context. However, in the Java Documents it explicitly wrote that it is possible to use "::" to "reference to an instance method of an arbitrary object of a particular type". Can anyone point out what's wrong with my code? Thank you!
package Test;
import java.util.function.BiPredicate;
class Evaluation {
public boolean evaluate(int a, int b) {
if (a-b ==5){
return true ;
}
return false;
}
public void methodTest() {
BiPredicate<Integer, Integer> biPredicate = Evaluation::evaluate;
System.out.println(biPredicate.test(6,1));
}
}
Edit: After reading the answers, I was wondering if it is the case that referencing an instance method by the class name only works in some functional interfaces but not in other ones? For instance,
BiPredicate <String, Integer> biPredicate = String::startsWith;
doesn't compile, while:
Predicate <String> predicate = String::isEmpty;
compiles.
If this is the case, is there a page/tutorial/whatever that anyone can refer me to that explains which function interfaces are compatible and which are not?
When statically referencing an instance method, the returned functor takes an additional argument that represents the instance.
interface Func {
boolean evaluate(Evaluation instance, int a, int b);
}
...
Func biPredicate = Evaluation::evaluate;
System.out.println(biPredicate.evaluate(new Evaluation(), 6, 1));
But you will need to pass an instance of Evaluation when calling it.
Since your evaluate method does not use any instance fields, you might as well make it static, then you don't need to pass an instance, and can use just a BiPredicate<Integer, Integer> like you tried to.
If your method is an instance method, then you have to invoke it on some instance, for example:
public void methodTest(){
BiPredicate<Integer, Integer> biPredicate = this::evaluate;
System.out.println(biPredicate.test(6,1));
}
Since you are not using any instance variables or method, you can simply make it static and keep it like it is.
I'm still trying to figure out the rule that applies, but the problem goes away if you use
BiPredicate<Integer, Integer> biPredicate = this::evaluate;
I'm puzzling through https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13 but as near as I can figure, because the Evaluation::evaluate forces the compiler to create an arbitrary object of the type Evaluation, and you're calling it from within an object of that type, that the rule is different. You need to call it from the specific object inside of which the methodTest method appears.
While I don't have the explanation, the solution is to use this::evaluate. That unambiguously ties the method reference to the object calling it.
Side note: You don't need to evaluate a boolean as a conditional in order to derive a boolean from the boolean. You could just return a - b == 5;.
I am probably way too late to answer this, but since the question is still unanswered I would like to attempt an answer.
I think there is a miss in what OP is trying to achieve.
I understand that OP is trying to understand, why something like this would work:
String str = "abc";
Predicate<String> methodRef = str::startsWith;
methodRef.test("s");
and then,
Predicate <String> predicate = String::isEmpty
Works and in similar fashion, why wouldn't
Predicate <String> predicate = String::startsWith;
Compile which is taking String class name compile.
That is simply because, Predicate basically, takes any argument and returns a boolean. This is not a correct setup for this problem.
You can instead try,
BiFunction<String, String, Boolean> methodRef2 = String::startsWith;
methodRef2.apply("sdsdfsd", "sdfsdf");
This would work, as startswith needs a source string, string to check and return value. Basically there are 4 ways to invoke method references in Java 8
Static method calls.
Instance method calls.
Class method calls
Constructors

How to get the value of the arguments of the sonar tree

I'm writing a custom rule for SonarQube for java, I want to check if the value of an argument is qualified. For example, I want to know if the String fit the specific pattern. I can only test if the argument is a String, but I can not get the exact value. Does the API allows me to do so?
For example, for the code below
log.error("errorID:210134 It's an error");
Can I get the argument and test if the string contains errorID?
Besides, can I get what variable did the method invocation?
For example, for the code below
log.error("errorID:210134 It's an error");
How can I know that log is an Object of the class Logger?
The following should do the trick:
When looking at the argument of the method invocation, check if its kind is a STRING_LITERAL, then cast the argument into a LiteralTree. From there, you will be able to access its value, as a String (Note that it will contain the double quotation marks).
To check if the invocation was done on a variable, get the methodSelect() expression tree from the method invocation. If its kind is a MEMBER_SELECT, cast it to MemberSelectExpressionTree. From there, check if the kind of the expression() is an IDENTIFIER. If it's the case, then you will be able to get the IdentifierTree and its associated symbol. You will then be able to say if the symbol calling the method is a variable or not, check its type, etc.

Is there a way in Java to find the name of the variable that was passed to a function?

I have a Java function called testForNull
public static void testForNull(Object obj)
{
if (obj == null)
{
System.out.println("Object is null");
}
}
I use it to test multiple objects to ensure they are not null. But, I am unable to tell the name of the variable that way.
For eg. if I say
testForNull(x);
testForNull(y);
testForNull(z);
I cannot tell which of the three lines caused the "Object is null" output. Of course, I can simply add another parameter to the function and have something like
testForNull(x, "x");
testForNull(y, "y");
testForNull(z, "z");
But I want to know whether it is possible to deduce the name of the variable without passing it explicitly. Thanks.
Consider that the parameter might not have been a variable (and therefore wouldn't have a name):
testForNull(x != y);
No, there is no such a way. You will have to explicitly pass the name of the variable.
However, if your object has a field 'name' or displays its name via the toString() function, then that might help you.
Yes, but I wouldn't recommend it and it would be exceptionally hard. Try assert instead:
http://docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html
To do what you want, if you have the source code, get the current thread http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#currentThread()
Get a stack trace http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getStackTrace()
Get the 2nd to last element, the class name, file name, and line number, then print that line, or parse it http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html#method_summary
This is what a debugger is for. There is no way to do this programmatically. What if I invoke testForNull(1 + 1). What is the variable name then?
Eclipse has a graphical and easy-to-use debugger for Java built-in. Learning how to use that will pay dividends in the long run, and happens to be the immediate solution to your problem as well.
you could place the method call in a foreach and set a reference ID for each object that you are going through, even if it returns null or not null for that specific object.
Bah, After looking at the original question again, this is a non-starter.
The question asks us to be able to provide a means by which a value passed into a CheckForNull() method can retrieve the values name - and here's the kicker... only when the value is null.
There is absolutely no way you are going to get anything from a null value other than a String containing "null" or a NullPointerException.
But, as usual, object orientation to the rescue. Create a value class like I mentioned above. Now add an isNull() method to it. Use this value class for any value you are wanting to dump debugging text for.
Java is an object oriented language, therefore the answer is "most definitely!" you can tell the name of the variable passed as a parameter. To do so, try this...
class Value<T> extends Object
{
T value;
String name;
public Value(String name, T value)
{
this.name = name;
this.value = value;
}
}
Now in your methods, you would accept all parameters as instances of Value, as in the following method which would accept only Values created with classes having Number as a base class (which would be Long, Float, Double, etc)...
public String SomeMethodWantingToKnowParameterNames(Value<? extends Number> parm1)
{
if (parm1 != null)
{
// Do your work with the parameter - it's name can be accessed via parm1.name
// This is only an example
// You would probably want to write an accessor for name
return parm1.name;
}
// Return null for null
return null;
}
And that is all there is to it! I use a generic class so that Value can be used to pass in any type - Floats, Longs, Double, BigInteger, String - for example...
Value<Float> vFloat = new Value<Float>("MyFloat", 0.0);
Also, the method above is simply an example - in practice any method accepting a Value could access its name.
Good Luck and may all your code compile flawlessly!
Rodney

Categories

Resources