I made this class ArrayBuilder with generics to make some basic operation to manage an array of T objects.
public class ArrayBuilder<T> {
#SuppressWarnings("unchecked")
public ArrayBuilder(Class<T> ct, int dim){
container = (T []) Array.newInstance(ct, dim);
}
public T getElement(int index){
return container[index];
}
public void setElement(int index, T value){
container[index] = value;
}
public T[] getContainer(){
return container;
}
T[] container;
public static void main(String[] args) throws ClassNotFoundException {
PrintStream ps = new PrintStream(System.out);
Scanner sc = new Scanner(System.in);
ps.print("che array desidera? ");
String nameClass = "discover.";
nameClass = nameClass + sc.nextLine();
Class<?> toManipulate = Class.forName(nameClass);
//Type type = toManipulate.getGenericSuperclass();
ArrayBuilder<toManipulate> ab = new ArrayBuilder<toManipulate>(toManipulate, 10);
}
}
in main, program asks to the user to insert the name of the Class wich he prefers, so I want to use ArrayBuilder constructor to create this kind of array but compiler doesn't accept variable toManipulate in the angular brackets. Maybe Do I have to extract generic Type from the instance toManipulate?
Generics are a compile time feature. What you have can equally be handled by raw types as you don't know what the type is at compile time.
Class toManipulate = Class.forName(nameClass);
ArrayBuilder ab = new ArrayBuilder(toManipulate, 10);
or if you really want to use generics you can do
Class<?> toManipulate = Class.forName(nameClass);
ArrayBuilder<?> ab = new ArrayBuilder<Object>(toManipulate, 10);
Related
public class QueueDemo<T> {
public static <T> ArrayUnbndQueue<T> mergeQueue(ArrayBndQueue<T> q1, ArrayBndQueue<T> q2) {
ArrayUnbndQueue<T> temp = new ArrayUnbndQueue<T>();
while (!q1.isEmpty()) {
T x = q1.dequeue();
temp.enqueue(x);
}
while (!q2.isEmpty()) {
temp.enqueue(q2.dequeue());
}
return temp;
}
public static void main(String[] args) {
ArrayBndQueue<Integer> q1 = new ArrayBndQueue<Integer>();
ArrayBndQueue<Integer> q2 = new ArrayBndQueue<Integer>();
ArrayUnbndQueue<Integer> q3 = new ArrayUnbndQueue<Integer>();
q1.enqueue(1);
q1.enqueue(2);
q2.enqueue(5);
q2.enqueue(6);
q3.mergeQueue(q1, q2); // i get an errorThe method
//mergeQueue(ArrayBndQueue<Integer>,
//ArrayBndQueue<Integer>) is undefined
//for the type ArrayUnbndQueue<Integer>
}
}
I have a method that adds two queues and returns them together as a new queue, I am not very experienced with generic datatypes which I believe its whats causing the error.
You do not have any method mergeQueue for ArrayUnbndQueue but for QueueDemo.
Therefore you have to do this statement within your main method of QueueDemo:
ArrayUnbndQueue<Integer> q3 = mergeQueue(q1, q2);
The problem does not relate to generics.
I am once again asking for technical support.
I need to define a custom type inside a class, I've done it like this:
public class MainClass {
private class CustomType {
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
private CustomType[] myArray;
public MainClass() {
myArray = new CustomType[1024]
System.out.println(this.CustomType[0].varB);
}
}
When I run it throws a NullPointerException at System.out.println(this.CustomType[0].varB);
I've tested if myArray gets properly initialized with 1024 elements and it does, however I can't seem to access them.
I just moved from C++ to Java so I'm still getting used to it, am I missing something blatant?.
You only create an array without any objects, so this.CustomType[0] is null.
You should add the objects to the array:
public MainClass() {
myArray = new CustomType[1024]
for (int i =0; i<myArray.length;i++ {
myArray[i] = new CustomType();
}
System.out.println(this.myArray[0].varB);
}
Also you should make the member of CustomType private and access it via getter and setter.
Two things,
You must instantiate CustomType.
CustomType does not need access to MainClass.this so you can make it static.
So
public class MainClass {
private static class CustomType {
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
private CustomType[] myArray;
public MainClass() {
myArray = new CustomType[1024];
for (int i = 0; i < myArray.length; ++i) {
this.CustomType[i] = new CustomType();
}
// Or
Arrays.setAll(myArray, CustomType::new);
System.out.println(this.CustomType[0].varB);
}
}
Not making it static stores a MainClass.this in every CustomType instance which is unnecessary overhead.
Arrays in java are objects. The following line of the code you posted creates an array of 1024 elements where each and every element is null.
myArray = new CustomType[1024];
If you want to place actual objects in the array, named myArray, you need to create instances of class CustomType and assign them to elements of the array, for example:
CustomType instance = new CustomType();
myArray[0] = instance;
Then you can execute the following line of code and it will not throw NullPointerException.
System.out.println(myArray[0].varB);
Here is the full code to get the value of varB. In which you can avoid declaring CustomType[] myArray
public class Test
{
private static class CustomType
{
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
public static void main(String... args)
{
System.out.println(new CustomType().varB);
}
}
The solution is to add some elements to that array. See the below steps for more information.
constructor will be invoked, when you create the object of that class
And then you created an empty array of CustomType with size 1024 and trying to access the first element which does not exist(default is null) and trying to perform operations on that null reference. So you are getting the NullPointerException.
I have the object numberlist that i created in create() method and i want to access it so i can use it in the question() method.
Is there another way to do this that I probably missed? Am I messing something up? If not, how should I do this to get the same functionality as below?
private static void create() {
Scanner input = new Scanner(System.in);
int length,offset;
System.out.print("Input the size of the numbers : ");
length = input.nextInt();
System.out.print("Input the Offset : ");
offset = input.nextInt();
NumberList numberlist= new NumberList(length, offset);
}
private static void question(){
Scanner input = new Scanner(System.in);
System.out.print("Please enter a command or type ?: ");
String c = input.nextLine();
if (c.equals("a")){
create();
}else if(c.equals("b")){
numberlist.flip(); \\ error
}else if(c.equals("c")){
numberlist.shuffle(); \\ error
}else if(c.equals("d")){
numberlist.printInfo(); \\ error
}
}
While interesting, both of the answers listed ignored that fact that the questioner is using static methods. Thus, any class or member variable will not be accessible to the method unless they are also declared static, or referenced statically.
This example:
public class MyClass {
public static String xThing;
private static void makeThing() {
String thing = "thing";
xThing = thing;
System.out.println(thing);
}
private static void makeOtherThing() {
String otherThing = "otherThing";
System.out.println(otherThing);
System.out.println(xThing);
}
public static void main(String args[]) {
makeThing();
makeOtherThing();
}
}
Will work, however, it would be better if it was more like this...
public class MyClass {
private String xThing;
public void makeThing() {
String thing = "thing";
xThing = thing;
System.out.println(thing);
}
public void makeOtherThing() {
String otherThing = "otherThing";
System.out.println(otherThing);
System.out.println(xThing);
}
public static void main(String args[]) {
MyClass myObject = new MyClass();
myObject.makeThing();
myObject.makeOtherThing();
}
}
You would have to make it a class variable. Instead of defining and initializing it in the create() function, define it in the class and initialize it in the create() function.
public class SomeClass {
NumberList numberlist; // Definition
....
Then in your create() function just say:
numberlist= new NumberList(length, offset); // Initialization
Declare numberList outside your methods like this:
NumberList numberList;
Then inside create() use this to initialise it:
numberList = new NumberList(length, offset);
This means you can access it from any methods in this class.
I created these two files in java and they don't compile. This error comes up:
cannot find symbol C02FootprintV1".
Why doesn't the program recognize the object? I am new to this.
How could I fix this problem?
public class CO2FootprintV1 {
private double myGallonsUsed;
private double myTonsCO2;
private double myPoundsCO2;
CO2FootprintV1(double gals) {
myGallonsUsed = gals;
}
public void calcTonsCO2() {
myTonsCO2 = myGallonsUsed * 0.878;
}
public double getTonsCO2() {
return myTonsCO2;
}
public void convertTonsToPoundsCO2() {
myPoundsCO2 = myTonsCO2 * 220462262;
}
public double getPoundsCO2() {
return myPoundsCO2;
}
}
public class CO2FootprintV1Tester {
public static void main(String[] args) {
double gals;
double tonsCO2, poundsCO2;
gals = 1300;
CO2FootprintV1 object = new C02FootprintV1(gals);
object.calcTonsCO2();
tonsCO2 = object.getTonsCO2();
object.convertTonsToPoundsCO2();
poundsCO2 = object.getPoundsCO2();
}
}
On the line
CO2FootprintV1 object = new C02FootprintV1(gals);
you have C02 (see zero two) on the right hand side, you meant for it to be
CO2FootprintV1 object = new CO2FootprintV1(gals);
or CO2 (see oh two). Also, you should consider that the error messages your tools give you might be correct.
Just change:
CO2FootprintV1 object = new C02FootprintV1(gals);
to:
CO2FootprintV1 object = new CO2FootprintV1(gals);
That's why it is important to have good naming practice.
You put a "0" (cero) instead of an "O" (letter):
CO2FootprintV1 object = new C02FootprintV1(gals);
Try this:
CO2FootprintV1 object = new CO2FootprintV1(gals);
Alright, I'm trying to call setters and getters from another function that's inside another class, in another file. Here's what I'm getting, and I really don't know what I'm doing wrong...
Bank.java
package Bank;
import java.io.*;
import java.util.*;
public class Bank
{
public static void main (String args[]) throws FileNotFoundException
{
final String fileName = "Bank/AcctInfo.txt";
File accounts = new File(fileName);
ArrayList <Object> acctInfo = new ArrayList <Object> ();
acctInfo = setObjects(accounts);
}
public static ArrayList setObjects(File document) throws FileNotFoundException
{
ArrayList <Object> objectArray = new ArrayList <Object> ();
Scanner fileInput = new Scanner(document);
String blankInfo;
String accountType;
String customerType;
String customerName;
int accountNumber;
float balance;
int counter = 0;
while (fileInput.hasNext())
{
accountNumber = fileInput.nextInt();
blankInfo = fileInput.nextLine();
accountType = fileInput.nextLine();
customerName = fileInput.nextLine();
customerType = fileInput.nextLine();
balance = fileInput.nextFloat();
blankInfo = fileInput.nextLine();
objectArray.add(new BankAccount());
objectArray.get(counter).setAccNumber(accountNumber);
counter++;
}
return objectArray;
}
}
BankAccount.java
package Bank;
public class BankAccount extends Bank
{
private int accNumber;
private String accType;
private String cusName;
private String cusType;
private float bal;
public void setAccNumber(int accountNumber)
{
int accNumber = accountNumber;
}
public int getAccNumber()
{
return accNumber;
}
public void setAccType(String accountType)
{
String accType = accountType;
}
public String getAccType()
{
return accType;
}
public void setCusName(String customerName)
{
String cusName = customerName;
}
public String getCusName()
{
return cusName;
}
public void setCusType(String customerType)
{
String cusType = customerType;
}
public String getCusType()
{
return cusType;
}
public void setBal(float balance)
{
float bal = balance;
}
public float getBal()
{
return bal;
}
}
Errors:
Bank.java:51: error: cannot find symbol
objectArray.get(counter).setAccNumber(accountNumber);
^
symbol: method setAccNumber(int)
location: class Object
Note: .\Bank\Bank.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
It's not completed yet, but if someone can help me through that bit, it'd be a huge help...
Instead of ArrayList<Object>, use ArrayList<BankAccount>.
Object is a class that doesn't have a method with the signature setAccNumber(int) whereas BankAccount does.
The ArrayList<Object> declaration says that you're declaring an ArrayList that will have Objects inside it; since all classes inherit from Object, putting instances of BankAccount in the list is valid, but as far as the compiler is concerned, when you refer to an element inside the list, it's an Object and only has the standard methods available to Object.
There are other peculiarities in your class too (e.g. in your setter methods, you declare a new variable and assign to it, inside of assigning it to a field). I would recommend revisiting your course lecture notes if available. There's an online free PDF called Java Precisely which is a very concise look at Java - the free version is up to Java 5 I think, but it's enough to cover the topics here.
Because you're doing this:
ArrayList <Object> objectArray = new ArrayList <Object> ();
the list there doesn't know what the things inside are, because you said they are Object.
if you make that
ArrayList <BankAccount> objectArray = new ArrayList <BankAccount> ();
it should work like you expect.
If you want to use the methods of BankAccount on the items of your ArrayList, you have to specify that it is a list of BankAccounts. Speficically, the line
ArrayList <Object> objectArray = new ArrayList <Object> ();
should really be
ArrayList <BankAccount> objectArray = new ArrayList <BankAccount>();
You can think of generics as specifying what you have a list of. So for the first example, you can read it as "An ArrayList of Objects." Since you don't know if they are BankAccounts or not, you don't know if you can call settAccNumber() on them.
For the second example, you can read it as "An ArrayList of BankAccounts." In this case you know that they are BankAccounts, so you know that you can call setAccNumber() on them.
Here's a lesson on generics, since you don't seem to quite have the hang of them.
Here's the oracle documentation on them as well.
Other answers correctly suggest using ArrayList<BankAccount>
If (for whatever strange reason) you cannot or do not want to do it, then you need to implicitly cast the retrieved list element to BankAccount type.
Your
objectArray.get(counter).setAccNumber(accountNumber);
will become
((BankAccount)objectArray.get(counter)).setAccNumber(accountNumber);