Greater than and less than in one statement - java

I was wondering, do you have a neat way of doing this ?
if(orderBean.getFiles().size() > 0 && orderBean.getFiles().size() < 5)
without declaring a variable that is not needed anywhere else ?
int filesCount = orderBean.getFiles().size();
if(filesCount > 0 && filesCount < 5) {
I mean, in for loop we are "declaring conditions" for the actual iteration, one can declare a variable and then specify the conditions. Here one can't do it, and neither can do something like
if(5 > orderBean.getFiles().size() > 0)

Simple utility method:
public static boolean isBetween(int value, int min, int max)
{
return((value > min) && (value < max));
}

Several third-party libraries have classes encapsulating the concept of a range, such as Apache commons-lang's Range (and subclasses).
Using classes such as this you could express your constraint similar to:
if (new IntRange(0, 5).contains(orderBean.getFiles().size())
// (though actually Apache's Range is INclusive, so it'd be new Range(1, 4) - meh
with the added bonus that the range object could be defined as a constant value elsewhere in the class.
However, without pulling in other libraries and using their classes, Java's strong syntax means you can't massage the language itself to provide this feature nicely. And (in my own opinion), pulling in a third party library just for this small amount of syntactic sugar isn't worth it.

If getFiles() returns a java.util.Collection, !getFiles().isEmpty() && size<5 can be OK.
On the other hand, unless you encapsulate the container which provides method such as boolean sizeBetween(int min, int max).

This is one ugly way to do this. I would just use a local variable.
EDIT: If size() > 0 as well.
if (orderBean.getFiles().size() + Integer.MIN_VALUE-1 < Integer.MIN_VALUE + 5-1)

java is not python.
you can't do anything like this
if(0 < i < 5) or if(i in range(0,6))
you mentioned the easiest way :
int i = getFilesSize();
if(0 < i && i < 5){
//operations
}
of
if(0 < i){
if(i < 5){
//operations
}
}

If this is really bothering you, why not write your own method isBetween(orderBean.getFiles().size(),0,5)?
Another option is to use isEmpty as it is a tad clearer:
if(!orderBean.getFiles().isEmpty() && orderBean.getFiles().size() < 5)

Please just write a static method somewhere and write:
if( isSizeBetween(orderBean.getFiles(), 0, 5) ){
// do your stuff
}

Nowadays you can use lodash:
var x = 1;
var y = 5;
var z = 3;
_.inRange(z,x,y);
//results true

Related

Sorting an ArrayList object populated with custom objects with two data fields each

stuck on a problem with sorting ArrayLists. I'm sure the answer is really easy and something I just keep overlooking, but I've been working on this for the past many hours straight and just need someone else's eyes.
It's a lab project that required us to make 3 custom classes; Applications.java, Rectangle.java, and RectangleList.java and I have to sort an ArratList that contains Rectangle objects with length and width data fields.
The order is (W1, L1) > (W2, L2) if and only if [(W1 > W2) or (W1 = W2 and L1 > L2)
I'm not sure what bits of code would be necessary to look at for help, but I know I'm supposed to use for loops and no outside pre-made methods for sorting. I'm supposed to run a for loop through each index and compare that index to each other index and then switch values. My current bit of code either doesn't do anything (no sorting happens) or it throws up duplicates. Just lots of stuff going on and I've erased everything and started over many times. Not sure where to go from here, and I no longer know how to think of the problem.
Thanks, just let me know what you need to see and I'll try posting it.
Edit note: We aren't allowed to use comparator or comparable or any other compare method I don't know about yet.
/////////////////////////////////////////////////////////////////////////////
I figured it out!
for(int index = 0; index < (list.boxes.size()-1); index++){
minIndex = index;
for(int index2 = index+1; index2 < list.boxes.size(); index2++){
if((list.boxes.get(minIndex).getLength() > list.boxes.get(index2).getLength()) || (list.boxes.get(minIndex).getLength() == list.boxes.get(index2).getLength() && list.boxes.get(minIndex).getWidth() > list.boxes.get(index2).getWidth())){
minIndex = index2;
}
}
list.boxes.set(index, list.boxes.set(minIndex, list.boxes.get(index)));
}
I think the comparator could help you :
Collections.sort(rectList, new Comparator<Rectangle>() {
#Override
public int compare(Rectangle rect1, Rectangle rect2) {
if(rect1.width > rect2.width)
return -1;
else if(rect1.width == rect2.width && rect1.length > rect2.length)
return -1;
else if(rect1.width == rect2.width && rect1.length == rect2.length)
return 0;
else
return 1;
}
});
If you are using Java8 then Lambda expression can be used to make the code smaller.

Beginner Boolean compiling error

I am very new to Java (doing a beginners university module) so sorry for the probably silly question. I am trying to verify whether a ragged array is a 'tridiagonal matrix'.
It is valid if it is of length 3 at the first level and of length n − 1, n, and n − 1 at the second level. I intended to come up with a code to firstly verify the length is 3, then find the longest length array within it for n, then finally verify each length.
For whatever reason my code won't compile but I'm not seeing an error message, just a red exclamation mark on the class. I assume this means there are multiple errors. If anyone could point them out it would be a massive help.
static boolean isValidTridiagonal ( double [][] m)
{
if (double [][]=new double [3][])
{
int n = 0;
for(int i = 0; i < m.length; i++)
{
if(m[i].length > n)
{
n = m[i].length;
if( (m[0].length = n-1) && (m[1].length = n) &&(m[2].length=n-1))
{
return true
}
else
{
return false
}
}
else
{
return false
}
}
Thanks very much!
I agree with Foolish in the comments that it's helpful to use an IDE that can highlight syntax errors and other problems with the code, it really makes a huge difference. Apart from that, another general strategy is to always code in "baby steps": do only the minimal thing to test if the code works, compile and test often. And if you still have troubles, you can always comment out chunks of your code when searching for the offending bits.
Having said that, the errors that I see in your code are:
if (double [][]=new double[3][])
If you want to test the length of the input, you can do if (m.length == 3)
In
if( (m[0].length = n-1) && (m[1].length = n) &&(m[2].length=n-1))
you're not testing for equality, but rather trying to put the values n-1 etc into m[0].length, which is not going to work. What you probably meant was
if( (m[0].length == n-1) && (m[1].length == n) &&(m[2].length==n-1))
In
return true
you're missing a semicolon. The compiler is whiny about things like that and unless you use an IDE or learn to interpret the compiler error messages, it can be really painful to find such errors.
Finally, of course, the answer by vasste provides a much simpler solution to your actual task, so it's worth looking into that :).
Why do you need all that loops? If all arrays cannot be null, than
static boolean isValidTridiagonal(double[][] m) {
return m.length == 3 && m[0].length == m[1].length - 1 && m[2].length == m[0].length;
}
You're missing a few braces at the end but, judging from your indentation, you just forgot to copy them.
You're missing semicolons from the end of the return lines.
The condition within this if statement if (double [][] = new double [3][]) is not a valid expression. You simply want to evaluate the length, which you can do like if (m.length == 3). You did the same thing later on.
The line including (m[0].length = n-1) && (m[1].length = n) && (m[2].length=n-1) is not valid because you are performing assignment (=) in all three cases. An equality check is the double equals operator ==.
You do not return a value in every case. You can fix this by adding return false; after the closing brace of your first if statement, i.e. the last line of the function.
This is enough to get your code to compile. As mentioned in another answer though, your logic is confusing and without actually tracing it through I would speculate that it will not work as you would expect.
If I have understood your requirements correctly, you can rewrite the entire function as:
static boolean isValidTridiagonal ( double [][] m)
{
return m.length == 3 &&
m[0].length + 1 == m[1].length &&
m[2].length + 1 == m[1].length;
}
A proper IDE - Netbeans, Eclipse, etc. - will give you fairly descriptive error messages to show you where you've gone wrong.
This is basically completely stylistic but I wish someone had pointed this out to me earlier. If you ever find yourself writing code in this form:
if( (m[0].length == n-1) && (m[1].length == n) && (m[2].length == n-1))
{
return true;
}
else
{
return false;
}
know that you can save yourself so many lines without losing any readability by instead writing:
return (m[0].length == n-1) && (m[1].length == n) && (m[2].length == n-1);

Displaying a string in an int array (for validation check)

I'm using a for loop as a form of validation check to make sure the input for the variable stScore is a number over 0 and under or equal to 100, example shown here, if the input isn't correct, the score parameter will be shown as 0:
for(int i = 0; i < 3; i++)
if ((stScore[i] > 0 && stScore[i] <= 100))
score[i] = stScore[i];
else
score[i] = 0;
My question is if there is any way to display a string (to say something like error!) in place of that 0 instead? Of course at the base of things you can't have an int array include a string, but I was wondering if there is a workaround for this.
Thanks
A workaround would be to ascribe some magic meaning to a particular int value that would never otherwise occur in your data. E.g., declare a constant:
private static final int INVALID_SCORE = -1;
Use it both when assigning:
if ((stScore[i] > 0 && stScore[i] <= 100))
score[i] = stScore[i];
else
score[i] = INVALID_SCORE;
And when printing:
System.out.println(score[i] != INVALID_SCORE ? score[i] : "Invalid score!");
The disadvantage is that it will cause problems if you forget to treat the value specially in later code that uses the data.
No, unfortunately you cannot :(. But we usually don't use 0 as an error code. In these situations I use Integer.MIN_VALUE to indicate an error.
So your code will be like this:
for(int i = 0; i < 3; i++)
if ((stScore[i] > 0 && stScore[i] <= 100))
score[i] = stScore[i];
else
score[i] = Integer.MIN_VALUE;
I suggest you not to use 0. Because 0, when it is an exit code, it usually means "OK". In C++, the main method returns 0 when the program exits with no errors. Alternatively, Integer.MAX_VALUE can be used as well.
For more readable code, you can declare a constant called ERROR:
final int ERROR = Integer.MIN_VALUE;
The best option would be to set any invalid inputs to -1. Then on output you could have an if statement the checks for the error value (-1) and outputs an appropriate error message.
It's bad practice to mix types in any sort of collection; avoid it whenever possible.
throw new IllegalArgumentException("your score is below zero");
That would seem to be appropriate

Error: variable might not have been initialised

I am doing a book exercise regarding the Ackermann function.
I have one question though. If I declare result but do not initialise it, the compiler complains that "variable result might not have been initialised".
int result;
When I set it to default to 0, it does not complain.
int result = 0;
I thought that when one declares a variable with type int it defaults to 0 automatically.
Here's the complete code:
public class Ackermann {
public static int ack(int m, int n) {
int result = 0;
//int result;
if (m == 0)
result = n + 1;
else if(m > 0 && n == 0)
result = ack(m-1, 1);
else if(m > 0 && n > 0)
result = ack(m-1, ack(m, n-1));
return result;
}
public static void main(String[] args) {
System.out.println(ack(3, 3));
}
}
Local variables are not initialized with default values. See the language specs for the ground truth.
it is very bad practice to not initialize variables. There is popular joke that fits to your case: John got 3 apples from his mother and 5 from his father. How many apples has John? If you are not good programmer, your answer will be 8. If you are good programmer, you will answer that we do not know how many apples had had john before obtaining apples from his Mother. Remember: always initialize variables and do not assume that they will be 0.
Fields in classes default to values (null, 0, false, etc.) Local variables however don't, you have to define them explicitly. A lot of people even disagree with not setting fields explicitly, because setting it shows the reader that you've actually thought about setting it to a value rather than just forgotten to set it, therefore potentially causing a bug somewhere down the line.

Is there any goto statement in Java? [duplicate]

This question already has answers here:
Is there a goto statement in Java?
(23 answers)
Closed 9 years ago.
I wrote a program in C++ with some goto statements. Now, I need to write the same program in Java. Is there any goto option in Java? If so, how it can be implemented? Is it same as the C++?
My program is:
#include<stdio.h>
#include<conio.h>
void main()
{
int i,j,k,w,l,q,d;
clrscr();
printf("\nEnter the limit:");
scanf("%d",&k);
for(i = 13; i <= k ; i++)
{
repeat:
j = i%10;
if (j != 0)
{
if(i < 99)
{
for(w = 1; w <= 9; w++)
{
l = 11*w;
if (l == i){
i++;
goto repeat;
}
}
}
if(i > 99)
{
for(q = 1; q<=9 ; q++)
{
d = 111*q;
if (d == i){
i++;
goto repeat;
}
}
}
printf("%d,",i);
}
}
getch();
}
No, Java does not have a goto operator, by design. It's considered harmful.
Your code could be rewritten with continue repeat in place of the goto repeat, if the repeat: label was placed just before the for loop.
E.g.
repeat: for(i=13;i<=k;i++)
and then
continue repeat;
instead of goto repeat
No Java doesn't have goto in active state (but in reserved state). You cannot use it in your program for now (it's a reserved keyword).
And avoid using it in C++ either. You can write your program using smartly placed continue and/or break for both the languages.
Short answer, No.
You can also refer this question
Although goto is a reserved word in Java it is not used in the Java language. But there is a label, an identifier that can be used in conjunction with the break or continue. The purpose of the label it to let an iteration to jump outside of the iteration, it is a bit like goto statement.
Code:
labelA:
// some loop {
continue labelA;
}
I wrote a program in C++ with some goto statements.
No, you didn't. C++ requires that main() returns int, and <stdio.h> is a C library (and conio.h a platform-specific C library). In C++, we spell it <cstdio>, and we don't normally use it anyway (because <iostream> is much more powerful and type-safe). However, your program is valid C.
Now,i need it to write the same program in java.
Good heavens, why? To the extent that I can figure out what your program is actually intended to do, it isn't anything useful at all. If this is for homework, your teacher is doing an incredibly bad job of explaining good coding style, from what I can see.
Is there any goto option in java ?
No, goto is not implemented in Java. They did this because you don't have a reason to use it. No, really. The fact that it's all over the Linux kernel doesn't mean you have a reason. (It doesn't mean they have a real reason, either.)
Your program can be written more simply, for example:
#include<stdio.h>
#include<conio.h>
void main()
{
int i,j,k,w,l,q,d;
clrscr();
printf("\nEnter the limit:");
scanf("%d",&k);
for(i=13;i<=k;i++)
{
j=i%10;
if (j == 0) continue;
if (i<99)
{
for(w=1;w<=9;w++)
{
l=11*w;
if (l==i) continue;
}
}
else
{
for(q=1;q<=9;q++)
{
d=111*q;
if(d==i) continue;
}
}
printf("%d,",i);
}
getch();
}
And the same basic approach will work in Java, too.
Although you really need to work on several other style issues. Please try to use real variable names, and restrict variable scope.
I do condone the use of goto on occasion. This is not one of those occasions. This particular problem can be solved without any kind of goto (break and continue are a goto, just a restricted form).
#include <iostream>
int main()
{
unsigned int lim;
std::cout << "Enter the limit: ";
std::cin >> lim;
std::cout << "\n";
if (lim > 999) {
std::cout << lim << " is too large. Truncating to 999.\n";
lim = 999;
}
// Why start at 13? Oh well.
for (unsigned int ii=13; ii <= lim; ii++) {
if (((ii % 10) != 0) &&
((ii < 100) ? (ii % 11) != 0 : (ii % 111 != 0))) {
std::cout << ii << ",";
}
}
std::cout << "\n";
return 0;
}
There are times where the clearest way to write a chunk of code involves break or continue. There are times where the clearest way to write a chunk of code involves a multi-level break or continue. While Java does provide such a mechanism, neither C nor C++ does.
As I said at the onset, I do condone the use of goto on occasion. The occasions are very, very rare:
To emulate a multi-level break or continue when that truly is the clearest way to write the code.
To deal with errors in a stupid programming environment that mandates single point of entry, single point of return.
To deal with errors in a programming environment that makes try, catch, and throw forbidden keywords.
To implement a finite state machine (but a loop around a switch usually quite nicely in this case).
You can do anything with label that you could do with goto. Labels as an Anti-Pattern This doesn't make it a good idea.
What you are trying to do here doesn't need nested loops which avoids the need to use labels at all.
Scanner in = new Scanner(System.in);
System.out.print("\nEnter the limit:");
int limit = in.nextInt();
for (int i = 12; i <= limit; i++) {
if (i % 10 == 0) continue;
if (i <= 99) {
// two digits the same.
if (i % 10 == i / 10 % 10) continue;
} else if (i <= 999) {
// three digits the same.
if (i % 10 == i / 10 % 10 && i % 10 == i / 100) continue;
} else {
System.err.println("Value " + i + " too large to check");
break;
}
System.out.printf("%d,", i);
}

Categories