I have a Counter class that stores value as AtomicInteger. That class should be thread safe. I have method boolean consume(int number) that should decrement counter and return true if counter >= number, and should not change counter and return false if counter < number
class Counter {
AtomicInteger counter = new AtomicInteger(initialValue);
boolean consume(int number) {
counter.accumulateAndGet(number, (prev, next) -> {
if (number <= prev) {
return prev - number;
} else {
// not modify the previous number;
return prev;
}
});
return ???
}
}
And I don't know if the function applied or not. I found the following solution
boolean consume(int number) {
AtomicBoolean result = new AtomicBoolean(false);
counter.accumulateAndGet(number, (prev, next) -> {
if (number <= prev) {
result.set(true);
return prev - number;
// function applied
} else {
result.set(false);
// not modify the previous number;
return prev;
}
});
return result.get();
}
but javadoc of accumulateAndGet sais:
The function should be side-effect-free, since it may be re-applied
when attempted updates fail due to contention among threads.
So, my solution has side effects. Is it safe to use? If not, how can I get the same result?
From the description, it sounds as if you want something like:
class Counter {
private final int initialValue = 42; // make compile
/** Non-negative count. */
private final AtomicInteger counter = new AtomicInteger(initialValue);
public boolean consume(int number) {
for (;;) {
int old = counter.get();
int next = old-number;
if (next >= 0) {
if (counter.compareAndSet(old, next)) {
return true;
};
} else {
return false;
}
}
}
}
since it may be re-applied when attempted updates fail due to
contention among threads.
The code in the question is fine with regarding to being executed one or more times, but it doesn't help to use convenience methods if they're not convenient.
Related
this is a supplementary question aligned to a question I asked recently. I have the following recursive code that will give me the largest number from a List of integers
static int maximum (List<Integer> a)
{
if ((a.getTail().isEmpty()))
return 0;
else {
int n = maximum(a.getTail());
System.out.println(n);
if (a.getHead() > n) {
return (a.getHead());
} else {
return m;
}}
}
This is helpful. But what I really want to do is to be able to return a Boolean value true or false depending on where the list increases in value or decreases. So my method would become:
static boolean maximum (List<Integer> a)
{
if ((a.getTail().isEmpty()))
return true;
else {
int n = maximum(a.getTail());
System.out.println(n);
if (a.getHead() > n) {
return true;
} else {
return false;
}}
}
But this will not run. The challenge I am faced with is that the recursive call as I have written returns an integer so that I can compare the previous maximum with the current maximum ----- if (a.getHead() > m).
What I want to do is to try and complete the assessment of the current verses previous max within the recursive call so that I only have to return a Boolean, true or false.
So for example if as the recursion occurs the list continually increases then the Boolean stays true but if at any point it decreases then it will give a false:
1,2,3,4 = true
1,2,4,3 = false
Thank you for your help I am really struggling with the whole concept of recursion.....
Some things you might have missed:
in a function, a return statement terminates (break) the function immediatly. So in
if(...) { return ...; }
else {...}
→ else is redundant, as if the condition is true, the function is already terminated (break)
Something like a==0 has a boolean value (true or false). So
if(i==0) { return true; }
else { return false; }
can be shortened to return count==0;
I recommend to always use braces, because something like if(i==0) ++i; break;, means if(i==0) {++i;}. break; will be called in any case.
what you want, is something like this:
static boolean is_sorted(List<Integer> list)
{
return is_sorted_from(0, list);
}
static boolean is_sorted_from(int index, List<Integer> list)
{
if(index+1 >= a.size()) { return true };
return list.get(index) < list.get(index+1)
&& is_next_sorted(index+1, list);
}
static boolean maximum (List<Integer> a, boolean cont){
if(cont){
if ((a.getTail().isEmpty())){
cont = false;
}else {
int n = maximum(a.getTail());
System.out.println(n);
if (a.getHead() > n) {
maximum(a.getHead(), cont);
} else {
maximum(n, cont);
}
}
}
return cont;
}
I'd say to make the method void or return the List, but I left it as boolean since that is technically what your question asked for.
You would just call the method with cont having the value of true. By using two parameters, you can continue comparing your max function while simultaneously using a boolean as your recursion flag. You would not be able to return your maximum however, but you could work around this by setting the maximum to either a class instance or to an object that you have as your third parameter (Double, Integer, etc.).
I want to write a code to check the existence of given two values in a List.
List<Tag> tags = new ArrayList<>();
The requirement is to return true only if the List tag contains both "start" and "end" values.
My code is like this, but it doesn't cater to the requirement.
public static boolean checkStartAndEndTimeTag(List<Tag> tags) {
boolean isSuccess = false;
int count = 0;
for (Tag tag : tags) {
if (tag.getKey().equals("start") || tag.getKey().equals("end")) {
count++;
if (count == 2)
break;
isSuccess = true;
}
}
return isSuccess;
Can someone help me with to resolve this issue?
This...
if (count == 2)
break;
isSuccess = true;
doesn't make sense. This will set isSuccess even if there is only one match
The long winded approach
Okay, let's assuming for a second that you only care if there is at least one start and one end (discounting duplicates). One approach would be to use to state flags, one for start and one for end. To keep it simple, they would start of as 0 but would only ever be a maximum of 1 (because we don't want duplicates), then you might be able to do something like...
public static boolean checkStartAndEndTimeTag(List<Tag> tags) {
boolean isSuccess = false;
int starts = 0;
int ends = 0;
for (Tag tag : tags) {
if (tag.getKey().equals("start")) {
starts = 1;
} else if (tag.getKey().equals("end")) {
ends = 1;
}
}
isSuccess = (starts + ends) == 2;
return isSuccess;
}
Ok, you don't need isSuccess = (starts + ends) == 2; and could simply return the result of the comparison. You could also break out of the loop if (starts + ends) == 2 and save yourself from unnecessary computation
for (Tag tag : tags) {
if (tag.getKey().equals("start")) {
starts = 1;
} else if (tag.getKey().equals("end")) {
ends = 1;
}
if ((starts + ends) == 2) {
break;
}
}
Using streams...
One approach might be to make use the streams support and simply filter the List and count the results, for example...
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
List<Tag> tags = new ArrayList<Tag>(25);
tags.add(new Tag("begin"));
tags.add(new Tag("front"));
tags.add(new Tag("start"));
tags.add(new Tag("finish"));
tags.add(new Tag("tail"));
tags.add(new Tag("end"));
boolean isSuccessful = tags.stream().filter(tag -> tag.getKey().equals("start") || tag.getKey().equals("end")).count() >= 2;
System.out.println(isSuccessful);
}
public class Tag {
private String key;
public Tag(String key) {
this.key = key;
}
public String getKey() {
return key;
}
}
}
Updated...
Okay, this got complicated fast. Let's assume you don't want to match two start tags, so you MUST have both one end and one start tag
So, using the above, example, we can modify the Tag class to support equals (and by extension hashcode)
public class Tag {
private String key;
public Tag(String key) {
this.key = key;
}
public String getKey() {
return key;
}
#Override
public String toString() {
return getKey();
}
#Override
public int hashCode() {
int hash = 7;
hash = 73 * hash + Objects.hashCode(this.key);
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Tag other = (Tag) obj;
if (!Objects.equals(this.key, other.key)) {
return false;
}
return true;
}
}
Then we can simply use distinct to filter out any duplicates, for example...
boolean isSuccessful = tags
.stream()
.distinct()
.filter(tag -> tag.getKey().equals("start") || tag.getKey().equals("end"))
.count() >= 2;
Probably not the most efficient solution, but certainly one of the shortest
In this code
if (tag.getKey().equals("start") || tag.getKey().equals("end")) {
count++;
if (count == 2)
break;
isSuccess = true;
}
you are setting isSuccess to true whenever the tag is start or end.
Better way would be
if (tag.getKey().equals("start") || tag.getKey().equals("end")) {
count++;
if (count == 2)
return true;
}
You could also use
tags.stream()
.map(Tag::getKey)
.distinct()
.filter(t -> "start".equals(t) || "end".equals(t))
.count() == 2;
This would also fix the issue that your original code falsely returns true if the list contains statt or end twice.
What about
tags.containsAll(Arrays.asList(new Tag("start"), new Tag("stop")))
Hello I am working on a project for school and im having a great deal of difficulty trying to figure why my program keeps telling me im missing a return statement in all of my methods,
Here is my code:
public class Temperature {
private int temperature;
//constructors
public int Test( int temperature )
{
temperature = temperature;
return temperature;
}
public int TempClass()
{
temperature = 0;
return 0;
}
// get and set methods
public int getTemp()
{
return temperature;
}
public void setTemp(int temp)
{
temperature = temp;
}
//methods to determine if the substances
// will freeze or boil
public static boolean isEthylFreezing(int temp)
{
int EthylF = -173;
if (EthylF <= temp)
{System.out.print("Ethyl will freeze at that temperature");}
else
return false;
}
public boolean isEthylBoiling(int temp)
{
int EthylB = 172;
if (EthylB >= temp)
System.out.print("Ethyl will boil at that temperature");
else
return false;
}
public boolean isOxygenFreezing(int temp)
{
int OxyF = -362;
if (OxyF <= temp)
System.out.print("Oxygen will freeze at that temperature");
else
return false;
}
public boolean isOxygenBoiling(int temp)
{
int OxyB = -306;
if (OxyB >= temp)
System.out.print("Oxygen will boil at that temperature");
else
return false;
}
public boolean isWaterFreezing(int temp)
{
int H2OF = 32;
if (H2OF <= temp)
System.out.print("Water will freeze at that temperature");
else
return false;
}
public boolean isWaterBoiling(int temp)
{
int H2OB = 212;
if (H2OB >= temp)
System.out.print("Water will boil at that temperature");
else
return false;
}
}
Here is the problem line:
if (EthylF <= temp)
{System.out.print("Ethyl will freeze at that temperature");}
else
return false;
The compiler thinks that return false belongs with the else branch, so if the EthylF <= temp branch is taken, the method ends without returning a value. Same goes for the rest of your boolean getters.
Properly indenting and using curly braces would help you avoid problems like that: when you see the same code formatted as follows
if (EthylF <= temp) {
System.out.print("Ethyl will freeze at that temperature");
} else {
return false;
}
you see exactly where the problem is.
Adding return true in the if branch would solve this problem.
Look at the if-else statements in your isXXXFreezing(int temp) and isXXXBoiling(int temp) methods: The section below the if-statement does not contain a return statement, only the section below the else does.
The correct code for isEthylFreezing(int temp) would be
public static boolean isEthylFreezing(int temp) {
int EthylF = -173;
if (EthylF <= temp)
{
System.out.print("Ethyl will freeze at that temperature");
return true;
}
else
return false;
}
Also in the constructor of Test you are assigning the variable temperature to itself. I guess you want to assign the function parameter temperature to a member variable of Test which is also named temperature? If so, write this.temperature = temperature;.
this refers to the current Test object and will make sure that you access the member variable.
int EthylF = -173;
if (EthylF <= temp)
{System.out.print("Ethyl will freeze at that temperature");}
else
return false;
This method only returns (false) if EthylF > temp. Otherwise, you have a print, but no return statement.
Every possible path of execution inside a non-void method must end with a return statement, or with a throw statement.
I have to write the following recursion method:
public static int countA(String s)
Yet I find it impossible to do this without declaring a counter and position variable; like so:
public static int countA(String s, int position) {
int count = 0;
if( s.charAt(position) == 'A' )
count++;
if( position + 1 < s.length() ) {
count += countA(s, position + 1);
}
return count;
}
How can I simplify my answer so that my method is the same as the one listed?
EDIT: Yes, I want to count all A's inside a string.
Try this:
public static int countA(String s) {
int count = 0;
if (s == null)
return 0;
if (s.length() == 0)
return 0;
if (s.charAt(0) == 'A')
count++;
return count + countA(s.substring(1));
}
There are two forms of recursion,
Tail Recursion : The return value is calculated as a combination of the value of current subroutine and the return value of the next call. Example,
int factorial(int a) {
if(a==0)
return 1;
else
return a * factorial( a-1 );
}
Accumulator based recursion : You accumulate the results by adding an additional parameter and return the accumulated value.
int factorial(int a, int fact) {
if(a==0)
return fact;
else
return factorial(a-1, a*fact);
}
Obviously what you have here is accumulator based, while you can improve it to Tail recursion.
Tail recursion is considered more readable, while it can cause a StackOverflow! (no pun intended). This is because it has to push the current value to a stack, before calling subroutine again. And when you make a large number of such calls, this stack might go over its limit.
Some compilers optimize tail recursion to accumulator based in order to avoid this problem.
What about:
public static int countA(String s) {
if(s==null) return 0;
if(s.length()==0) return 0;
if( s.charAt(0) == 'A' )
{
return 1 + countA(s.substring(1));
} else
{
return countA(s.substring(1));
}
}
I think something like this should do the trick
Here we are assuming that countA returns the number of As inside String s
public static int countA(String s)
{
if(s.length()==0) return 0; // return 0 if string is empty
else
{
// if the first char is A add 1 to the answer, recurse
if(s.toCharArray()[0])=='A') return 1+countA(s.subString(1,s.length()));
// else add nothing to the answer, recurse
else return countA(s.subString(1,s.length()));
}
}
You move the position variable out of the method and make it static(since your countA() is also static).
static int position = 0;
public static int countA(String s) {
int count = 0;
if( s.charAt(position) == 'A' )
count++;
if( position + 1 < s.length() ) {
position++;
count += countA(s);
}
return count;
}
Ideally you have the termination condition first, which then usually simplifies the code by reducing indentation/nesting and have a "do nothing" action for it (typically requiring one more iteration than absolutely required).
You also don't need the local variable!
public static int countA(String s, int position) {
if (position == s.length())
return 0;
return (s.charAt(position) == 'A' ? 1 : 0) + countA(s, position + 1);
}
I am having trouble with this problem: I am to write a method contains3 that accepts a List of strings as a parameter and returns true if any single string occurs at least 3 times in the list, and false otherwise. I need to use a map.
When there are three instances of a word, it still does not return true; I am having trouble locating where things went wrong.
Here is what I have:
private static boolean contains3(List<String> thing) {
Map<String, Integer> wordCount = new TreeMap<String, Integer>();
for (String s: thing) {
String word = s;
if (wordCount.containsKey(word)) { // seen before.
int count = wordCount.get(word);
wordCount.put(word, count + 1);
} else {
wordCount.put(word, 1); // never seen before.
}
if (wordCount.containsValue(3)) {
return true;
} else {
return false;
}
}
return false;
}
The problem is here:
if (wordCount.containsValue(3)) {
//...
You should get the value using the key, in other words, the word you're counting.
if (wordCount.get(word) >= 3) {
return true;
}
Note that I removed the return false; from this if statement since it will break the method in the first iteration.
As a suggestion, you may use a HashMap instead of TreeMap to enhance the performance of your method since the put and get time in HashMap are O(1) (constant time) while TreeMap's are O(log n).
Try using the following code.
private static boolean contains3(List<String> thing) {
Map<String, Integer> wordCount = new TreeMap<String, Integer>();
thing.add("hi");
thing.add("hi");
thing.add("hi");
thing.add("hia");
thing.add("hi3");
for (String s: thing) {
String word = s;
if (wordCount.containsKey(word)) { // seen before.
int count = wordCount.get(word);
wordCount.put(word, count + 1);
} else {
wordCount.put(word, 1); // never seen before.
}
}
if (wordCount.containsValue(3)) {
return true;
} else {
return false;}
You're running this code as you add each word:
if (wordCount.containsValue(3)) {
return true;
} else {
return false;
The test will fail when the first word is added, and you'll immediately return false. Move that block to the end of the method, in the final line where you currently have return false to only make the check when you've counted all the words.
put
if (wordCount.containsValue(3)) {
return true;
} else {
return false;
}
outside the for loop
It is much more efficient to check if count is >= 3 in the initial if block
if (wordCount.containsKey(word)) { // seen before.
int count = wordCount.get(word) + 1;
if(count >= 3) {
return true;
}
wordCount.put(word, count);
}
and remove the following if else block
if (wordCount.containsValue(3)) {
return true;
} else {
return false;
}