Is there a tool or a way to count the number of branches in a given Java class? For example, I want to count the number of branches in the following simple Java class:
public class Testt {
public boolean getTest(int x) {
if (x > 5) {
return true;
} else {
return false;
}
}
public int getTest1(int x) {
int t = 0;
if (x == 10) {
t = 1;
} else if (x == 8) {
t = 3;
} else {
t = 11;
}
return t;
}
}
The term you are looking for is "cyclomatic complexity".
Cyclomatic complexity is a software metric (measurement), used to
indicate the complexity of a program. It is a quantitative measure of
the number of linearly independent paths through a program's source
code.
If you are using Eclipse as your IDE there is a plugin called Eclipse Metrics that can give this kind of information.
Related
I was recently asked this question in an interview to find the median from data stream of numbers and I was able to come up with Priority Queue solution as shown below:
public class MedianFinder {
private final PriorityQueue<Long> min = new PriorityQueue<>();
private final PriorityQueue<Long> max = new PriorityQueue<>(Collections.reverseOrder());
public void addNum(long num) {
max.offer(num);
min.offer(max.poll());
if (max.size() < min.size()) {
max.offer(min.poll());
}
}
public double findMedian() {
if (max.size() == min.size())
return (max.peek() + min.peek()) / 2.0;
else
return max.peek();
}
}
Now interviewer wanted me to optimize addNum method because it has lot of O(log n) operations (around 5) and he wanted to see if we can optimize it any further so that we have fewer O(log n) operations? Is there anything we can do here to optimize addNum method?
This can reduce the average number of offer call from 2.5 to 1.5 and poll call from 1.5 to 0.5. Overall reduce the average number of O(log n) operations from 4 to 2.
public void addNum(long num) {
if(!max.isEmpty() )
{
if(max.size() == min.size())
{
if(num > max.peek())
{
min.offer(num);
max.offer(min.poll());
}
else
{
max.offer(num);
}
}
else
{
if(num > max.peek())
{
min.offer(num);
}
else
{
max.offer(num);
min.offer(max.poll());
}
}
}
else
{
max.offer(num);
}
}
A more compact version (same logic)
public void addNum(long num) {
if(!max.isEmpty())
{
(num > max.peek() ? min : max).offer(num);
if(min.size() > max.size())
{
max.offer(min.poll());
}
else if(max.size() - min.size() > 1)
{
min.offer(max.poll());
}
}
else
{
max.offer(num);
}
}
I get the numbers scanned in correctly, but the methods aren't working right. First one doesn't do anything and the second one goes into an infinite loop.
Method called is not performing correctly. I am not sure what to do.
import java.util.Scanner;
public class testSequence {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
int enterNumber = scan.nextInt();
System.out.println("1 for Iteration, 2 for Recursion: ");
int type = scan.nextInt();
if (type == 1){
computeIteration(enterNumber);
} else if (type == 2){
computeRecursion(enterNumber);
}
}
public static int computeIteration(int enterNumber) {
int answer;
int multiplier = 1;
int count = 0;
int addend = 0;
if (enterNumber == 0) {
count++;
return enterNumber;
} else if (enterNumber == 1) {
count++;
return enterNumber;
} else {
for (int i = 0; i <= enterNumber; i++) {//need to adjust "i" for counter correction
enterNumber = (multiplier * 2) + addend;
addend = multiplier;
multiplier = enterNumber;
count += 1;
}//end for loop
answer = enterNumber;
}//end else
return answer;
}//end computeIteration
public static int computeRecursion(int n) {
int count = 0;
if (n == 0) {
count++;
return 0;
} else if (n == 1) {
count++;
return 1;
} else {
count++;
return computeRecursion(2 * (n - 1)) + computeRecursion(n - 2);
}
}//end computerRecursion()
}//end Sequence()
You're never printing the answer.
if (type == 1){
computeIteration(enterNumber);
} else if (type == 2){
computeRecursion(enterNumber);
}
Note how you're calling the functions, but you never do anything with the result.
You probably meant:
if (type == 1){
System.out.println(computeIteration(enterNumber));
} else if (type == 2){
System.out.println(computeRecursion(enterNumber));
}
Or, if you wanted to get fancy:
UnaryOperator<Integer> f =
type == 1 ?
computeIteration
: computeRecursion;
System.out.println( f.apply(enterNumber) ) ;
Just an addition since you asked. I'm using the ternary operator because I need to choose between 2 things. In a case like this, it's neater than a full if statement.
The UnaryOperator is a functional interface. Basically, using them, you can save a function inside a variable. This is useful where in cases like this, you want to choose between 2 functions whose signatures are the same (both of your functions take an int, and give back an int), and use the result.
I save one of your functions into f, then call it by writing f.apply(9) (apply "applies" the arguments to the function; calling it).
Note you shouldn't use functional interfaces just for kicks, as they can make code less clear. When used properly though, they can make code much simpler; especially when paired with anonymous functions.
I try to refactor a code so that it will use separate methods to do some calculations. Just to make it clear.
What I want to know is, is it a good practice or a bad one to write a separate method to find out a simple thing like a number is odd or even ?
The original code is ,
int n = 11;
if (n % 2 == 0) {
System.out.println("Not selected");
} else {
boolean isPrime = true;
if (n == 0 || n == 1) {
isPrime = false;
} else {
int i = 2;
double a = Math.sqrt(Math.abs(n));
while (i <= a) {
if (n % i == 0) {
isPrime = false;
}
++i;
}
}
if(isPrime){
System.out.println("Prime it is");
}
}
The refactored code is,
int n = 11;
if (isEven(n)) {
System.out.println("Not selected");
} else {
if (isPrime(n)) {
System.out.println("Prime it is");
}
}
public static boolean isEven(int n) {
return n % 2 == 0 ? true : false;
}
public static boolean isPrime(int n){
if(n==0 || n==1)return false;
int i=2;
double a = Math.sqrt(Math.abs(n));
while(i<=a){
if(n%i==0){
return false;
}
++i;
}
return true;
}
It's generally considered good practice to break code down into separate methods for things like readability, length, or cyclomatic complexity, especially if you are not changing how the code works.
Boolean expressions, like what you have extracted, are often good choices for a quick extract function refactor. It allows a reader of the code base to know why a boolean expression is important or what it does by being able to read a descriptive function name versus complex domain related boolean math which they may not care to know the intricate details of.
A good book about commonly considered best practices in Java for code organization is a book called Clean Code. It's a pretty easy and enjoyable read, I would suggest it.
This is referred to as functional decomposition, and (in my opinion) is always good practice.
Not only is it easier to read, you can find problems in that code easier, since you can now easily test each section individually.
For example, you can now make sure isEven actually returns an even number. If a problem arises later on, you know that method is not the issue. This is called unit testing.
I suggest switching
if(isEven(n)) {
} else {
if(isPrime(n)) {
}
}
to
if(isEven(n)) {
} else if(isPrime(n)) {
}
Since it gives the same functionality, yet saves you a line.
Although, if you were counting 0 as being even, you wouldn't even need isPrime; if it's not even, it has to be prime. You wouldn't need to perform all the processing in isPrime:
if(isEven(n)) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
To make it a bit cleaner:
String result = isEven(n) ? "Even" : "Odd";
System.out.println(result);
Im quite the novice when it comes to programming and im trying to translate this PHP algorithm to Java.
function isPrime($n)
{
$i = 2;
if ($n == 2) {
return true;
}
while ($i < $n) {
if ($n % $i == 0) {
return false;
}
$i++;
}
return true;
}
for ($i = 3; $i < 100; $i++) {
if (isPrime($i)) {
echo $i;
}
}
The only thing i've come up with so far is this.
public class Primtal {
public static boolean isPrime(int n)
{
int i = 2;
if (n == 2) {
return true;
}
while (i < n) {
if ( n % i == 0) {
return false;
}
i++;
}
return true;
}
for(int i = 3; i < 1000; i++){
if (isPrime(i)) {
System.out.print(i);
}
}
}
I realize this look really stupid but i really need to get this to work. I think the problem lies mostly with the for loop as im currently getting the error illegal start of type there. Im not really sure how to translate this to Java and i would appreciate any help i can get.
I believe the problem with your code is that you've put a for loop in the middle of class declaration, which is incorrect - it needs to be inside some method. It seems logical in this case to put it in main(), so it's executed when you run your program. Maybe something like this:
public class Primtal
{
public static boolean isPrime(int n)
{
int i = 2;
if(n == 2)
{
return true;
}
while(i < n)
{
if(n % i == 0)
{
return false;
}
i++;
}
return true;
}
public static void main(String[] args)
{
for(int i = 3; i < 1000; i++)
{
if(isPrime(i))
{
System.out.print(i);
}
}
}
}
(Note the addition of public static void main(String[] args) in the second half of the code.)
Oracle has official tutorials on how Java programs need to be structured, and other basics of the language. You can find the one related to the main method here. Or, to start from the beginning, the full tutorial starts here.
you can't write the for loop
for(int i = 3; i < 1000; i++){
if (isPrime(i)) {
System.out.print(i);
}
}
directly inside a class.
i believe what you wish to do is to have a main method, in which you can have the for loop
Your for loop needs to be within a method of some sort,so you can put it in the main method:
public class Primtal {
public static void main(String [] args)
{
for(int i = 3; i < 1000; i++)
{
if (isPrime(i)) {
System.out.print(i);
}
}
public static boolean isPrime(int n)
{
int i = 2;
if (n == 2) {
return true;
}
while (i < n) {
if ( n % i == 0) {
return false;
}
i++;
}
return true;
}
}
The problem is that your for loop isn't in a method. Enclose it in a main method.
public static void main(String[] args) {
// Your for loop here
}
Also, change print to println, or else all the numbers will appear concatenated together on one line.
I beginner in Java and I ask tell me some words about Java tradition of writing generic code. I wrote helper class for pushing items into generic sorted collections in code below and I want to know it is accepted? Or I should extends some base class of collections? Or other ways to welcome more in Java?
package com.rkovalev.Helper;
import java.util.Comparator;
import java.util.List;
public abstract class ListExtensions {
public static <T> void addOnCompare(List<T> collection, T item, Comparator<T> comparator) {
synchronized(collection) {
int i = 0;
int size = collection.size();
if (size == 1) {
int diff = comparator.compare(item, collection.get(0));
switch(diff) {
case 1: i++; break;
default: break;
}
} else {
int range = size - 1;
i = size / 2;
int left = 0;
int right = range;
while(true) {
if (i <= 0) { i = 0; break; }
if (i > range) { i = range; break; }
int diff = comparator.compare(item, collection.get(i));
if (diff == 0) break;
else {
if (diff == -1) right = i;
if (diff == 1) left = i;
int near = i + diff;
if (near < 0) { i = 0; break; }
if (near > range) { i = range + 1; break; }
int diff_near = comparator.compare(item, collection.get(near));
if (diff_near == 0) { i = diff_near; break; }
if (diff_near == diff) {
int step = (right-left)/2;
if (step == 0) step = 1;
switch(diff){
case -1:
right = i;
i = i - step; break;
case 1:
left = i;
i = i + step; break;
}
} else if (diff > diff_near) {
i = near; break;
} else { break; }
}
}
}
collection.add(i, item);
}
}
}
If you want to make extra "generic" functionality available for all collection classes, then writing the functionality as a static method in a "helper" class is the right way to go.
Adding the method to a base class of the existing collection classes would not work. It would entail modifying the standard Java class library, and nobody in their right mind would do that. (It is technically possible, but you would be creating a portability nightmare for your code. Not to mention legal issues if you used the trademarked term "Java" in connection with your code.)