How do I use multidimensional arrays with array list? - java

I want to add some records from sql query but the output is not correct. Always return the last record.
The correct list is :
John
Nick
Mary
Joe
,but always return Joe.
This is the method to add the elements:
public ArrayList<String[][]> getFiledArrayList()
{
// ArrayList<String[][]> fieldsList = new ArrayList<>();
String[][] tempRow = new String[1][2];
ResultSet result;
String sql = "select id, name_of from field";
result = database.exeQueryStatement(sql);
try
{
while(result.next())
{
tempRow[0][0] = result.getString("id");
// System.out.println(tempRow[0][0]);
tempRow[0][1] = result.getString("name_of");
// System.out.println(tempRow[0][1]);
fieldsList.add(tempRow);
System.out.println(fieldsList.get(0)[0][1]);
}
}
catch (SQLException ex)
{
Logger.getLogger(FieldManage.class.getName()).log(Level.SEVERE, null, ex);
}
return fieldsList;
I put the id and the name_of in a String[1][2] table and I want to show the name_of in a jComboBox. Ι want to make an insert and watch the name_of with id
FieldManage fieldmanage = new FieldManage();
ArrayList<String[][]> listOfField;
listOfField = fieldmanage.getFiledArrayList();
String[] fields = new String[listOfField.size()];
System.out.println(listOfField.get(0)[0][0]);
for (int i=0; i<listOfField.size(); i++)
{
fields[i] = listOfField.get(i)[0][1];
System.out.println(fields[i]);//test print show always joe!
}
jComboFields.setModel(new javax.swing.DefaultComboBoxModel(fields));
This code always return Joe.
Also I want to know if there is better way to match an jcombo element with an id.

When populating fieldsList, you repeatedly add references to the same object (tempRow). When your loop modifies the contents of tempRow, all previously added entries also change (since they're the same object).
Move the following line inside the loop:
String[][] tempRow = new String[1][2];

You are trying to create an array of object values.
Using ArrayList<String[][]> is not the way to do this.
Create a class
public class Person {
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
self.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
self.name = name;
}
}
Then in your code....
ArrayList<Person> myPeople = new ArrayList<Person>();
Person p = new Person();
p.setName("mary");
p.setId(1);
myPeople.add(p);
Start from there, your doing it the hard way, and given that you are having problems understanding arrays and object references, learn the language before you start using multidimensional primitive arrays in conjunction with loops and collections.

Move this line:
String[][] tempRow = new String[1][2];
as the first line in your while(result.next()) loop.
What is happening:
if you put tempRow outside loop, in 2nd iterator on loop same array is modified i.e overwritten by next value. At the completion of while loop, your fieldsList contains the last element only at all indexes.
Run your loop 3 times and you'' see Mary as output.

Related

Iteration over nested arraylist structure shows unexpected results

I have a nested arraylist structure over which I need to iterate. See the following:
ArrayList<ArrayList<SubjectnameandMark>> level2arraylist = new ArrayList<ArrayList<SubjectnameandMark>>();
Then I have the following arraylists that I would add to the level2arraylist
ArrayList<SubjectnameandMark> st1 = new ArrayList<SubjectnameandMark>();
ArrayList<SubjectnameandMark> st2 = new ArrayList<SubjectnameandMark>();
ArrayList<SubjectnameandMark> st3 =new ArrayList<SubjectnameandMark>();
My SubjectnameandMark class is given below:
public class SubjectnameandMark
{
String name;
double mark;
SubjectnameandMark(String name, double mark)
{
this.name=name;
this.mark=mark;
}
}
I am adding the subject names and marks to each student(st1, st2...) arraylist in the following way:
SubjectnameandMark sub1 = new ServtermnameandWeight("math",1.0);
SubjectnameandMark sub2 = new ServtermnameandWeight("geo",1.0);
SubjectnameandMark sub3 = new ServtermnameandWeight("physics",0.389);
st1.add(sub1);
st1.add(sub2);
st1.add(sub3);
............
Note that this process is repeated for all st that is st1, st2, st3....
Finally I am adding all st arraylists to level2arraylist with the following:
level2arraylist.add(st1);
level2arraylist.add(st2);
level2arraylist.add(st3);
....................
Now I am trying to iterate over these nested arraylist to see the subject name and marks:
for (l=0;l<level2arraylist.size();l++)
{
for(n=0;n<level2arraylist.get(l).size();n++)
{
studenttomatch= level2arraylist.get(l);
Iterator<SubjectnameandMark> itr=studenttomatch.iterator();
while(itr.hasNext())
{
SubjectnameandMark st=(SubjectnameandMark)itr.next(); System.out.println(st.servterm+" "+st.servtermweight);
}
}
}
The problem is that not all subject and marks are shown. However, If I restrict the loop variable in the following way the specific record at that particular index is shown, for example I am only restricting to the first record (l=0;l<1) and the correct results are shown:
for (l=0;l<1;l++)
{
for(n=0;n<level2arraylist.get(l).size();n++)
{
studenttomatch= level2arraylist.get(l);
Iterator<SubjectnameandMark> itr=studenttomatch.iterator();
while(itr.hasNext())
{
SubjectnameandMark st=(SubjectnameandMark)itr.next();
System.out.println(st.servterm+" "+st.servtermweight);
}
}
}
There's no need for the double for-loop structure here since you're using an iterator. If you're iterating through all the elements in level2arraylist, then you don't need a for loop to iterate through all the elements in level2arraylist.get(l) because that's essentially what your iterator is doing. So simply just remove the inner for loop like so,
for (l=0;l<level2arraylist.size();l++)
{
studenttomatch= level2arraylist.get(l);
Iterator<SubjectnameandMark> itr=studenttomatch.iterator();
while(itr.hasNext())
{
SubjectnameandMark st=(SubjectnameandMark)itr.next();
System.out.println(st.servterm+" "+st.servtermweight);
}
}

Return String continuously - Data getting overwritten by ArrayList

Currently creating a tableview using JavaFX and came accross this problem where it would simply append the last element of the array (As all the other elements get overrwritten ..)
public void companyTable() {
for(CompanyData s: companydataList()){
companyDataTableView.getItems().setAll(s);
}
}
Where companyDataList is:
private List<CompanyData> companydataList(){
CompanyData company = new CompanyData("test",9,1);
for(String i : sim.getCompanyNames()) {
company.setPFCompanyName(i);
}
for(int j : sim.getCompanyValues()) {
company.setPFShareValues(j);
}
List<CompanyData> companydata = new ArrayList<>();
companydata.add(company);
return companydata;
}
The data gets added to this (Setters and getters of Strings)
private final StringProperty PFCompanyName;
private final IntegerProperty PFShareValues;
public CompanyData(String CompanyName, int ShareValue, int ClosingPence) {
this.PFCompanyName = new SimpleStringProperty(CompanyName);
this.PFShareValues = new SimpleIntegerProperty(ShareValue);
}
public String getPFCompanyName() {
return PFCompanyName.get();
}
public StringProperty PFCompanyNameProperty() {
return PFCompanyName;
}
public void setPFCompanyName(String PFCompanyName) {
this.PFCompanyName.set(PFCompanyName);
}
public int getPFShareValues(int j) {
return PFShareValues.get();
}
public IntegerProperty PFShareValuesProperty() {
return PFShareValues;
}
public void setPFShareValues(int PFShareValues) {
this.PFShareValues.set(PFShareValues);
}
Currently the output is:
CompanyName CompanyValue
Samsung 1093
But what I desire is:
CompanyName CompanyValue
Nokia 3
Apple 1
HTC 9
Samsung 1093
The method setAll(...) replaces all the elements currently in the list with the ones you provide (it "sets them all"). So each time you iterate through your loop, you replace all the elements with the current one. At the end you will just have one element in the table.
An ObservableList is a subtype of the standard java.util.List, so you can call any of the standard list methods. E.g. you can just add each element instead:
public void companyTable() {
for(CompanyData s: companydataList()){
companyDataTableView.getItems().add(s);
}
}
Of course, you don't really need to write the loop yourself, you can just add them all:
public void companyTable() {
companyDataTableView.getItems().addAll(companydataList());
}
or, if it's what you need, set them all:
public void companyTable() {
companyDataTableView.getItems().setAll(companydataList());
}
Furthermore, your companydataList() method only creates one CompanyData instance, and then constantly changes it. Here is your current implementation, with comments explaining what each line you wrote does:
private List<CompanyData> companydataList(){
// create a single instance:
CompanyData company = new CompanyData("test",9,1);
// repeatedly change the name of that instance:
for(String i : sim.getCompanyNames()) {
company.setPFCompanyName(i);
}
// repeatedly change the value of that instance:
for(int j : sim.getCompanyValues()) {
company.setPFShareValues(j);
}
// create an empty list:
List<CompanyData> companydata = new ArrayList<>();
// add one object to the list
companydata.add(company);
// return the list containing the single object:
return companydata;
}
You need to create a CompanyData instance for each of the name/value pairs, and add each instance to the list. Assuming sim.getCompanyNames() and sim.getCompanyValues() return lists (or arrays; I will assume they are lists) of the same length, you need to do something like
private List<CompanyData> companydataList(){
List<String> companyNames = sim.getCompanyNames();
List<Integer> companyValues = sim.getCompanyValues();
List<CompanyData> companydata = new ArrayList<>();
for (int i = 0 ; i < companyNames.size(); i++) {
String name = companyNames.get(i);
int value = companyValues.get(i);
CompanyData company = new CompanyData();
company.setPFCompanyName(name);
company.setPFShareValues(value);
companydata.add(company);
}
return companydata;
}
Obviously, it would be far more sensible to have sim, which I assume is some kind of data accessor, return a List<CompanyData> directly in the first place, instead of two different lists for the different properties.

Refining data in java array

Ok, I have reworked the question. I was wondering what the best way to refine an array of objects would be.
I have an array of objects. These objects will be referred to as objectA and this can be seen below:
public class objectA {
private String ID;
private String groupID;
private String isEligable;
public String getID()
{
return ID;
}
public void setID(String ID)
{
this.ID = ID;
}
public String getgroupID()
{
return groupID;
}
public void setgroupID(String groupID)
{
this.groupID = groupID;
}
public String getIsEligable()
{
return isEligable;
}
public void setIsEligable(String isEligable)
{
this.isEligable = isEligable;
}
}
As you can see the object has an ID, groupID and an isEligable variable. These objects will be added to an array and there can only ever be a maximum of two objects which have the same groupID. One where isEligable = "F" and one where isEligable = "T". What I want to do is efficiently refine the array so that the group which has 2 objects associated to it only displays the object which isEligable = "T", ie, disregard the object in the same group where isEligable = "F". So in the below example only object 1 and 3 would be in the array:
Public class testExample
{
objectA[] objectArray = new objectA[3]
objectA object1 = new objectA();
object1.setID = "1"
object1.setGroupID = "0001"
object1.setIsEligable = "F"
objectA object2 = new objectA();
object2.setID = "2"
object2.setGroupID = "0002"
object2.setIsEligable = "F"
objectA object3 = new objectA();
object3.setID = "3"
object3.setGroupID = "0002"
object3.setIsEligable = "T"
objectArray[0] = object1;
objectArray[1] = object2;
objectArray[2] = object3;
}
I am assuming I need to sort them into a group somehow then loop round each group to determine which one (if any) where isEligable = "T" and if so add that to a new array else if none meet that criteria in the group just add the one where isEligable ="F" to the array.
My issue is though that I dont know how big the new array should be. I suppose this is where I should use an array list? though I wanted to avoid this if possible but I suppose in this case an array list makes the most sense. I also think this seems quite costly in terms of performance?
Any opinions, help or guidance would be greatly appreciated.
Thanks.

separating unique values in an algorithm

I am decomposing a series of 90,000+ strings into a discrete list of the individual, non-duplicated pairs of words that are included in the strings with the rxcui id values associated with each string. I have developed a method which tries to accomplish this, but it is producing a lot of redundancy. Analysis of the data shows there are about 12,000 unique words in the 90,000+ source strings, after I clean and format the contents of the strings.
How can I change the code below so that it avoids creating the redundant rows in the destination 2D ArrayList (shown below the code)?
public static ArrayList<ArrayList<String>> getAllWords(String[] tempsArray){//int count = tempsArray.length;
int fieldslenlessthan2 = 0;//ArrayList<String> outputarr = new ArrayList<String>();
ArrayList<ArrayList<String>> twoDimArrayList= new ArrayList<ArrayList<String>>();
int idx = 0;
for (String s : tempsArray) {
String[] fields = s.split("\t");//System.out.println(" --- fields.length is: "+fields.length);
if(fields.length>1){
ArrayList<String> row = new ArrayList<String>();
System.out.println("fields[0] is: "+fields[0]);
String cleanedTerms = cleanTerms(fields[1]);
String[] words = cleanedTerms.split(" ");
for(int j=0;j<words.length;j++){
String word=words[j].trim();
word = word.toLowerCase();
if(isValidWord(word)){//outputarr.add(word);
System.out.println("words["+j+"] is: "+word);
row.add(word_id);//WORD_ID NEEDS TO BE CREATED BY SOME METHOD.
row.add(fields[0]);
row.add(word);
twoDimArrayList.add(row);
idx += 1;
}
}
}else{fieldslenlessthan2 += 1;}
}
System.out.println("........... fieldslenlessthan2 is: "+fieldslenlessthan2);
return twoDimArrayList;
}
The output of the above method currently looks like the following, with many rxcui values for some name values, and with many name values for some rxcui:
How do I change the code above so that the output is a list of unique pairs of name/rxcui values, summarizing all relevant data from the current output while removing only the redundancies?
If you just need a Collection of all words, use a HashSet Sets are primarily used for contains logic. If you need to associate a value with your string use a HashMap
public HashSet<String> getUniqueWords(String[] stringArray) {
HashSet<String> uniqueWords = new HashSet<String>();
for (String str : stringArray) {
uniqueWords.add(str);
}
return uniqueWords;
}
This will give you a collection of all the unique Strings in your array. If you need an ID use a HashMap
String[] strList; // your String array
int idCounter = 0;
HashMap<String, Integer> stringIDMap = new HashMap<String, Integer>();
for (String str : strList) {
if (!stringIDMap.contains(str)) {
stringIDMap.put(str, new Integer(idCounter));
idCounter++;
}
}
This will provide you a HashMap with unique String keys and unique Integer values. To get an id for a String you do this:
stringIDMap.get("myString"); // returns the Integer ID associated with the String "myString"
UPDATE
Based on the question update from the OP. I recommend creating an object that holds the String value and the rxcui. You can then place these in a Set or HashMap using a similar implementation to the one provided above.
public MyObject(String str, int rxcui); // The constructor for your new object
MyObject mo1 = new MyObject("hello", 5);
Either
mySet.add(myObject);
will work or
myMap.put(mo1.getStr, mo1.getRxcui);
What is the purpose of the unique word ID? Is the word itself not unique enough since you are not keeping duplicates?
A very basic way would be to keep a counter going as you are checking new words. For each word that doesn't already exist you could increase the counter and use the new value as the unique id.
Lastly, might I suggest you use a HashMap instead. It would allow you to both insert and retrieve words in O(1) time. I am not entirely sure what you are going for, but I think the HashMap might give you more range.
Edit2:
It would be something a little more along these lines. This should help you out.
public static Set<DataPair> getAllWords(String[] tempsArray) {
Set<DataPair> set = new HashSet<>();
for (String row : tempsArray) {
// PARSE YOUR STRING DATA
// the way you were doing it seemed fine but something like this
String[] rowArray = row.split(" ");
String word = row[1];
int id = Integer.parseInt(row[0]);
DataPair pair = new DataPair(word, id);
set.add(pair);
}
return set;
}
class DataPair {
private String word;
private int id;
public DataPair(String word, int id) {
this.word = word;
this.id = id;
}
public boolean equals(Object o) {
if (o instanceof DataPair) {
return ((DataPair) o).word.equals(word) && ((DataPair) o).id == id;
}
return false;
}
}

creating names for linked lists while looping (Java)

I have implemented a simple linked list class and I would now like to use it in a loop. I am wondering how to best assign names to the list in each iteration of the loop.
Essentially I am looping over some integers, and I would like to just give each list the name of that integer, but I cannot say
List i = new List();
right ?
There probably is an easy way to do this, but I m not sure how, and would be grateful for
I think you're confusing the role of variables with the role of collections. From your question I gather that you want to create a list for each index in your loop, and you would like to later be able to access that list by its index:
ArrayList<LinkedList<String>> listOfLists = new ArrayList<LinkedList<String>>();
for(int i = 0; i < 10; i++)
{
LinkedList<String> list = new LinkedList();
listOfLists.add(list);
// do stuff to the list...
}
// access
LinkedList<String> thirdList = listOfLists.get(2); // index 2 = third entry
So you see, the LinkedLists are not named according to the value of i, but you can still access them by a given value of i.
First of all, if if not for learning purposes, it is highly recommended not to implement your own classes for stuff that is already implemented in libraries.
For Lists, you should check out the collection framework: http://docs.oracle.com/javase/tutorial/collections/
I am not sure what you mean by "the name of that integer".
I assume you want to create a List of elements that contain both an integer, and a String representing the name of the value that is hold in the integer.
If it is the case, the best way to do this probably is to create your own Object:
class NamedInteger {
private int value;
private String name;
public NamedInteger(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
public void setValue(int value) {
this.value = value;
}
public void setName(String name) {
this.name = name;
}
}
The advantage of this method, is that later, if you want to add other information to your object, it is very easy to do so.
And then, just have a List of those objects....
public static void main(String[] args) {
List<NamedInteger> list = new LinkedList<NamedInteger>();
list.add(new NamedInteger(1, "Hello");
...
}

Categories