I am stucked by coding and I need your help.
Ok first of all I have an array variable under a class.
I get the values from excel and put inside the nodename array like as follows.I shortened the following codes.
Following class Readexcel is also under ConfigGenerator Class.
class ReadExcel {
private String inputFile;
public void setInputFile(String inputFile) {
this.inputFile = inputFile;
}
public void read() throws IOException {
File inputWorkbook = new File(inputFile);
Workbook nodes;
try {
nodes = Workbook.getWorkbook(inputWorkbook);
// Get the first sheet
Sheet nodessheet = nodes.getSheet(1);
String[] nodename = new String[nodessheet.getRows()];
for (int i = 1; i < nodessheet.getRows(); i++) {
int j = 0;
Cell x1a = nodessheet.getCell(0, i);
nodename[j] = x1a.getContents();
j++;
// System.out.println(nodename[j]);
}
} catch (BiffException e) {
// e.printStackTrace();
}
}
}
But my problem is to reaching this variable from a button action.
public class ConfigGenerator extends javax.swing.JFrame {
public ConfigGenerator() {
initComponents();
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
private void generateActionPerformed(java.awt.event.ActionEvent evt) {
try {
Writer output = null;
for (String name: Generator.ConfigGenerator.ReadExcel.nodename[????]){
System.out.println(name);
}
output.close();
System.out.println("Your files has been written.");
} catch (IOException ex) {
Logger.getLogger(ConfigGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The parts that i added question mark is my problem for the last 2 days I am tring but couldn't get the values from that array.
First I need to get lenght of array and second the values :)
Thank you very much for your help in advance.
Ok I edited the question by adding the whole section with codes.
Maybe you mean that you want to get the array lenght using nodename.length, but I have two issues with your code:
First you access nodename as an array local to your action, then later access it as a static variable of class ConfigGenerator, which means you are accessing two different arrays.
Also, you access the nodename array as a static variable (although even the .class is not necessary), but you mentioned it as a "array variable" which means you need first to create a new instance of class ConfigGenerator, initializing the array nodename, and then you can use it in other classes.
First of all, the way to retrieve the length of an array in Java is
nodename.length
not
nodename.getlength()
But you could also use the shortened syntax to loop through all elements in the specific array:
for (Object obj : array) {
System.out.println(obj);
}
In your case it would be:
for (Object obj : ConfigGenerator.nodename) { //replace Object with your datatype
System.out.println(obj);
}
Related
So normally, I know one would use a standard for loop to iterate though the array, like such:
public static void readCodesFromFile(String filename, String[] codes) throws FileNotFoundException {
try ( Scanner fin = new Scanner(new File(filename) ); ) {
for (int i = 0; i <= codes.length - 1; i++) {
codes[i] = fin.nextLine();
}
}
}
But, I desperately want to discover how to do this with a for each loop instead.
At this point I just need to know if it can be done, but also would love the efficiency and cleanliness of using this loop for this task. I have tried something like this, and moved things around many times, but cannot seem to get anything to read properly.
Below is the for each ( : ) I have been working with:
public static void readCodesFromFile(String filename, String [] codes) throws FileNotFoundException {
try (Scanner fin = new Scanner(new File(filename) ); ) {
for (String code : codes) {
codes = fin.nextLine();
}
}
}
At this point I just need to know if it can be done...
No, not as it's written. For one, the spec doesn't allow for it but you're also dealing with immutable Strings. Say, from your second example, code is a reference to an element in your array. Once I do code = "foo";, code now references the (presumably) new String and the array element retains its original value.
But, I desperately want to discover how to do this with a for each
loop instead.
If that's the case, why not invert the problem? Instead of iterating over the array, provide a way to iterate over the file.
In this answer I'm going to assume two things:
You'll provide an Iterable FileReader
You'll use an ArrayList instead of a normal array (this is to get past the indexing issue with the additional benefit that you'll no longer need to know or care about the number of lines in the file)
Here's the FileReader (with a lot not implemented):
class FileReader implements Iterable<String> {
#Override
public Iterator<String> iterator() {
return new FileReaderIterator();
}
#Override
public void forEach(Consumer<? super String> action) { }
#Override
public Spliterator<String> spliterator() { return null; }
class FileReaderIterator implements Iterator<String> {
#Override
public boolean hasNext() {
return false;
}
#Override
public String next() {
return null;
}
#Override
public void remove() { }
#Override
public void forEachRemaining(Consumer<? super String> action) { }
}
}
Assuming you had this implemented you could have used it like so:
List<String> lines = new ArrayList<>();
FileReader reader = new FileReader(...);
for (String line : reader) {
lines.add(line);
}
I'm not suggesting you change your design rather to consider what a different design choice could have provided.
Another way you could achieve this with a basic array very easily would be to encapsulate the line in a class. For example:
class FileLine {
private String line;
public FileLine() {...}
public FileLine(String line) {
this.line = line;
}
public setLine(String line) {
this.line = line;
}
}
Make an array of those, iterate over it with the enhanced for loop, and instead of setting the value of the array string element, set the value of the string member of the FileLine instance. Like so:
// Given an array of instantiated FileLines...
for (FileLine fileLine : fileLines) {
fileLine.setLine(...);
}
Less effort and you don't have to worry about trying to iterate over a file.
i'm writing a program for a game called 'Trivia'. Below is the source code:
Trivia.java
public class Trivia implements Serializable {
private String question;
private String answer;
private int points;
public Trivia() {
question = " ";
answer = " ";
points = 0;
}
public String getQuestion() {
return question;
}
public String getAnswer() {
return answer;
}
public int getPoints() {
return points;
}
public void setQuestion(String q) {
question = q;
}
public void setAnswer(String a) {
answer = a;
}
public void setPoints(int p) {
points = p;
}
}
Driver.java
public class Driver {
public static void main(String[] args) {
Trivia[] t = new Trivia[5];
for (int i = 0; i < 5; i++) {
t[i] = new Trivia();
}
t[0].setQuestion("How many states are in the US?");
t[0].setAnswer("50");
t[0].setPoints(1);
t[1].setQuestion("Who is the richest person in the US");
t[1].setAnswer("You");
t[1].setPoints(1);
t[2].setQuestion("How many senators come from each state?");
t[2].setAnswer("2");
t[2].setPoints(2);
t[3].setQuestion("What is the largest state?");
t[3].setAnswer("Alaska");
t[3].setPoints(2);
t[4].setQuestion("Who was the thrid president?");
t[4].setAnswer("Thomas Jefferson");
t[4].setPoints(3);
ObjectOutputStream outputStream = null;
try {
outputStream = new ObjectOutputStream(new FileOutputStream("C:\\Work\\workspace\\aman\\src\\trivia\\trivia.dat"));
} catch (IOException e) {
System.out.println("Could not open file");
System.exit(0);
}
try {
outputStream.writeObject(t);
outputStream.close();
} catch (IOException e) {
System.out.println("Writing error");
System.exit(0);
}
ArrayList<Trivia> triviaQuestions = new ArrayList<Trivia>();
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("C:\\Work\\workspace\\aman\\src\\trivia\\trivia.dat"));
for(int i=0; i<5; i++){ // Repeats the content of the loop five times
triviaQuestions.add((Trivia) inputStream.readObject());
}
inputStream.close(); // Closes the input stream because it is not longer needed
} catch (IOException | ClassNotFoundException e) {
System.out.println("File not found.");
System.exit(0);
}
Trivia yourRandomTrivia = triviaQuestions.get((new Random()).nextInt(triviaQuestions.size())); // This will be your random question
}
// You did not get an auto complete suggestion because you typed outside of a method
}
noe when I try to run this program, I get an error saying "Ltrivia.Trivia; cannot be cast to trivia.Trivia". The error is thrown in class Driver on line " triviaQuestions.add((Trivia) inputStream.readObject());". I did some research on this and found that 'L' means array of a datatype. But, I have simple created an arrayList of type Trivia and trying to add each element I get from the inputStream by casting them to Trivia class.
Does anybody have any suggestions on this?
Your code is writing an Array of Trivia objects.
Then you try to read and add that to a list of Trivia objects.
You cant add arrays of Trivia to an List of Trivia!
And that is what the message is telling you: you cant cast the type Trivia[] to Trivia. Because an array of X is not the same as a single X.
One solution: instead of writing t as a whole, you can simply iterate t and write the members of the array. Of course that means that you have to somehow remember how many elements you wrote into that stream. You could get there by first writing an Integer object representing the number of Trivia objects that will follow.
The other solution: just read back that Trivia[]; and iterate it then; to add the various Trivia objects one by one.
Edit: on your comment: when you read from an ObjectInputStream you get back those things that you put into your file/stream earlier on. As said: your code puts a single object of type ARRAY of Trivia into bytes ... and then you want to read that thing back as a single Trivia object! That does not work!
I have a set of data that look like this.
1:2:3:4:5
6:7:8:9:10
I have manage to use array list to store the information using a delimiter of ":".
However i would like to store the information of their line numbers together in the array list.
class test
{
String items;
String linenumber;
}
Example:
test(1,1)
test(2,1)
test(6,2)
test(7,2)
Here is my current code.
Scanner fileScanner = new Scanner(new File(fname));
fileScanner.useDelimiter("\n");
int counter = 0; String scounter;
String test;
String events;
while(fileScanner.hasNext())
{
events = fileScanner.next();
scounter = Integer.toString(counter);
Base obj = new Base(scounter, events);
baseArrayList.add(obj);
}
fileScanner.close();
I have try using delimiter "\n" and then trying to split out the string and it is not very successful.
Any advice would be appreciated.
public void Base_Seperator()
{
String temp, temp2;
String[] split;
String days, events;
for(int i = 0; i < baseArrayList.size(); i++)
{
temp = baseArrayList.get(i).events;
temp2 = baseArrayList.get(i).days;
split = temp.split(":");
}
}
Despite the code in #Alex's answer that may solve your problem, your attempt is almost close to get what you want/need. Now you only need to create Test instances and store them in a container, usually a List. I'll add the necessary code to start this from your code:
//it is better to return the List instead of declaring it as a static field
public List<Test> Base_Seperator() {
//try to declare variables in the narrower scope
//String temp, temp2;
//String[] split;
//String days, events;
//this variable must be recognized in all the paths of this method
List<Test> testList = new ArrayList<Test>();
for(int i = 0; i < baseArrayList.size(); i++) {
//these variables should only work within the for statement
String temp = baseArrayList.get(i).events;
String temp2 = baseArrayList.get(i).days;
String[] split = temp.split(":");
//you have splitted the String by :
//now you have every element between : as an item stored in split array
//go through each one and create a new Test instance
//first, let's create the lineNumber variable as String
String lineNumber = Integer.toString(i+1);
//using enhanced for to go through these elements
for (String value : split) {
//now, let's create Test instance
Test test = new Test(value, lineNumber);
//store the instance in testList
testList.add(test);
}
}
//now just return the list with the desired values
return testList;
}
Not part of your question, but some advices:
There are plenty other ways to write code to achieve the same solution (take #Alex's answer as an example). I didn't posted any of them because looks like you're in learning phase, so it will be better for you to first achieve what you're looking for with your own effort (and a little of help).
Not sure if you're doing it (or not) but you should not use raw types. This is, you should always provide a generic type when the class/interface needs it. For example, it is better to define a variable as ArrayList<MyClass> myClassList rather than ArrayList myClass so the class become parameterized and the compiler can help you to avoid problems at runtime.
It is better to always program oriented to interfaces/abstract classes. This means, it is better to declare the variables as an interface or abstract class rather than the specific class implementation. This is the case for ArrayList and List:
List<String> stringList = new ArrayList<String>();
//above is better than
ArrayList<String> stringList2 = new ArrayList<String>();
In case you need to use a different implementation of the interface/abstract class, you will have to change the object initialization only (hopefully).
More info:
What is a raw type and why shouldn't we use it?
What does it mean to "program to an interface"?
Looks like you want to store days instead of lineNumber in your Test instances:
//comment this line
//Test test = new Test(value, lineNumber);
//use this one instead
Test test = new Test(value, days);
First of all you don't need to keep line number info in the test object because it can be inferred from the ArrayList that holds them. If you must though, it should be changed to an int. So,
class test
{
ArrayList items<Integer>;
int linenumber;
public test(int line, String[] input){
items=new ArrayList();
linenumber=line;
//populate with the line read by the Scanner
for(int i=0; i<input.lenth; i++)
items.add(Integer.parseInt(input[i]));
}
}
I use an ArrayList inside test because you don't know how many elements you'll be handling. Moving on to the scanner
Scanner fileScanner = new Scanner(new File(fname));
// fileScanner.useDelimiter("\n"); You don't need this!
String tmp[];
int line=0; //number of lines
while(fileScanner.hasNext()) {
line++;
//this returns the entire line, that's why you don't need useDelimeter()
//it also splits it on '.' I'm not sure if that needs to be escaped but
//just to be sure
tmp=fileScanner.nextLine() . split(Pattern.quote("."));
baseArrayList.add(new test(line, tmp));
}
fileScanner.close();
Here I use test to store the objects you read, I'm not sure what Base is supposed to be.
A Java Bean/construct is required that will hold the day and the item together. The following code will read the text file. Each line will be converted to a List where finally the application will populate the List DayItems collection properly.
public class DayItem {
private int day;
private String item;
public int getDay() {
return day;
}
public void setDay(final int day) {
this.day = day;
}
public String getItem() {
return item;
}
public void setItem(final String item) {
this.item = item;
}
}
And main code
public class ReadFile {
private static final List<DayItem> dayItems = new ArrayList<DayItem>();
public static void main(String args[]) throws FileNotFoundException{
final BufferedReader bufferReader = new BufferedReader(new FileReader("items.txt"));
int lineNumber=0;
try
{
String currentLine;
while ((currentLine = bufferReader.readLine()) != null) {
lineNumber++;
List<String> todaysItems = Arrays.asList(currentLine.split(":"));
addItems(todaysItems,lineNumber);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void addItems(final List<String> todaysItems,final int day){
int listSize = todaysItems.size();
for(int i=0;i<listSize;i++){
String item = todaysItems.get(i);
DayItem dayItem = new DayItem();
dayItem.setDay(day);
dayItem.setItem(item);
dayItems.add(dayItem);
}
}
}
I am trying to add object of type Shoe into the fixed array of type Shoe, but I have a problem with it.
In the addShoe method I am trying to add reference of type Shoe to the sh array like this: sh.add(s);
when I trie to run it I get this error:
Cannot invoke add(Shoe) on the array type Shoe[]
Eclipse recommends me to change it to 'length' and it doesn't make sens
I am also thinking I could write an else part of the addShoes method like this:
public void addShoe(Shoe s) throws ShoeException
{
if(s.getId() < 0) {
throw new ShoeException(s);
}
else {
if(numShoes<=10){
sh = Arrays.add(s, numShoes);
numShoes++;
}
}
}
It is just one of the ideas. Is it the correct way to do it?
public class TestShoe {
public static void main(String[] args) {
ShoeProcessor s = new Shoe();
Shoe s1 = new Shoe(7, "Black");
Shoe s2 = new Shoe(10, "Red");
try {
s.addShoe(s1);
s.addShoe(s2);
}catch(ShoeException bex){
System.out.println("Shoe Exception: " + bex);
}
}
}
public class ShoeProcessor
{
private Shoe [] sh;
private int numShoes=0;
private ShoeComparator<Shoe> sc;
public ShoeProcessor()
{
sh = new Shoe [10];
sc=new ShoeComparator<Shoe>();
}
public void addShoe(Shoe s) throws ShoeException
{
if(s.getId() < 0) {
throw new ShoeException(s);
}
else {
sh.add(s);
numShoes++;
}
}
}
Thank you for your help
I want to add I need to use array Shoe of fixed size.
I also want to add that I don't want to extend the array sh. I can add max 10 references of type Shoe to it. This is why I am also counting number of shoes added.
Probably I'm missing something: do you want replace sh.add(s); with sh[numShoes]= s; ?
Arrays in Java have a fixed size. You have two options:
Switch to using a List. This can dynamically grow when you add more items to it. For implementation you can use an ArrayList or LinkedList.
Try using System.arraycopy to resize your array each time you need to add to it. I don't recommend this. Internally, this is actually something that ArrayList does, but you are free to do it manually if you so choose.
edit: Just saw your edit. You can do something like:
public void addToList(Shoe shoe) {
if(shoeList.size() < 10) {
shoeList.add(shoe);
}
}
shoeArrayCount = 0;
public void addToArray(Shoe shoe) {
if(shoeArrayCount < 10) {
shoeArray[shoeArrayCount] = shoe;
shoeArrayCount++;
}
}
Depending on which method you choose to inplement.
I've already made another question close to this one several minutes ago, and there were good answers, but it was not what I was looking for, so I tried to be a bit clearer.
Let's say I have a list of Thread in a class :
class Network {
private List<Thread> tArray = new ArrayList<Thread>();
private List<ObjectInputStream> input = new ArrayList<ObjectInputStream>();
private void aMethod() {
for(int i = 0; i < 10; i++) {
Runnable r = new Runnable() {
public void run() {
try {
String received = (String) input.get(****).readObject(); // I don't know what to put here instead of the ****
showReceived(received); // random method in Network class
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
tArray.add(new Thread(r));
tArray.get(i).start();
}
}
}
What should I put instead of ** ?
The first thread of the tArray list must only access the first input of the input list for example.
EDIT : Let's assume my input list has already 10 elements
It would work if you put i. You also need to add an ObjectInputStream to the list for each thread. I recommend you use input.add for that purpose. You also need to fill the tArray list with some threads, use add again there.
Here's the solution:
private void aMethod() {
for(int i = 0; i < 10; i++) {
final int index = i; // Captures the value of i in a final varialbe.
Runnable r = new Runnable() {
public void run() {
try {
String received = input.get(index).readObject().toString(); // Use te final variable to access the list.
showReceived(received); // random method in Network class
} catch (Exception exception) {
exception.printStackTrace();
}
}
};
tArray.add(new Thread(r));
tArray.get(i).start();
}
}
As you want each thread to access one element from the input array you can use the value of the i variable as an index into the list. The problem with using i directly is that an inner class cannot access non-final variables from the enclosing scope. To overcome this we assign i to a final variable index. Being final index is accessible by the code of your Runnable.
Additional fixes:
readObject().toString()
catch(Exception exception)
tArray.add(new Thread(r))