I have a program in java that I wrote to return a table of values. Later on as the functions of this program grew I found that I would like to access a variable within the method that isn't returned but I am not sure the best way to go about it. I know that you cannot return more than one value but how would I go about accessing this variable without a major overhaul?
here is a simplified version of my code:
public class Reader {
public String[][] fluidigmReader(String cllmp) throws IOException {
//read in a file
while ((inpt = br.readLine()) != null) {
if (!inpt.equals("Calls")) {
continue;
}
break;
}
br.readLine();
inpt = br.readLine();
//set up parse parse parameters and parse
prse = inpt.split(dlmcma, -1);
while ((inpt = br.readLine()) != null) {
buffed.add(inpt);
}
int lncnt = 0;
String tbl[][] = new String[buffed.size()][rssnps.size()];
for (int s = 0; s < buffed.size(); s++) {
prse = buffed.get(s).split(dlmcma);
//turns out I want this smpls ArrayList elsewhere
smpls.add(prse[1]);
//making the table to search through
for (int m = 0; m < prse.length; m++) {
tbl[lncnt][m] = prse[m];
}
lncnt++;
}
//but I return just the tbl here
return tbl;
}
Can anyone recommend a way to use smpls in another class without returning it? Is this perhaps when you use a get/set sort of setup?
Sorry if this seems like an obvious question, I am still new to the world of modular programming
Right now you have this tbl variable. Wrap it in a class and add the list to the class.
class TableWrapper {
// default accessing for illustrative purposes -
// setters and getters are a good idea
String[][] table;
List<String> samples;
TableWrapper(String[][] table, List<String> samples) {
this.table = table;
this.samples = samples;
}
}
Then refactor your method to return the wrapper object.
public TableWrapper fluidigmReader(String cllmp) throws IOException {
// your code here
String tbl[][] = new String[buffed.size()][rssnps.size()];
TableWrapper tw = new TableWrapper(tbl,smpls);
// more of your code
return tw;
}
Then later in your code where you were going
String[][] tbl = fluidigmReader(cllmp);
You instead go
TableWrapper tw = fluidigmReader(cllmp);
String[][] tbl = tw.table;
List<String> smpls = tw.samples;
If you had used a dedicated class for the return value (such as the TableWrapper mentioned in another answer), then you could add additional fields there.
That is the good thing about classes - they can be extended. But you cannot extend String[][] in Java.
You can set a field, instead of a local variable, which you can retrieve later with a getter. You want to avoid it unless it is needed, but in this case it is.
You can use class(Inside Reader class) variable for this. But make sure that it's read/write is synchronized
Related
I am passing few values to mail method for sending the details like below
private static String getTeam(String Team, List<String> prioritys1, String number,String description
) {
StringBuilder builder1 = new StringBuilder();
for (String v : prioritys1) {
if ( v == "1") {
Integer cnt1 = count1.get(new Team(Team, v,number,description));
if (cnt1 == null) {
cnt1 = 0;
}
else
if (cnt1 !=0){
cnt1 = 1;
mail1(Team,v,number,description);
}}
else
if ( v == "3") {
Integer cnt1 = count1.get(new Team(Team, v,number,description));
if (cnt1 == null) {
cnt1 = 0;
}
else
if (cnt1 !=0){
cnt1 = 1;
mail1(Team,v,number,description);
}}
}
return builder1.toString();
}
I tried to store in arrays but it didnt worked.
I after pass above parameters, i need to store the value of the number. i need to store the number so that next time while passing the parameters i need to check first whether the number is already passed or not if not then only i need to pass to mail.
can any one help on this
With this code very complicated understand what you are doing. But if you need check value that already been processed store it outside of the method. Create global class variable:
public class className {
private final List<String> ARRAY = new ArrayList<>(); // global variable
public void yourMethod(String value) {
if (!ARRAY.contains(value)) {
mail(value);
ARRAY.add(value);
}
}
}
I dont know your case and I can not get better example.
You need to store the value in a "class level" variable. Whether the variable type needs to be static or instance will depend on your implementation of the method.
If you can post a sample code, we can help further.
You need to compare with 2 equals and not 1
Instead of
if( Team = A )
you need this way
if( Team == A )
Using Team = A, your saying that every time your code reaches that line it will equal Team to A.
I am getting a null exception error from this segment of code and I am not sure what causing it. The array itemcatalog has being populate for i =0 to 8. I am new to java so any assistance will be greatly appreciated. The error message points to the line of the while statement. Thanks
public class ItemCatalog {
private static ItemCatalog instance = new ItemCatalog();
private Item itemCatalog[] = new Item[9];
private ItemCatalog(){
};
public static synchronized ItemCatalog getInstance() {
return instance;
}
public void populateCatalog()
{
itemCatalog[0] = new Item("bb","Baked Beans",new BigDecimal("0.35"));
itemCatalog[1] = new Item("cf","Cornflakes",new BigDecimal("1.00"));
itemCatalog[2] = new Item("s0","Sugar",new BigDecimal("0.50"));
itemCatalog[3] = new Item("tb","Tea Bags",new BigDecimal("1.15"));
itemCatalog[4] = new Item("ic","Instant Coffee",new BigDecimal("2.50"));
itemCatalog[5] = new Item("b0","Bread",new BigDecimal("0.50"));
itemCatalog[6] = new Item("s0","Sausages",new BigDecimal("1.30"));
itemCatalog[7] = new Item("e0","Eggs",new BigDecimal("0.75"));
itemCatalog[8] = new Item("m0","Milk",new BigDecimal("0.65"));
}
public BigDecimal getPrice(String itemCode)
{
int i = 0;
while (!itemCode.equals(itemCatalog[i].getItemCode()))
{
i++;
}
BigDecimal itemPrice = itemCatalog[i].getItemprice();
return itemPrice;
}
}
I solved the issue. I was populating the catalog in the main class which was giving the null exception error. I instantiate it in the jframe instead and it works. The follow code solved the issue, but is this the best place to populate the catalog?
private void saleButtonActionPerformed(java.awt.event.ActionEvent evt) {
String itemCode = this.itemCodeinput.getText();
int itemQuantity =Integer.parseInt(this.itemQuantityinput.getText());
ItemCatalog catalog = ItemCatalog.getInstance();
catalog.populateCatalog();
BigDecimal price = catalog.getPrice(itemCode);
itemCostoutput.setText(price.toString());
}
If your itemCode doesn't match any entries in your itemCatalog, then eventually
while (!itemCode.equals(itemCatalog[i].getItemCode()))
{
i++;
}
will increment i to 11, in which case itemCatalog[11] is either empty or out of bounds.
If addition, you should use a for loop to iterate through the itemCatalog:
for (int i = 0; i < itemCatalog.length; i++) {
if (itemCode.equals(itemCatalog[i].getItemCode()) {
return (BigDecimal) itemCatalog[i].getItemprice();
}
}
return null // you can change this from null to a flag
// value for not finding the item.
From the comments, it's clear the design isn't sound.
Here's a possible solution :
public BigDecimal getPrice(String itemCode) {
for (int i=0; i<itemCatalog.length; i++) { // not going outside the array
if (itemCatalog[i].getItemCode().equals(itemCode)) { // inversing the test to avoid npe if itemCode is null
return itemCatalog[i].getItemprice();
}
}
return null; // default value
}
This supposes your array is correctly filled with itemCatalogs having an itemCode.
How do you end your loop?
Seems that the loop will keep going until i is 10. Then your will have exceeded the limit.
Unless this is a uni assignment where you have to use arrays, I'd also suggest using a map, rather than an array. This way your lookup will be the same time, whether your collection has 100,000 entries or 10.
You will also reduce risk of NPE or ArrayOutOfBounds exception
See http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html
When adding the object use the item code as the key. Then lookup by the key.
The cost of using a map is increased memory usage.
I am having some trouble with passing data of an array from one class to the next.
edits
I am now no longer getting the error, and my code compiles, but as I had been warned, I got null for every element of the array. Now that I have taken out the static modifiers though, it still gives me null. I have also updated the code.
Here is the class where the array is created.
public class AssignSeat {
String[] arrangement = new String[12];
public void SeatStart() {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
arrangement[6] = "Morgans";
arrangement[7] = "Rohan";
arrangement[8] = "Shatrov";
arrangement[9] = "Sword";
arrangement[11] = "Tuckness";
System.out.format("%-15s%-15s%n", "seat", "passenger");
for (int i=0; i<arrangement.length; i++) {
System.out.format("%-15s%-15s%n", i+1, arrangement[i]);
}
}
public String[] getArrangement() {
return arrangement;
}
public void setArrangement(String[] arrangement) {
this.arrangement = arrangement;
}
}
and here is the method trying to access the information. It is specifically the for loop that I need help with so Ignore other areas where there are mistakes. Thank you.
public void actionPerformed(ActionEvent event) {
Scanner scanner = new Scanner(System.in);
AssignSeat seat = new AssignSeat();
if(event.getSource() instanceof JButton){
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("first class")) {
entername.setVisible(true);
seatnum.setVisible(true);
confirmed.setVisible(true);
inputline.setVisible(true);
outputline.setVisible(true);
if ((seat.arrangement[1] == null)) {
System.out.println(seat.arrangement[0]);
System.out.println(seat.arrangement[2]);
two.setForeground(Color.green);
}
} else if (buttonText.equals("coach")) {
//System.out.println("so does this!");
entername.setVisible(true);
seatnum.setVisible(true);
confirmed.setVisible(true);
inputline.setVisible(true);
outputline.setVisible(true);
if ((seat.arrangement[4] == null)) {
five.setForeground(Color.green);
}
if ((seat.arrangement[5] == null)) {
six.setForeground(Color.green);
}
if ((seat.arrangement[10] == null)) {
eleven.setForeground(Color.green);
}
}
}
}
The problem lies in the fact that the array was declared as static, but the initialization code for it is in the constructor. Remove all the static modifiers in the original code, and replace this part:
if (AssignSeat.getArrangement()[1].equals("null"))
With this:
AssignSeat assign = new AssignSeat();
if (assign.getArrangement()[1] == null)
Also notice that "null" is not a null value, use null (without quotes) for that.
A different approach would be to leave the array as an static member, but initialize it statically, like this:
private static String[] arrangement = new String[12];
static {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
arrangement[6] = "Morgans";
arrangement[7] = "Rohan";
arrangement[8] = "Shatrov";
arrangement[9] = "Sword";
arrangement[11] = "Tuckness";
}
In that case, this would work:
if (AssignSeat.getArrangement()[1] == null)
But I still believe that making the array static is going to be problematic if several instances of the class happen to be modifying its contents.
Replace
if (AssignSeat.getArrangement()[1].equals("null"))
with
if (AssignSeat.getArrangement()[1] == null)
If the value is null, you can't invoke methods (like equals) on it. You need to compare the value directly to null, which is a constant rather than a string.
Ok, I'm a bit confused as to what you're trying to do in the first class. You are initializing a static array from an instance method...
In other words, the String values in the array will be null until you call SeatStart from an instance of the class.
Try to initialize the String array from the static constructor for AssignSeat to make sure it has been initialized before you use it: http://www.snippetit.com/2009/05/java-static-variables-static-methods-and-static-constructor/
You are trying to use an attribute of a class, without instantiating the object first. Until you call a default/user-defined constructor, there is no memory dedicated to the attribute of that object.
Even though you manage to call the method you are using a static method, which can be called without an instance of the object being required.
Create a constructor for the object (or use a default constructor) and then you will be able to access your attribute because your object will be on the heap and have memory allocated for the string[].
Simply define the SeaStart as an Array.
public String[] SeatStart() {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
return arrangement;
}
For convinience, make a new array to copy the array from AssignSeat class. Then retrieve the value from that array.
public void actionPerformed(ActionEvent event) {
AssignSeat seat = new AssignSeat();
String[] foo = seat.SeatStart();
System.out.println(foo[0]);
System.out.println(foo[1]);
System.out.println(foo[2]);
}
Though you can acces it also with:
System.out.println(seat.SeatStart()[0]);
The result would be:
Collins
null
Faivre
and that 'null' is because apparently you haven't allocate a value for arrangement[1] :-)
But in the end, it works.
I have a Enumeration as shown in below program
public class Test {
public static void main(String args[]) {
Vector v = new Vector();
v.add("Three");
v.add("Four");
v.add("One");
v.add("Two");
Enumeration e = v.elements();
load(e) ; // **Passing the Enumeration .**
}
}
There is also a Student Object
public Student
{
String one ;
String two ;
String three ;
String four ;
}
i need to pass this Enumeration to another method as shown below
private Data load(Enumeration rs)
{
Student stud = new Student();
while(rs.hasMoreElements())
{
// Is it possible to set the Values for the Student Object with appropiate values I mean as shown below
stud.one = One Value of Vector here
stud.two = Two Value of Vector here
stud.three = Three Value of Vector here
stud.four = Four Value of Vector here
}
}
Please share your ideas on this .
Thanks
Sure. You could use the elementAt method, documented here, to get the value you wanted. Do you have a specific reason you are using a Vector? Some of the List implementations might be better.
Enumerations don't have the idea of "first value", "second value", etc. They just have the current value. You could work around this in various ways:
The easy way -- convert it to something easier to work with, like to a List.
List<String> inputs = Collections.list(rs);
stud.one = inputs.get(0);
stud.two = inputs.get(1);
// etc.
Keep track of the position yourself.
for(int i = 0; i <= 4 && rs.hasNext(); ++i) {
// Could use a switch statement here
if(i == 0) {
stud.one = rs.nextElement();
} else if(i == 1) {
stud.two = rs.nextElement();
} else {
// etc.
}
}
I really don't recommend either of these things, for the following reasons:
If you want your parameters in a particular order, just pass them in that way. It's much easier and it's also easier to maintain (and for other people to read).
void example(String one, String two, String three, String four) {
Student student = new Student();
student.one = one;
student.two = two;
// etc.
}
You shouldn't use Enumeration at all, since it's been replaced with Iterator and Iterable since Java 1.2. See ArrayList and Collection.
I'm a little lost (still working with Ron Jeffries's book). Here's a simple class:
public class Model{
private String[] lines;
public void myMethod(){
String[] newLines = new String[lines.length + 2];
for (i = 0, i <= lines.length, i++) {
newLines[i] = lines[i];
}
}
}
I have another class that initializes Model, and an empty array, by setting myModel = new String[0]. When I invoke myModel.myMethod(), I get a subscript out of range error. Looking at the debugger, what I see is that myModel.lines has zero dimensions and zero length. Shouldn't it have a dimension and length of 1? Granted the value of lines[0] is null, but the array itself shouldn't be, should it?
Any thoughts truly appreciated.
Randy
I think your example is probably not the same as your actual code based on your description. I think the problem is that arrays are zero-based and thus an array initialized as:
string[] lines = new string[0];
has no elements.
You need to change your loop so that you check that the index is strictly less than the length of the array. As others have indicated you also need to make sure that the array itself is not null before trying to reference it.
My take on your code:
public class Model{
private String[] lines = new string[0];
public Model( string[] lines ) {
this.lines = lines;
}
public void myMethod(){
int len = 2;
if (lines != null) {
len = len + lines.length;
}
String[] newLines = new String[len];
for (i = 0, i < lines.length, i++) {
newLines[i] = lines[i];
}
}
}
lines will be null, so lines.length will throw an exception.
I believe your other class initializing "Model" won't help since Lines itself is private. In fact, whatever you are doing to Model is probably illegal in at least 30 states.
lines is initalized to null, check for null or initialize it in this way :
private String[] lines = new String[0];
You cannot initialize an instance of Model by setting it equal to a String array. I'm actually surprised that the compiler will let you even try.
If you really want Model to be initializable with an external array, you should make a Constructor for the Model class that will take as an argument the array. Then in the body of your constructor, set the value of lines to that value.
Example:
public class Model {
private String []lines;
public Model(String [] inLines)
{
lines = inLines;
}
}
Usage:
myStringArray = new String[0];
myModel = new Model(myStringArray);
Take a look at my answer here - I think this will get you the background you are looking for on the differences between array initialization in Java and C/C++.