Array Search of Generics java - java

I am trying to search an array of any data type (Int, Strings, Chars, etc...) to see if there exist an element that matches the one you input. You should return the index of the matching element. There are two classes being used.
The error I get is:
"Cannot make a static reference to the non-static method find(Object[], Object) from the type ArraySearch"
Its suggestion is to make the method static, however, doing that gives me an error in the Search class:
"Cannot make a static reference to the non-static type E".
Search Class:
public class ArraySearch<E> {
public int find (E[] array, E item) {
int index = 0;
for (int i = 0; i < array.length; i++) {
if (array[i].equals(item)) {
System.out.println("There is a element " + array[i] +
" at index " + i);
index = i;
break;
}
}
return index;
}
}
Runner Class:
public class ArraySearchRunner {
public static void main(String[] args) {
String[] strings = new String[]{"Jim", "Tim", "Bob", "Greg"};
Integer[] ints = new Integer[]{1, 2, 3, 4, 5};
ArraySearch.find(strings, "Bob");
ArraySearch.find(ints, 4);
}
}
What is the best solution in this case?
Thanks,

You need to create an instance of your class to invoke the instance methods. Something like this:
class Demo {
public void show() { }
}
new Demo().show();
Now, I leave it to you to instantiate your generic class.
Also, your find() method is broken. If an element is not found, it will return an index = 0. Which is a valid index in array. You should rather initialize the index to -1:
int index = -1;
Regarding your attempt to make the method static, it will give you error, because the type parameters are not applicable for static members of a class.
From Java Generics FAQs - Angelika Langer:
The scope of a class's type parameter is the entire definition of the class, except any static members or static initializers of the class. This means that the type parameters cannot be used in the declaration of static fields or methods or in static nested types or static initializers.

public class ArraySearch<E>
{
public int find (E[] array, E item)
{
int c = 0;
for (int i = 0; i < array.length; i++)
{
if (array[i].equals(item))
{
c++;
}
}
System.out.println("There is a element " + item +
" repeated " + c + " time(s)");
return c;
}
public static void main(String[] args)
{
String[] strings = new String[]{"Jim", "Tim", "Bob", "Greg","Bob"};
String[] strings2 = new String[]{"Jim", "Tim", "Bob", "Greg","Bob"};
Integer[] ints = new Integer[]{1, 2, 3, 4, 5,2};
Double[] dbl= new Double[] {1.2,3.6,8.4,8.4,8.4,3.6};
ArraySearch arr = new ArraySearch();
arr.find(strings, "Bob");
arr.find(strings, "Tim");
arr.find(ints, 2);
arr.find(dbl, 8.4);
enter code here
}
}

Related

Visibility Control of the variables

package Array;
public class ArrayLesson1
{
static int[] array = { 10, 20, 30, 40 };
public static void main(String[] args) {
int i = 0;
System.out.println("While Loop Result");
while (i < 4) {
int c = array[i] * array[i];
System.out.println("Resutl = " + c);
i++;
}
subclass obj = new subclass();
obj.loopj();
obj.loopk();
}
}
class subclass {
public static void loopj() {
for (int j = 0; j < 4; j++) {
int result = array[j] * array[j];
System.out.println("FOR Loop J Result");
System.out.println("Result = " + result);
}
}
static void loopk() {
for (int k = 0; k < 4; k++) {
int result2 = array[k] + array[k];
System.out.println("FOR Loop K Result");
System.out.println("Result = " + result2);
}
}
}
From the above code, I couldn't access the "array" from the class "ArrayLesson1".
Below you can find the Output:
While Loop Result
Resutl = 100
Resutl = 400
Resutl = 900
Resutl = 1600
I am getting below error.
Exception in thread "main" java.lang.Error: Unresolved
compilation problems: array cannot be resolved to a variable array
cannot be resolved to a variable
at Array.subclass.loopj(ArrayLesson1.java:40)
at Array.ArrayLesson1.main(ArrayLesson1.java:25)
You have declared array in your ArrayLesson1 class, which is not visible to your subclass so you are getting compilation error.
You have couple of options,
1) Create constructor in your subclass to accept array as an argument and create a local variable in your subclass and pass array from ArrayLesson1 to your subclass like this:
//in subclass
private int [] array;
public subclass(int [] array) {
this.array = array;
}
So call like this in your ArrayLesson1 class like this:
subclass obj=new subclass(array); // Pass array like this
2) Modify loopj() and loopk() method to accept array as a parameter like this:
public static void loopj(int [] array) {
//Codes here
//
and call it in your ArrayLesson1 like this:
obj.loopj(array);
3) Or if you want to use static reference then you need to use with classname.variablename before using it, like this:
ArrayLesson1.array[j]
Let me know if this helps.

How to make generic Counting Sort Method?

Okay I am a pretty beginner java coder, and I am doing an assignment where I am stuck. I need to create a generic method (sort) that sorts a Type array according to frequency, basically, I am taking the CountingSort Algorithm and making it a generic method. This is where I am lost. I can't seem to figure out how to do this.
Here is a link to my instructions,
https://classes.cs.siue.edu/pluginfile.php/7068/mod_assign/intro/150mp08.pdf
Code:
Driver Class
package mp08;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Lists array = new Lists();
array.populateLists();
System.out.println("Original Int List: \n");
array.sort(Lists.intList);
System.out.println("Sorted Int List: \n");
}
}
Lists Class
package mp08;
import java.util.Arrays;
import java.util.Random;
public class Lists {
public static Integer[] intList;
public static Integer[] sortedintList;
public static Integer[] frequency;
public static Character[] charList;
public static Character[] sortedcharList;
public static int MAX_SIZE = 101;
public static int lengthInt;
public static int lengthChar;
public Lists(){
this.intList = new Integer[MAX_SIZE];
this.sortedintList = new Integer[MAX_SIZE];
this.charList = new Character[MAX_SIZE];
this.sortedcharList = new Character[MAX_SIZE];
this.frequency = new Integer[MAX_SIZE];
this.lengthInt = 0;
this.lengthChar = 0;
}
//Makes random integer for populated lists method.
public int randomInt(int min, int max){
Random rand = new Random();
int randomNum = rand.nextInt((max-min)+1)+min;
return randomNum;
}
//Makes random character for populated lists method.
public char randomChar(){
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int N = alphabet.length();
Random rand = new Random();
char randomLet = alphabet.charAt(rand.nextInt(N));
return randomLet;
}
//Populates intList and charList with random values.
public void populateLists(){
for (int i = 0; i < MAX_SIZE; i++) {
intList[i] = randomInt(1,100);
lengthInt++;
}
for (int i = 0; i < MAX_SIZE; i++) {
charList[i] = randomChar();
lengthChar++;
}
}
//Returns sorted array
public Integer[] sorted(){
return intList;
}
public static <T> void sort(T[] array) {
// array to be sorted in, this array is necessary
// when we sort object datatypes, if we don't,
// we can sort directly into the input array
Integer[] aux = new Integer[array.length];
// find the smallest and the largest value
int min = 1;
int max = 101;
// init array of frequencies
int[] counts = new int[max - min + 1];
// init the frequencies
for (int i = 0; i < array.length; i++) {
counts[array[i] - min]++;
}
// recalculate the array - create the array of occurence
counts[0]--;
for (int i = 1; i < counts.length; i++) {
counts[i] = counts[i] + counts[i-1];
}
/*
Sort the array right to the left
1) Look up in the array of occurences the last occurence of the given value
2) Place it into the sorted array
3) Decrement the index of the last occurence of the given value
4) Continue with the previous value of the input array (goto set1),
terminate if all values were already sorted
*/
for (int i = array.length - 1; i >= 0; i--) {
aux[counts[array[i] - min]--] = array[i];
}
}
public static void main(String[] args) {
Integer [] unsorted = {5,3,0,2,4,1,0,5,2,3,1,4};
System.out.println("Before: " + Arrays.toString(unsorted));
Integer [] sorted = sort(unsorted);
System.out.println("After: " + Arrays.toString(sorted));
}
}
I obviously have not finished my driver class yet and I would appreciate any help I can get!
There's no generic way for any Comparable type to get its ordinal number. Sometimes such numbers do not exist at all (for example, String is Comparable, but you cannot map any String to the integer number). I can propose two solutions.
First one is to store counts not in the array, but in TreeMap instead creating new entries on demand (using Java-8 syntax for brevity):
public static <T extends Comparable<T>> void sort(T[] array) {
Map<T, Integer> counts = new TreeMap<>();
for(T t : array) {
counts.merge(t, 1, Integer::sum);
}
int i=0;
for(Map.Entry<T, Integer> entry : counts.entrySet()) {
for(int j=0; j<entry.getValue(); j++)
array[i++] = entry.getKey();
}
}
public static void main(String[] args) {
Integer[] data = { 5, 3, 0, 2, 4, 1, 0, 5, 2, 3, 1, 4 };
System.out.println("Before: " + Arrays.toString(data));
sort(data);
System.out.println("After: " + Arrays.toString(data));
Character[] chars = { 'A', 'Z', 'B', 'D', 'F' };
System.out.println("Before: " + Arrays.toString(chars));
sort(chars);
System.out.println("After: " + Arrays.toString(chars));
}
Such solution looks clean, but probably not very optimal (though its advantage is that it does not care whether all numbers are from 1 to 100 or not).
Another possible solution is to create some additional interface which defines ordering for given type:
public interface Ordering<T> {
int toOrdinal(T obj);
T toObject(int ordinal);
}
public class IntegerOrdering implements Ordering<Integer> {
#Override
public int toOrdinal(Integer obj) {
return obj;
}
#Override
public Integer toObject(int ordinal) {
return ordinal;
}
}
public class CharacterOrdering implements Ordering<Character> {
#Override
public int toOrdinal(Character obj) {
return obj;
}
#Override
public Character toObject(int ordinal) {
return (char)ordinal;
}
}
Now you may make your sort method accepting the ordering parameter:
public static <T> void sort(T[] array, Ordering<T> ordering) { ... }
Every time you need to get counts array index by T object, just call ordering.toOrdinal(object). Every time you need to get object by array index, just use ordering.toObject(index). So, for example, instead of
counts[array[i] - min]++;
Use
counts[ordering.toOrdinal(array[i]) - min]++;
And call the sorting method like this:
sort(characterArray, new CharacterOrdering());
sort(integerArray, new IntegerOrdering());

JAVA Pass by reference error in method

I was trying to perform sorting of integers in an array and it worked fine.
But when i try to modify the program by including a "pass by reference" concept via a method, it is throwing error "cannot find symbol".
I am new to JAVA and learning by my own, Please help me with what I am doing wrong here.
import java.util.*;
import java.io.*;
public class Sort {
public static void main(String[] args) {
Sort obj = new Sort();
Scanner in = new Scanner(System.in);
int i, p, k, arr[];
arr = new int[10];
System.out.println("Enter the numbers for sorting \n");
for (i = 0; i < 5; i++) {
arr[i] = in.nextInt();
}
for (i = 0; i < 5; i++) {
for (p = 0; p < 5; p++) {
if (arr[i] < arr[p]) {
/*
* moving the below block for swapping to a new method. k =
* arr[i]; arr[i]= arr[p]; arr[p]= k;
*/
obj.swap(obj);
}
}
}
System.out.println("\n");
for (i = 0; i < 5; i++)
System.out.println(arr[i]);
}
public void swap(Sort m) {
m.k = m.arr[i];
m.arr[i] = m.arr[p];
m.arr[p] = m.k;
}
}
The error I am getting is :
"Sort.java:44: error: cannot find symbol
m.k = m.arr[i];
^
"
Similarly 10 such errors for other variables as well.
You are trying to use index variables (i and p) that don't exist in the context you are trying to use them (inside swap() method body) as well as members of Sort (k and arr) which don't exist. The scope of all these, you have limited to the method body of main():-
public void swap(Sort m) {
m.k = m.arr[i]; //No 'i' in swap(). No 'k' or 'arr' in 'm'(an instance of 'Sort')
m.arr[i] = m.arr[p]; //No 'p' in swap()
m.arr[p] = m.k;
}
Short-term Solution
Change your swap() method to
//Now accepting in i and p
public void swap(Sort m, int i, int p) {
m.k = m.arr[i];
m.arr[i] = m.arr[p];
m.arr[p] = m.k;
}
then call it like this
obj.swap(obj, i, p); //pass in i and p
and move your Sort variables to be accessible members of Sort
public class Sort {
public static int k; //now accessible with m.k
public static int[] arr = new int[10]; //now accessible with m.arr
...
}
Lastly, is it intentional that your array is 10 long but you only fill it with 5 numbers?
Pass-by-Reference
There is no "pass-by-reference" in Java. Everything is passed by value. The confusing thing is that what is passed by value is technically a reference to the object, meaning you get strange effects like you can edit the object but not reassign it.
Solution: move the stuff back from the swap method to where it was.
Alternatively, provide the necessary values as parameters to swap.

Printing Values in an Array in Reverse

My code is designed to print the values if the array in order and then reverse order. However, I also have to At a minimum use the following method headers when writing your methods:
public static int printOriginalArray(int[] list)
public static int printInReverse(int[] list)
I got the code running! I get it now!! It just clicked!! Yes!!! :-) Now my method is not exactly accurate though correct? I should have 2 methods instead of 1 and I need to rewrite it so it reverses the numbers, not swaps.
public class Assignment01a {
public static void main (String[] args) {
int[] numbers = {4, 5, 6, 7};
System.out.println("The list in order is: ");
for (int num: numbers)
System.out.println(num + " ");
swap(numbers, 0, 3);
for (int num: numbers)
System.out.println(num + " ");
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr [i] = arr [j];
arr [j] = temp;
}
}
First, all methods need to be declared inside some class. Here, your swap method is being declared inside the Assignment01a class. Furthermore, there are static methods, which are declared by having the static keyword after the public keyword (as you have for your swap method). A static method can be called from main() directly (from a "static context") . Non-static methods however need to be invoked on/from object instances. These are methods without the static keyword and they can be thought of as belonging to a specific object.
Ok, now I corrected it the way you wanted it to work. Since your methods are declared so that they return int value I assumed it's for error checking. If method returns anything but 0 program will let you know something went wrong. It looks like this:
public class Assignment01a {
public static void main (String[] args) {
int[] numbers = {4, 5, 6, 7};
if (printOriginalArray(numbers) != 0)
System.out.println("ERROR!");
if (printInReverse(numbers) != 0)
System.out.println("ERROR!");
System.out.println("\nProgram completed successfully!");
}
public static int printOriginalArray(int[] list) {
System.out.println("The list in order is: ");
for (int num: list)
System.out.print(num + " ");
return 0;
}
public static int printInReverse(int[] list) {
System.out.println("\nThe list in reverse order is:");
for (int i = list.length-1; i >= 0; i--) {
System.out.print(list[i] + " ");
}
return 0;
}
}
I hope that clarified your problem, if you have any other question feel free to ask.

Constructor undefined

I have a problem with my code, in that it keeps saying that the constructor is undefined. I already read somewhere that I need to declare the constructor with no arguments. I just don't know how to do that.
If someone could help, I am new at java and programming. My code is below:
import java.util.*;//import library
class Input
{
public Input (int size,int startV,int endingV)
{
//declarations of variables
double difference;
double[] array= new double[size];
array[0]=startV;
//calculating the difference to add on each number in the array
difference=(endingV-startV)/size;
for (int counter=1;counter<size;counter++) //for loop to fill the array
{
array[counter]=array[counter-1] + difference;
}
}
public Input enter(int size,int startV,int endingV)
{
//declarations of variables
double difference;
double[] array= new double[size];
array[0]=startV;
//calculating the difference to add on each number in the array
difference=(endingV-startV)/size;
for (int counter=1;counter<size;counter++) //for loop to fill the array
{
array[counter]=array[counter-1] + difference;
}
return this;
}
}
class Show
{
public Show (int size,double[] array)
{
for (int i=0;i<size;i++) //for loop to print the array
System.out.println("This is the array " + i+ ": " + array[i]);
}
public Show print(int size,double[] array)
{
for (int i=0;i<size;i++) //for loop to print the array
System.out.println("This is the array " + i+ ": " + array[i]);
return this;
}
}
public class Assignment2
{
public static void main(String[] args)
{
//declaring variables
int startV,endingV;
int size=0;
System.out.print("Give the size of the array:");//Print message on screen
size = new Scanner(System.in).nextInt();//asking for the size of array
double[] array= new double[size]; //creation of array
System.out.print("Give the starting value of the array:");
startV = new Scanner(System.in).nextInt();//asking for the starting value of array
System.out.print("Give the ending value of the array:");
endingV = new Scanner(System.in).nextInt();//asking for the last value of array
//calling the functions from the other classes
Input enter= new Input(size,startV,endingV);
Show print= new Show(size,array);
}
}
You're close:
You have a method:
public Method enter(int size,int startV,int endingV) {
to make it a constructor it's signature must be
public Method (int size,int startV,int endingV) {
and you then have to delete the return this; statement.
Remember, constructors don't have a return type and their name is identical to the name of the class. With this information, you'll also be able to fix the Method1 constructor.
Also, please respect the Java naming conventions and have variables start with a lower-case letter to improve the readability of your code.
You need to create a
public Method(size,startV,endingV)
not
public Method enter = (size, startV, endingV)
The first is a constructor the second is a method
For class Method
the default constructor will be
public Method(){}
For class Method1
the default constructor will be
public Method1(){}
in your classes there are no constructors as the
constructor name must be will the same as class name.
enter(int size,int startV,int endingV)
and
print(int size,double[] array)
can be two methods in your classes.
also your two constructor can be -
public Method(int size,int startV,int endingV){ /..../}
and
public Method1(int size,double[] array){ /..../}
Your constructor must have the same name than your class and has no return type. So for your class Method, your constructor will simply be :
public Method(int size, int startV, int endingV)
{
// code...
}
Please also note that constructors exist to initialize your instances of objects, if you want to create a method that does a specific calcul, then yes, you'll have to do :
public int enter(int size, int startV, int endingV)
{
int result = 0;
// code to calculate, for example result = size + startV + endingV ...
return result;
}

Categories