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");
...
}
Related
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.
This is what i have so far, i'm trying to sort a bunch of List<String>'s based on the value of an index.
LinkedHashSet<List<String>> sorted = new LinkedHashSet<List<String>>();
How do i sort the LinkedHashSet in order from Highest to Lowest index 2 value of the List's?
Example input:
List<String> data1 = Database.getData(uuid);
double price = Double.valueOf(data1.get(2))
data1.add("testval");
data1.add("testval");
data1.add("100.00");
sorted.add(data1);
and on another seperate List:
List<String> data2 = Database.getData(uuid);
double price = Double.valueOf(data2.get(2))
data2.add("anotherval");
data2.add("anotherval");
data2.add("50.00");
sorted.add(data2);
Output of the sorted LinkedHashSet in descending order.
testval testval 100.00
anotherval anotherval 50.00
Sorry if this is confusing, im not sure where to go about sorting like this.
Create a new class to represent you complex objects. There is no need to store multiple values in a list when you can do it in objects.
public class ComplexObject {
private String description1;
private String description2;
private Double value;
public ComplexObject(String description1, String description2, Double value) {
this.description1 = description1;
this.description2 = description2;
this.value = value;
}
public void setDescription1(String description1) {
this.description1 = description1;
}
public String getDescription1() {
return description1;
}
public void setDescription2(String description2) {
this.description2 = description2;
}
public String getDescription2() {
return description2;
}
public void setValue(Double value) {
this.value = value;
}
public Double getValue() {
return value;
}
}
Then add elements to the list and sort it using a new, custom, comparator:
public static void main(String[] args) {
List<ComplexObject> complexObjectList = new ArrayList<ComplexObject>();
//add elements to the list
complexObjectList.add(new ComplexObject("testval","testval",100.00d));
complexObjectList.add(new ComplexObject("anotherval","anotherval",50.00d));
//sort the list in descending order based on the value attribute of complexObject
Collections.sort(complexObjectList, new Comparator<ComplexObject>() {
public int compare(ComplexObject obj1, ComplexObject obj2) {
return obj2.getValue().compareTo(obj1.getValue()); //compares 2 Double values, -1 if less , 0 if equal, 1 if greater
}
});
//print objects from sorted list
for(ComplexObject co : complexObjectList){
System.out.println(co.getDescription1()+" "+co.getDescription2()+" "+co.getValue());
}
}
Output:
testval testval 100.0
anotherval anotherval 50.0
Firstly, you shouldn't use a LinkedHashSet but a TreeSet. LinkedHashSet will retain the insertion order without sorting.
Secondly, you need to initialize your TreeSet with a Comparator that compares based on whichever value of your List is required, that is, if you know the index of the String that will represent a double value in advance. Otherwise I would recommend using custom objects instead of List.
If you decide to use custom objects, you don't necessarily need to initialize your TreeSet with a Comparator as second argument.
Instead, you could have your custom objects implement Comparable, and implement a one-time comparation logic there.
It all depends on whether you only need to sort in a particular order.
Finally, custom objects will require you to override equals and hashCode.
First, and extracted from Oracle's Java reference:
This linked list defines the iteration ordering, which is the order in which elements were inserted into the set
So you can't sort your data just inserting it into the LinkedHashSet.
You may be confusing that set implementation with SortedSet. SortedSet allows you to pass a comparator which will determine the elements order in the data structure.
On the other hand, I don't know whether you chose you List<String> arbitrarily but it seems to me a wiser option to aggregate your the 3 strings as a class attributes. The point is that, if your elements are always going to be 3 elements, being the last one a double value: Why do you need a dynamic structure as a List?
EDIT
Here you have a possible better implementation of what you want:
public class Element
{
public Element(String a, String b, double val) {
this.a = a;
this.b = b;
this.val = val;
}
#Override
public String toString() {
return a + "\t" + b + "\t" + val;
}
public String a;
public String b;
public double val;
}
And you can use this class to store your elements. An example of use:
SortedSet<Element> sorted = new TreeSet<>(new Comparator<Element>() {
#Override
public int compare(Element o1, Element o2) {
return (new Double(o1.val)).compareTo(o2.val);
}
});
sorted.add(new Element("testval", "testval", 100.0));
sorted.add(new Element("anotherval", "anotherval", 50.0));
for(Element el: sorted)
{
System.out.println(el);
}
Note that the comparator is given as an instance of an anonympous inner class implementing Java's Comparator interface.
If I have a certain number of objects which each take multiple parameters, how can I fill an array with one particular parameter for all objects, but have the order of the elements in the array based off another parameter. For example, I have this code:
public CollegeList(double gpa, int act, int sat, String name, String location){
this.gpa = gpa;
this.act = act;
this.sat = sat;
this.name = name;
this.location = location;
if(act/36.0>sat/2400.0){
this.score = 0.6*gpa*25.0+0.4*(act/36.0)*100.0;
}else{
this.score = 0.6*gpa*25.0+0.4*(sat/2400.0)*100.0;
}
this.scoreDistance = Math.abs(this.score-MainActivity.scoreDouble)/MainActivity.scoreDouble;
}
public double getGpa(){
return this.gpa;
}
public int getAct(){
return this.act;
}
public int getSat(){
return this.sat;
}
public String getName(){
return this.name;
}
public String getLocation(){
return this.location;
}
public double getScore(){
return this.score;
}
public double getScoreDistance(){
return this.scoreDistance;
}
Here, I would like the name parameter for all objects that I may create to populate a String array, but have those names go in ascending order by the double scoreDistance in the array. I'm sorry if the wording of this question is bad, but I hope it makes sense.
1) Create a CollegeList[] or ArrayList<CollegeList> containing the objects you want to sort.
2) Create a Comparator<CollegeList> that compares two CollegeList objects by comparing the scoreDistance. In Java 8 (yes, I know this isn't available for Android, but other readers may find this useful):
Comparator<CollegeList> compareByScoreDistance = (CollegeList a, CollegeList b) -> Double.compare(a.getScoreDistance(), b.getScoreDistance());
In Java 7:
Comparator<CollegeList> compareByScoreDistance = new Comparator<CollegeList>() {
#Override
public int compare(CollegeList a, CollegeList b) {
return Double.compare(a.getScoreDistance(), b.getScoreDistance());
}
};
3) Sort the array or ArrayList using the comparator. If it's an array:
Arrays.sort(theArray, compareByScoreDistance);
If it's an ArrayList, use Collections.sort instead of Arrays.sort.
4) Now you can create the string array by going through the CollegeList[] or ArrayList<CollegeList> and creating an array or ArrayList using getName(). For example, if your list is an ArrayList, then you can use this from #user3717646's answer:
for (CollegeList collegeList : theList) {
nameList.add(collegeList.getName());
}
Or using Java 8:
String[] names = theList.stream().map(CollegeList::getName).toArray(String[]::new);
or
ArrayList<String> names = new ArrayList<>(theList.stream().map(CollegeList::getName).collect(Collectors.toList()));
EDIT: Code has now been tested, and several mistakes fixed.
Try Using ArrayLists. Following sample code is given for two CollegeList objects.
ArrayList<CollegeList> collegeLists=new ArrayList<>(); // To store all CollegeList Objects
ArrayList<String> nameList=new ArrayList<>(); // To store Names
CollegeList cl1=new CollegeList(12, 45, 5, "Name1", "Location1");
CollegeList cl2=new CollegeList(12, 45, 5, "Name2", "Location2");
collegeLists.add(cl1);
collegeLists.add(cl2);
for (CollegeList collegeList : collegeLists) {
nameList.add(collegeList.getName());
}
collegeLists stores all CollegeList objects.
then you can get each and every parameter using get methods and put the in to seperate aarraylists.
If you want to sort the arraylist, You can uose Collections.sort(nameList); to do it.
I google it before, the answer was no but I wonder if there is any possible way.
Is there a way to give names to row and column of a 2D array in Java?
No you can't. 2D array is just array of arrays. You'll need to have 2 other arrays with names for columns and rows
Probably you can use something different (another data structure like Map) if you need to.
More dimensional arrays are normally the approach to avoid classes. For example:
String[][] persons;
persons[0][1];
If you are confronted with such a code you should first make it more readable.
public static final int FIRSTNAME = 0;
public static final int LASTNAME = 1;
persons[0][FIRSTNAME];
persons[0][LASTNAME];
A better way to encapsulate the data structure is a class:
public class Person {
private String firstname;
private String lastname;
public String getFirstname(){
return firstname;
}
public String getLastname(){
return lastname;
}
}
Person[] persons;
person[0].getFirstname();
Or if you want the change to be as minimal as necesarry:
public class Person {
public static final int FIRSTNAME = 0;
public static final int LASTNAME = 1;
private String[] personData;
public String getFirstname(){
return personData[FIRSTNAME];
}
public String getLastname(){
return personData[LASTNAME];
}
}
Make your choice
It seems that your requirement is to identify the rows. For that instead of using arrays you can use Map which are formed by unique keys.
You can define like
Map<String,ArrayList<SomeObject>> map = new HashMap<String,ArrayList<SomeObject>>();
By this way, you can put a key which can work as a row identifier as it is unique and add an entire arrayList as its value
Forget about associative arrays.You are in Java now and go for advanced way :)For this Java provides maps.You need to use the maps.
Here is a example
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
Map<String ,Integer> m1 = new HashMap<String ,Integer>();
m1.put("name1", 8);
m1.put("name2", 31);
m1.put("name3", 12);
m1.put("name4", 14);
System.out.println();
System.out.println(" Map Elements");
System.out.print("\t" + m1);
}
}
If you need more deeply,As you are saying
is there a way to give names to row and column of a 2D array in Java?
then need to store a datastructure against a key then it is possible.You may store a Map against a key and then you will call it a multimap which will look like this
Map<X, Map<Y,Z>> map1;
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.