Java 8 efficient for loop - java

I have below code snippet, Is any other efficient way exists to achieve the same in java 8. I have tried lambda expression but throws error when i assign some variable inside lambda function.
public boolean countUsers(UserDetais details){
List<SystemProfile> systemProfileDataList = getSystemProfileData();
int userCountForService = service.getUserCountByService(details.id);
int vpcUsersCount=0;
int internetUsersCount=0;
if (systemProfileDataList != null) {
SystemProfile sysProfile;
Iterator profileItr = systemProfileDataList.iterator();
while (profileItr.hasNext()) {
SystemProfile sysProfile = (SystemProfile) profileItr.next();
if(sysProfile.getName().equalsIgnoreCase(IPConstants.DEFAULT_MAX_USERS)) {
vpcUsersCount = Integer.parseInt(sysProfile.getValue());
if (userCountForService > vpcUsersCount) {
maxUserFlag = true;
break;
}
}else if(sysProfile.getName().equalsIgnoreCase(IPConstants.DEAULT_MAX_USERS_WITH_INTERNET)) {
internetUsersCount = Integer.parseInt(sysProfile.getValue());
if (userCountForService > internetUsersCount) {
maxUserFlag = true;
break;
}
}
}
}

I think this should work :
boolean tooManyUsers = getSystemProfileData().stream()
.anyMatch((SystemProfile s) ->
s.getName().equalsIgnoreCase(IPConstants.DEFAULT_MAX_USERS)
&& Integer.parseInt(sysProfile.getValue()) < userCountForService
||
s.getName().equalsIgnoreCase(IPConstants.DEAULT_MAX_USERS_WITH_INTERNET)
&& Integer.parseInt(sysProfile.getValue()) < internetUsersCount
);

Related

java:S2189: "Add an end condition to this loop.". Could you please help me?

I'm trying to solve this Sonarqube issue regarding this piece of code
private void processEvents() {
long nextSequence = sequence.get() + 1L;
long groupCounter = 0;
long msgsInGroup = 0;
long groupLastNs = 0;
long l2dataLastNs = 0;
boolean triggerL2DataRequest = false;
final int tradeEventChainLengthTarget = sharedPool.getChainLength();
MatcherTradeEvent tradeEventHead = null;
MatcherTradeEvent tradeEventTail = null;
int tradeEventCounter = 0; // counter
while (true) {
try {
// should spin and also check another barrier
long availableSequence = waitSpinningHelper.tryWaitFor(nextSequence);
if (nextSequence <= availableSequence) {
while (nextSequence <= availableSequence) {
OrderCommand cmd = ringBuffer.get(nextSequence);
nextSequence++;
// some commands should trigger R2 stage to avoid unprocessed state in events
if (cmd.command == OrderCommandType.RESET
|| cmd.command == OrderCommandType.PERSIST_STATE_MATCHING
|| cmd.command == OrderCommandType.BINARY_DATA) {
groupCounter++;
msgsInGroup = 0;
}
cmd.eventsGroup = groupCounter;
cmd.serviceFlags = 0;
if (triggerL2DataRequest) {
triggerL2DataRequest = false;
cmd.serviceFlags = 1;
}
// cleaning attached events
if (EVENTS_POOLING && cmd.matcherEvent != null) {
// update tail
if (tradeEventTail == null) {
tradeEventHead = cmd.matcherEvent; //?
} else {
tradeEventTail.nextEvent = cmd.matcherEvent;
}
tradeEventTail = cmd.matcherEvent;
tradeEventCounter++;
// find last element in the chain and update tail accourdingly
while (tradeEventTail.nextEvent != null) {
tradeEventTail = tradeEventTail.nextEvent;
tradeEventCounter++;
}
if (tradeEventCounter >= tradeEventChainLengthTarget) {
// chain is big enough -> send to the shared pool
tradeEventCounter = 0;
sharedPool.putChain(tradeEventHead);
tradeEventTail = null;
tradeEventHead = null;
}
}
cmd.matcherEvent = null;
// TODO collect to shared buffer
cmd.marketData = null;
if (cmd.command == OrderCommandType.NOP) {
// just set next group and pass
continue;
}
msgsInGroup++;
// switch group after each N messages
// avoid changing groups when PERSIST_STATE_MATCHING is already executing
if (msgsInGroup >= msgsInGroupLimit && cmd.command != OrderCommandType.PERSIST_STATE_RISK) {
groupCounter++;
msgsInGroup = 0;
}
}
sequence.set(availableSequence);
groupLastNs = System.nanoTime() + GROUP_MAX_DURATION_NS;
} else {
final long t = System.nanoTime();
if (msgsInGroup > 0 && t > groupLastNs) {
// switch group after T microseconds elapsed, if group is non empty
groupCounter++;
msgsInGroup = 0;
}
if (t > l2dataLastNs) {
l2dataLastNs = t + L2_PUBLISH_INTERVAL_NS; // trigger L2 data every 10ms
triggerL2DataRequest = true;
}
}
} catch (final AlertException ex) {
if (running.get() != RUNNING) {
break;
}
} catch (final Throwable ex) {
sequence.set(nextSequence);
nextSequence++;
}
}
}
The problem is about that while(true) loop with a try catch inside. I've tried to put while(true) into the try block but this created huge compilation error.
This code has not been written by me, but it is a project given me by my teacher for the exam.
Introduce a variable so that instead of
while (true) {
...
}
You can control it from within the loop
boolean running = true;
...
while (running) {
...
if (condition) {
running = false;
}
}
Or alternatively create a method to validate whatever criteria are necessary if the loop is to keep iterating:
while (isValid(input)) {
...
}
And define the method
boolean isValid( ... method args here ... ) {
...
}
If for example the loop should keep going for as long as nextSequence is not 0, this can all be simplified to
while (nextSequence != 0) {
...
}
Note that you can't use a compile time constant in this case. If it were set to false you would get an error due to unreachable code.

Recursion - Expressions that evaluate to target

I am trying to understand recursion and solve the problem with
operators = ['','*', "+"]
input : "2224"
target : 24
output = {"22+2", "2+22", "24"}
Here's the code that I came up with. But it produces invalid output.
static List<String> output = new ArrayList<>();
static String[] generate_all_expressions(String s, long target) {
getExpressionsRecur(s, target, 0, null, 0);
String[] out = new String[output.size()];
return output.toArray(out);
}
static void getExpressionsRecur(String s, long target, int currentValue, String currExpression, int currIndex) {
if (currIndex == s.length()){
if (currentValue == target) {
output.add(currExpression);
}
return;
}
if (currentValue == target) {
output.add(currExpression);
return;
}
int currentPart = Integer.valueOf(s.substring(currIndex, currIndex+1));
if (currIndex == 0) {
getExpressionsRecur(s, target, currentPart, String.valueOf(currentPart), currIndex+1);
} else {
int value = Integer.valueOf(String.valueOf(currentValue) + String.valueOf(currentPart));
getExpressionsRecur(s, target, value , currExpression + "" + currentPart, currIndex+1);
getExpressionsRecur(s, target, (currentValue * currentPart), currExpression + "*" + currentPart, currIndex+1);
getExpressionsRecur(s, target, (currentValue + currentPart), currExpression + "+" + currentPart, currIndex+1);
}
}
It produces:
{22+2, 2*2+2*4, 2+2+2*4}
Can someone help me spot the errors?
First rethink your recursion since you're not hitting every case.
Write out cases if you need to, maybe start with a 3 digit number since there are less cases; In your code, for example, "24" is never evaluated on it's own.
You are calculating value wrongly for concatenation case. 22*2 will become 22*24.But you are saying this new expression has a value of 444 (should be 528) . You can't really use current value. Probably you can restructure your recursion to make it easier.
You can use this Expression object I threw together in replace of your expression String... call expression.toString() and expression.value() as necessary. But still you'll need changes to your basic recursion structure even after implementing this or similar Expression Object.
public class Expression{
Expression lExpression;
String lValue;
Expression rExpression;
String operator;
public Expression(String expression) {
int multIndex = expression.indexOf("*");
int addIndex = expression.indexOf("+");
if(multIndex == -1 && addIndex == -1) {
this.lExpression = new Expression(Integer.valueOf(expression));
return;
}
if(multIndex != -1 && multIndex < addIndex) {
this.lExpression = new Expression(expression.substring(0, addIndex));
this.operator = expression.substring(addIndex, addIndex+1);
this.rExpression = new Expression(expression.substring(addIndex+1));
}else {
if(addIndex == -1) {
addIndex = Integer.MAX_VALUE;
}
if(multIndex == -1) {
multIndex = Integer.MAX_VALUE;
}
int opIndex = multIndex < addIndex ? multIndex : addIndex;
this.lExpression = new Expression(expression.substring(0, opIndex));
this.operator = expression.substring(opIndex, opIndex+1);
this.rExpression = new Expression(expression.substring(opIndex+1)); }
}
public Expression(int value) {
this.lValue = String.valueOf(value);
this.lExpression = null;
this.rExpression = null;
this.operator = null;
}
#Override
public String toString() {
return (lExpression!=null ? lExpression : lValue) + (operator !=null ? operator: "") + (rExpression!=null ? rExpression : "");
}
public int value() {
if(lExpression == null) {
return Integer.valueOf(lValue);
}
if("*".equals(operator)) {
return lExpression.value() * rExpression.value() ;
}
if("+".equals(operator)) {
return lExpression.value() + rExpression.value();
}
return lExpression.value();
}
}

Code re-factoring does not give the same result at the end

I am trying to rewrite and re-factor my code below but I do not have the same result at the end(List vgs does not contain the same result when I execute both function).
Also, I can not figure out what is wrong with my code below. Can someone tell me how can do to keep the order of my elements in List andVars, notVars and orVars?
The goal of this function is to remove all null or empty String element values of andVars & notVars list + all duplicate elements in my String element values of andVars & notVars list
for each varGroup element and keep the order of the elements of andVars, notVars list. Thank you
public static void RemoveDuplicateListElements(List<VarGroup> vgs) {
if (vgs == null) {
return;
}
for (VarGroup vg : vgs) {
RemoveDuplicateListElements(vg.getOrVars());
if (vg.getAndVars() != null) {
for (int x = vg.getAndVars().size()-1 ; x >= 0; x--) {
if (vg.getAndVars().get(x) == null
|| vg.getAndVars().get(x).isEmpty())
{
vg.getAndVars().remove(x);
} else {
for (int y = 0; y < x; y++) {
if (vg.getAndVars().get(x).equals(vg.getAndVars().get(y))) {
vg.getAndVars().remove(x);
break;
}
}
}
}
}
if (vg.getNotVars() != null) {
for (int x = vg.getNotVars().size()-1 ; x >= 0; x--) {
if (vg.getNotVars().get(x) == null
|| vg.getNotVars().get(x).isEmpty())
{
vg.getNotVars().remove(x);
} else {
for (int y = 0; y < x; y++) {
if (vg.getNotVars().get(x).equals(vg.getNotVars().get(y))) {
vg.getNotVars().remove(x);
break;
}
}
}
}
}
}
}
public class VarGroup {
private List<String> notVars = new ArrayList();
private List<VarGroup> orVars = new ArrayList();
private List<String> andVars = new ArrayList();
public List<VarGroup> getOrVs() {
return this.orVars;
}
public void setOrVars(List<VarGroup> orVars) {
this.orVars = orVars;
}
public List<String> getAndVars() {
return this.andVars;
}
public void setAndVars(List<String> andVars) {
this.andVars = andVars;
}
public List<String> getNotVars() {
return this.notVars;
}
public void setNotVars(List<String> notVars) {
this.notVars = notVars;
}
}
My refactoring is here:
public static void RemoveDuplicateListElements(List<VarGroup> vgs) {
if (vgs == null) {
return;
}
for (VarGroup vg : vgs) {
RemoveDuplicateListElements(vg.getOrVars());
if (vg.getAndVars() != null) {
vg.getAndVars().stream().distinct()
.filter(andVar -> Objects.nonNull(andVar) || !andVar.isEmpty())
.collect(Collectors.toList());
}
if (vg.getNotVars() != null) {
vg.getNotVars().stream().distinct()
.filter(notVar -> Objects.nonNull(notVar) || !notVar.isEmpty())
.collect(Collectors.toList());
}
}
}
I think you should extract some function here:
public static void removeDuplicateListElements(List<VarGroup> vgs) {
if (vgs == null) {
return;
}
for (final VarGroup vg : vgs) {
removeDuplicateListElements(vg.getOrVars());
handleVars(vg.getAndVars());
handleVars(vg.getNotVars());
}
}
private static void handleVars(final List<String> theVars) {
if (theVars != null) {
for (int x = theVars.size() - 1; x >= 0; x--) {
if (theVars.get(x) == null || theVars.get(x).isEmpty()) {
theVars.remove(x);
} else {
for (int y = 0; y < x; y++) {
if (theVars.get(x).equals(theVars.get(y))) {
theVars.remove(x);
break;
}
}
}
}
}
}
Method used (Intellij Idea):
select vg.getAndVars() and extract a variable for it
select vg.getOrVars() and extract a variable for it
got a warning about duplicated code
select the 1st bloc marked as duplicated and extract a method (accept IntelliJ proposal to replace 2nd block)
inline vars extracted in the 2 first steps
(Bonus step: some renaming)
This code in your refactored method does not do anything:
if (vg.getAndVars() != null) {
vg.getAndVars().stream().distinct()
.filter(andVar -> Objects.nonNull(andVar) || !andVar.isEmpty())
.collect(Collectors.toList());
}
It just creates a stream from the list, filters the stream, and then creates a new list from the filtered stream. But that new list is then immediately discarded. You should use the created filtered list using setAndVars, or e.g. using retainAll to modify the existing list.
Alternatively, if you want to use streams and lambdas, how about using removeIf? You can keep track of duplicates using a Set1). Simple example:
List<String> lst = new ArrayList<>(Arrays.asList("foo", "bar", "foo", "blub", null));
Set<String> seen = new HashSet<>();
lst.removeIf(x -> x == null || ! seen.add(x));
1) Usually you should not use methods with side effects in streams.
If you want duplicates removed and keeping order why don't you use a TreeSet
?
It looks to me like this code will remove every element of the list
for (int x = vg.getAndVars().size()-1 ; x >= 0; x--) {
// ...
for (int y = 0; y < x; y++) {
if (vg.getAndVars().get(x).equals(vg.getAndVars().get(y))) {
vg.getAndVars().remove(x);
break;
}
}
}
}
Since you're removing elements from the list in the loop, the data stored in a given index could change during the loop.

Is there any method to store conditional statement in java?

I wanted to know if there is any method to store if else condition in java? What I mean is like having a variable to represent the condition. This is my original code
private OnClickListener click2 = new OnClickListener() {
#Override
public void onClick(View v) {
tv1.setText("");
List<Integer> mClickedButtonIds = new ArrayList<Integer>();
int[] mDesiredOrder = new int[] { ans1.getId(), ans2.getId(), ans3.getId(),
ans4.getId(), ans5.getId() };
mClickedButtonIds.add(v.getId());
if (mClickedButtonIds.size() >= mDesiredOrder.length )
{
if (mClickedButtonIds.get(0) == mDesiredOrder[0]
&& mClickedButtonIds.get(1) == mDesiredOrder[1]
&& mClickedButtonIds.get(2) == mDesiredOrder[2]
&& mClickedButtonIds.get(3) == mDesiredOrder[3]
&& mClickedButtonIds.get(4) == mDesiredOrder[4]
)
{
tv1.setText("Correct!");
}
else
{
tv1.setText("Try Again!");
}
mClickedButtonIds.clear();
}
}
};
I plan to change it to something like this
private OnClickListener click2 = new OnClickListener() {
#Override
public void onClick(View v) {
tv1.setText("");
List<Integer> mClickedButtonIds = new ArrayList<Integer>();
int[] mDesiredOrder = new int[] { ans1.getId(), ans2.getId(), ans3.getId(),
ans4.getId(), ans5.getId(), ans6.getId() };
switch (main)
{
case 4 : Variable x = mClickedButtonIds.get(0) == mDesiredOrder[0]
&& mClickedButtonIds.get(1) == mDesiredOrder[1]
&& mClickedButtonIds.get(2) == mDesiredOrder[2]
&& mClickedButtonIds.get(3) == mDesiredOrder[3];
case 5 : Variable x = mClickedButtonIds.get(0) == mDesiredOrder[0]
&& mClickedButtonIds.get(1) == mDesiredOrder[1]
&& mClickedButtonIds.get(2) == mDesiredOrder[2]
&& mClickedButtonIds.get(3) == mDesiredOrder[3]
&& mClickedButtonIds.get(4) == mDesiredOrder[4];
case 6: Variable x = mClickedButtonIds.get(0) == mDesiredOrder[0]
&& mClickedButtonIds.get(1) == mDesiredOrder[1]
&& mClickedButtonIds.get(2) == mDesiredOrder[2]
&& mClickedButtonIds.get(3) == mDesiredOrder[3]
&& mClickedButtonIds.get(4) == mDesiredOrder[4]
&& mClickedButtonIds.get(5) == mDesiredOrder[5];
}
mClickedButtonIds.add(v.getId());
if (mClickedButtonIds.size() >= mDesiredOrder.length )
{
if (x)
{
tv1.setText("Correct!");
}
else
{
tv1.setText("Try Again!");
}
mClickedButtonIds.clear();
}
}
};
The Variable x is something which I would like to ask. Is there any method to do so or is there any variable that can store if else condition. Cause the original code, it is fixed to 5 clicks. Now I want the number of required clicks to change according to how many clicks the user want.
Based on the code snippet, consider a loop:
boolean result = true;
for (int i = 0; i < main; ++i) {
result = result && mClickedButtonIds.get(i) == mDesiredOrder[i];
if (!result)
break; // short-circuit out from loop if false
}
// now you can use "result" to test whether the condition matched all "main" ids
if (result) {
// correct
} else {
// bzzt, try again
}
If I understand correctly, that you want x to be a condition that you may change programatically (but which conforms to some structure) then you can do this using an interface Question and classes which implement that interface
public interface Question {
boolean getResponse(String condition1, int condition2);
}
public class StringIsLongCondition implements Question{
public boolean getResponse(String condition1, int condition2) {
return condition1.length()>condition2;
}
}
public class StringIsShortCondition implements Question{
public boolean getResponse(String condition1, int condition2) {
return condition1.length()<condition2;
}
}
Then use like
Question x;
//some code that selects the question
x= new StringIsShortCondition();
if(x.getResponse(someString, someInt){
//do something
}

Java : How to set the flag value in a array loop

This is my below mehod for Validation .
public boolean validateData(Bagform[] bagdata) {
boolean flag = false;
int length = bagdata.length;
if (length == 2) {
for (int i = 0; i < bagdata.length; i++) {
if (bagdata[i].getCallType() == null) {
flag = true;
}
}
}
else {
flag = true;
}
return flag;
}
In this basically i am checking that if the getCallType() is not null for any of the values in the array .
If its not null , then its a valid data , so i am setting the flag to true .
(Please see the code above )
But for me , i am getting the flag value still as false ( Even though the getCallype() is not null )
Please help me .
You're setting the flag to true if the call type is null. I suspect you want:
public boolean validateData(Bagform[] bagdata) {
boolean flag = true;
int length = bagdata.length;
if (length == 2) {
for (int i = 0; i < bagdata.length; i++) {
if (bagdata[i].getCallType() == null) {
flag = false;
}
}
}
return flag;
}
It's not clear why you're only performing this validation when there are exactly two entries in the array though. Unless that's really deliberate, I'd have written this has:
public boolean validateData(Bagform[] bagdata) {
for (Bagform form : bagdata) {
if (form.getCallType() == null) {
return false;
}
}
return true;
}

Categories

Resources