How to avoid calling a function multiple times in Java? - java

I'm calling a function with different values to get a particular result. Is there any way so that I can reduce calling functions like this to improve performance and reliability in Java?
func(1,6);
func(4,0);
func(2,7);
func(5,0);
func(3,0);
private static void func(int printer,int printing){
if(printing == 0){
for(int j=1;j<=7;j++){
if(j!=printer){
arrayOdd.add(j);
}
}
}else{
for(int j=1;j<=7;j++){
if(j!=printer && j!=printing)
arrayOdd.add(j);
}
}
}

My first note is that you can replace your function with
private static void func(int printer,int printing){
for(int j=1;j<=7;j++){
if(j!=printer && j!=printing)
arrayOdd.add(j);
}
}
and it will behave the same.
My second note is that calling a function repeatedly will not have any effect on performance or reliability unless you are using recursion, in which case you may get the classic stack overflow error. Why do you want/need to call the function fewer times?

If the above function can be idempotent( same inputs always produce the exact same outputs) i would suggest memoization (https://java2blog.com/memoization-example-java/).
On seeing the function outputs, it looks like you are just removing the passed values from a fixed array of 7 digits. If thats all you are looking for, just remove the element from the array and memoize the function . That way the function will execute only 64 times worst case (64 different combinations for 2 digit combinations for 0,1,2 3,4 ,5,6,7 )

you can put the printer's values and printing's values in List or array ,but you need to put the parameters manually, as long as there is no logic hold the inputs.
I mean some thing like that
int final static THE_TIMES_YOU_CALLED_THE_FUNC=5;
List<int[]> list =new ArrayList<>(THE_TIMES_YOU_CALLED_THE_FUNC);
list.add(new int []{1,6});
list.add(new int []{4,0});
list.add(new int []{2,7});
list.add(new int []{5,0});
list.add(new int []{3,0});
for(int i=0;i<list.size();i++){
funk(list.get(i)[0],list.get(i)[]);
}
}
private static void func(int printer,int printing){
if(printing == 0){
for(int j=1;j<=7;j++){
if(j!=printer){
arrayOdd.add(j);
}
}
}else{
for(int j=1;j<=7;j++){
if(j!=printer && j!=printing)
arrayOdd.add(j);
}
}
}
in the end the compiler will call the func 5 times, and I don't see an advantege of my soultion, but you want in the end to write the func one time.

Related

New to Java, why doesn't this code work? i++ is 'dead code', and the function does not return a variable of desired type; even though it does

I am making a little program in Java that makes a program that acts like a "library", only with video games. In the program you shoud be able to add, delete and edit games; you shoud also be able to list off all the games in the "library".
To be able to delete and edit games, I have decided to implement a function that will return a list of all the elements in the list that matches the query String that I give it, and then the user will have to choose between a numbered list of all the returned results.
This is my code:
public static ArrayList<GameStorage> findElement(ArrayList<GameStorage> gameList, String query) {
ArrayList<GameStorage> temp = new ArrayList<GameStorage>();
for(int i = 0; i < gameList.size(); i++) {
if(gameList.get(i).getName().contains(query)) {
temp.add(gameList.get(i));
}
return temp;
}
}
I initialize an empty GameStorage ArrayList, and use this to store all the desired elements and then return it. However, this does not work at all and Eclipse says that the i++ part is supposedly 'dead code' (and this supposedly means that the code never is reached), the function also says that I do not return a result of the desired type ArrayList<GameStorage>, even though I do. I don't know what I've done wrong.
Could someone perhaps enlighten me?
return should be after your loop body, not the last statement. Because it is the last statement i++ is never reached. Change it like
for(int i = 0; i < gameList.size(); i++) {
if(gameList.get(i).getName().contains(query)) {
temp.add(gameList.get(i));
}
}
return temp;
You could also use a for-each loop like
for (GameStorage gs : gameList) {
if (gs.getName().contains(query)) {
temp.add(gs);
}
}
return temp;
And in Java 8+ you might implement the entire method1 with a filter and Collectors
public static List<GameStorage> findElement(List<GameStorage> gameList, String query) {
return gameList.stream().filter(x -> x.getName().contains(query))
.collect(Collectors.toList());
}
1And I would prefer to program to the List interface.
You can make your code shorter with java 8+ lambda's example below
gameList.forEach((k)->{
if(k.getName().contains(query)){
temp.add(k)
}
}

Android II JAVA Sorting An ArrayList of an object

First of all sorry if my English bad, its not my first language..
I'm working on and android app project, that needed to sort ArrayList of an object..so I made this method to deal with that...
Lets say that I have an object of Restaurant that will contain this data:
private String name;
private float distance ;
And I sort it using the value of the variable distance from lowest to highest:
public void sort(RArrayList<RestaurantData> datas) {
RestaurantData tmp = new RestaurantData();
int swapped;
boolean b = true;
while (b) {
swapped = 0;
for (int i = 0; i < datas.size()-1; i++) {
if (datas.get(i).getDistance() > datas.get(i+1).getDistance()) {
tmp = datas.get(i);
datas.set(i, datas.get(i+1));
datas.set(i+1, tmp);
swapped = 1;
System.err.println("Swapped happening");
}
}
if (swapped == 0) {
System.err.println("Swapped end");
break;
}
}
But when i try the program..the result of an ArrayList is still random, is there any problem with my logic to sort the ArrayList of an object..
Please Help...Thankyou..
Why not use the Collections.sort method?
Here's how you could do it in your project:
public void sort(RArrayList<RestaurantData> datas) {
Collections.sort(datas, new Comparator<RestaurantData>() {
#Override
public int compare(RestaurantData lhs, RestaurantData rhs) {
return lhs.getDistance() - rhs.getDistance();
}
});
}
The above solution is a bit "destructive" in the sense that it changes the order of the elements in the original array - datas. If that's fine for you go ahead and use it. Personally I prefer things less destructive and if you have the memory to spare (meaning your array is small) you could consider this solution which copies the array before sorting. It also assumes your RArrayList is an implementation of ArrayList or backed up by it:
public List<RestaurantData> sort(RArrayList<RestaurantData> datas) {
// Create a list with enough capacity for all elements
List<RestaurantData> newList = new RArrayList<RestaurantData>(datas.size());
Collections.copy(newList, datas);
Collections.sort(newList, new Comparator<RestaurantData>() {
#Override
public int compare(RestaurantData lhs, RestaurantData rhs) {
return lhs.getDistance() - rhs.getDistance();
}
});
return newList;
}
Another thing to consider is also to create a single instance of the Comparator used in the method, since this implementation will create one instance per call. Not sure if it's worth it though, because it will also be destroyed quite soon since the scope is local.
Here's the documentation for the Collections api
One last thing, the comparator simply needs to return a value less than 0 if the elements are in the right order, bigger than 0 if they're in the wrong order or 0 if they're the same. Therefore it seems to be that it's enough to simply subtract the distances of each restaurant. However, if this isn't the case, please implement the comparator suiting your needs.

Java String Insertion Sort Not Working As Desired

My objective is to create a working insertion sort that can handle strings and integers using the array given to us in the main method. For this example I called it list.
public class insort{
public static void main(String[]list){
sort(list);
printsort(list);
}//main
public static void sort(String[]list){
for (int index = 1; index < list.length; index++){
int key = list[index];
int position = index;
while (position > 0 && key.compareTo(list[position-1]) < 0){
list[position] = list[position-1];
position--;
}//while
list[position] = key;
}//for
}//sort
public static void printsort(String[]list){
while ( i < list.length){
System.out.print(i);
}//while
}//printsort
}//insort
Some of the things to note for successful compilation:
The 'i' in the 'printsort' method is not declared and initialized. You will need to something like int i=0 before you start the while loop.
Also the while loop variable needs to be updated inside the loop so as to meet an end condition. The end condition will help you stop the loop from going into an infinite loop. So you will need an i++ after your System.out.print().
In the System.out.print() you are passing the variable i which will print the numbers from 0 to length-1 instead of the Strings in your list array. So you will need something like System.out.print(list[i]).
In the 'sort' method you have int key = list[index], the RHS will return a String object instead of an int that you have on the LHS. So String key = list[index] is what you need there.
I haven't checked the code for proper working of insertion sort. Just pointed out some syntactic mistakes that will help you compile the code.
All the best :)
You mixed couple things. It would be much easier to sort int or Integer objects, than String objects (especially that you need to be sure that String[] list contains only numerics), however if you want to sort String objects you need to change couple things:
you try to assign a reference to String object to primitive variable
int:
int key = list[index];
You can change it for example to:
int key = Integer.valueOf(list[index]);
or change list from String[] to int[].
you try to use compareTo() method on primitive variable int:
int key = list[index];
(key.compareTo(list[position-1])) < 0
Primitive variables doesn't have methods. You can solve the 1 and 2
problems with usage of Integer object instead of int variable:
Integer key = Integer.valueOf(list[index]);
or, if you want to stay with int variables, try with:
key < list[position-1]
instead of:
(key.compareTo(list[position-1])) < 0
your while loop is wrong:
while ( i < list.length){
System.out.print(i);
}//while
try with:
for(String element : list){
System.out.println(element);
}
to print every element of list.
also you changed a main method, from main(String[] args) to main(String[] list), and you try to use sort on String[] list. You should create new String[] array, and try with it, for example:
String[] list = {"4","6","1","8"};
sort(list);

Sorting two dimensional String array as per LastName then on FirstName without using any API

Hi all I am very new for the Java. I would like to sort below array of strings as per LastName then on FirstName without use of any API i.e. I am not supposed to use Arrays.sort() , compareTo(), equals() etc..
Input array String
String [][]name={{"Jen","Eric"},
{"Brain","Adams"},
{"Jon","Methew"},
{"Antino","Ronald"},
{"Cris","Ronald"}
};
my out put should be like.
Brain,Adams
Jen,Eric
Jon,Methew
Antino,Ronald
Cris,Ronald
Please Help.
public class StringArraySort {
public static void main(String[] args) {
//System.out.println(str.length);
String [][]name={{"Jen","Eric"},
{"Brain","Adams"},
{"Jon","Methew"},
{"Antino","Ronald"},
{"Cris","Ronald"}
};
String []str1= new String [name.length];
String []str2= new String [name.length];
for(int i=1;i<name.length;i++)
{
int j=i;
str1[i]=name[i][j];
str2[i]=name[i-1][j];
//System.out.println(str1[i]+" "+str2[i]);
}
/*for(String tmp:name)
{
char a[] = new char[tmp.length()] ;
//System.out.println(tmp);
for(int i=0;i<tmp.length();i++)
{
a[i]=tmp.charAt(i);
System.out.println(a[i]);
}
}*/
}
}
I will not give you any code, as this is clearly an assignment, but here's some general guidance:
Don't try to put everything into main. You may not be allowed to use any exiting API, but you can define your own! Write your own compare and sort methods.
Start with a method compare(String, String) -> int, or isSmaller(String, String) -> boolean. Use String.toCharArray to get the individual characters and compare them, in pairs from both strings. Make sure to handle the case of the strings having different lengths.
Now write a method compare(String[], String[]) -> int. This can look very similar to the above (in fact, you could make a generic one for both), but it might be simpler to make this one specific for the "lastname-firstname" case, particularly since here you want to sort by the second element first.
Finally, write your own sort method. An in-place bubble sort should be the easiest and the algorithm can easily be found on the internet. Other sort algorithms are faster, but if speed is an issue, the requirement not to use any API is nonsensical in the first place. If you want to score bonus-points, though, you can try to implement an in-place quick sort, but only after you've got it running with the bubble sort.
Also, you should test each of those methods individually. Don't try to run your sort method before you've made sure your compare methods actually work. Call them individually with different outputs and see whether they yield the correct result.
public class NameSort {
public static void main(String[] args) {
String [][] names={{"Jen","Eric"},
{"Brain","Adams"},
{"Jon","Methew"},
{"Antino","Ronald"},
{"Cris","Ronald"}
};
for(int m=0;m<names.length;m++)
{
for(int n=m+1;n<names.length;n++)
{
if(myCompare(names[m][1],names[n][1])==1)
{
swap(names, names[m], names[n], m, n);
}
else if (myCompare(names[m][1],names[n][1])==0)
{
if(myCompare(names[m][0],names[n][0])==1)
{
swap(names, names[m], names[n], m, n);
}
}
}
}
for (int i=0;i<names.length;i++)
{
System.out.println(names[i][0]+" " +names[i][1] );
}
}
public static void swap(String [][] names,String[] a,String[] b,int m,int n)
{
names[n]=a;
names[m]=b;
}
public static int myCompare(String a, String b)
{
int minLength= a.length()<b.length()?a.length():b.length();
for(int i=0;i<minLength;i++)
{
if(a.charAt(i)>b.charAt(i))
{
return 1;
}
else if(a.charAt(i)<b.charAt(i)){
return -1;
}
}
if(a.length()>minLength)
return 1;
else if (b.length()> minLength )
return -1;
else
return 0;
}
}
In order to let you learn at least something, I am going to give you the answer in psuedo-code and let you do the coding. The solution is based on bubble sort and comparing names (=Strings) by looping on their characters
in bubble sort we iterate over the array, in each iteration, we compare two adjacent cells and possibly swap them so that they are in the correct order.
at the end of the 1st iteration, the biggest cell will be in the correct position (=last). so we start another iteration but skip the last cell. by the end of the 2nd iteration, the 2nd biggest cell will in its correct position. we cotinue iterating, each time going over one less cell until there are no more cells to iterate over.
I give you the comparing method:
The solution assumes you are allowed to call length() and charAt() methods of String class.
/**
* returns negative, zero or positive value
* if s1 is smaller, equal or bigger than s2, respectively
* comparison is lexicographical
*/
static int compareStrings(String s1, String s2)
{
int i = 0;
for (i = 0; i < s1.length() && i < s2.length(); i++) {
int diff = s1.charAt(i) - s2.charAt(i);
if (diff != 0) return diff;
}
if (i == s1.length()) {
if (i == s2.length()) return 0; // equal lengths
else return 1; // exhausted s2 before s1
}
return -1; // exhausted s1 before s2
}
seeing the loop in your code, I think one last note is in order: you should be aware that arrays in Java start with index 0 and the last cell is at length-1.

Find and print the product of all the entries in array

Okay I have tried to write a simple Java code in BlueJ, that finds and prints the product of all the entries in data such as if data is {1,2,3,4} then the result will be 24.
And my code is below:
public class Product {
public static int[] product(int[] a) {
int [] s = new int[a.length];
for (int i =0; i< a.length; i++)
s[i] = a[i]*a[i];
return s; //the definition of your method...
}
public static void main(String[] args) {
//calling the method to seek if compiles
int[] results = Product.product(new int[] { 1,2,3,4 });
//printing the results
System.out.println(java.util.Arrays.toString(results));
}
}
The above code is giving me the square of each number, which is not what I want to have, somehow I have modify the code that the result will be 24 but I couldn't figure it out, anyone knows how to do it?
First of all, if you are first writing Java it is important to know that variable, function and class names are quite important. Please note that having Product.product() is not a good idea, since the function name is almost the same as the class name. Anyway, regarding your code. Your code is indeed returning the square of your input, what you would want is the following:
public class Product {
public static int getProduct(int[] input) {
int total = 1;
for (int v : input) {
total *= v;
}
return total;
}
}
This will return an integer value with the product of your input array. This also uses a for-each loop instead of a regular for-loop for readability. Also you don't need the index in this case. Good luck with it!
First, your product method needs to return an int rather than an int [].
You need to maintain the product as a variable. You can set it to 1 initially, and then multiply it by each element of the a array in turn; then you just return this value.

Categories