ArrayList - possible to read out the element name? - java

Heyho everyone!
My project is a bit bigger so I decided to short it a bit and showing only the problem code, which i have currently. On the first, im programming on a console. Reading six strings from a Scanner, before I save them in a variable i'm doing a validity check (length, special signs, etc...). So I decided to make this in an extra method check_newCustomer(). I used an ArrayList to return more as one value. So now is the point that I need the captured inputs in the main() function or any other method which writes the new Customer in the database. Problem is now i don't know how I can reference to userID, firstname, secondname... in other method. I just can refer with an index. But I would prefer it when i can use the variable names to refer to it. So its much easier on the other methods to handle with strings. Possible?
public static void main(String[] args) {
ArrayList<String> newCustomer = new ArrayList<String>();
check_newCustomer (newCustomer);
}
public static void check_newCustomer(ArrayList<String> newCustomer) throws IOException {
String userID = null;
String firstname = null;
String secondname = null;
String street = null;
String zipcode = null;
String city = null;
// validity check before I fill the input fields
...
// fill arraylist
newCustomer.add(userID);
newCustomer.add(firstname);
newCustomer.add(secondname);
newCustomer.add(street);
newCustomer.add(zipcode);
newCustomer.add(village);
}
Thanks!

No, the value in the ArrayList is just a reference. The fact that you originally referred to it using a different variable is irrelevant.
You could use a Map<String, String> instead... but it would be much cleaner to have a Customer class which had fields for the various pieces of information. If you want multiple customers, you can then have a List<Customer>.

One needs to make a class Customer, just a group of fields. Instead of a list of Strings.
public class Customer {
String userID;
String firstname;
String secondname;
String street;
String zipcode;
String city;
}
And in the code:
Customer newCustomer = new Customer();
newCustomer.userID = ....
System.out.println(newCustomer.userID);

When you pass check_newCustomer (newCustomer); you are only passing a copy of the array list. In this case, the original array list newcustomer is left intact while a new copy whose scope is within the method check_newCustomer is where all the strings are stored. You can either create a new class for Customers or you can create a class and have your array list as a class variable and check_newCustomer as a class method. In the latter case, it is much simple.
class customer
ArrayList<String> newCustomer;
public static void main(String[] args) {
newCustomer = new ArrayList<String>();
check_newCustomer ();
}
public static void check_newCustomer() throws IOException {
String userID = null;
String firstname = null;
String secondname = null;
String street = null;
String zipcode = null;
String city = null;
// validity check before I fill the input fields
...
// fill arraylist
newCustomer.add(userID);
newCustomer.add(firstname);
newCustomer.add(secondname);
newCustomer.add(street);
newCustomer.add(zipcode);
newCustomer.add(village);
}
}
This must work.

Related

Adding a string parameter to an object

This is what I need to do. I'm not really sure how though.
addGrade() method: Accepts a String parameter representing a new grade (including category prefix) to add to the GradeBook object; and returns true if added or false if not added (e.g., if category was not in the category array).
private String[] categories;
public Gradebook(String[] categoriesIn) {
categories = categoriesIn;
}
public boolean addGrade(String newGrade) {
categories[] = new Gradebook(newGrade);
}
I tried that above for starters but that's not correct
you cannot instantiate Gradebook Class in to variable categories, because variable categories is Array of String
try to instance new array, then assign to variable categories

initializing an object in an array

I've been playing around with arrays for some time and this problem has been troubling me.
I created a user defined object and declared it in an array like this: `Property regesteredAssets[] = new Property[200];
And here's my constructor: `
public Property(String newPropertyName,String newPropertyAddress,String newPropertyType, String newPropertyDescription)
{
propertyName[arraySequence] = newPropertyName;
propertyFullAddress[arraySequence] = newPropertyAddress;
propertyType[arraySequence] = newPropertyType;
propertyDescription[arraySequence] = newPropertyDescription;
arraySequence++;
}
I want to initialize each array regesteredAsssets[] according to my desire. How can I do it?
Do I have to use arrays in my attributes in the Property class too?
You do not need your attributes to be arrays, unless a particular asset has multiple of something. In this case, I don't think it does. You can greatly simplify your code as follows:
public class Property {
private String name, address, type, description;
public Property(String name, String address, String type, String description) {
this.name = name;
this.address = address;
this.type = type;
this.description = description;
}
public static void main(String[] args) {
Property[] registeredAssets = new Property[200];
registeredAssets[0] = new Property("Joe Bloggs", "555 Fake St.", "IMPORTANT", "Lorem Ipsum Dolor");
// etc.
}
}
If you have an array of type Property, you can set each of the elements up using the following code:
regesteredAssets[0] = new Property( enterYourParametersHere );
I assume the fields in your Property constructor are single fields, and therefore you do not need to set them using the array notation field[index] = value, and indeed, if the Property class is of the consistency I think it is, then this will produce a compilation error.
If you wanted to set up multiple entries in your array, you could perform the initialisation step inside a loop, providing a loop index to the index of the array as below:
for( int i = 0; i < 10; i++ )
{
regesteredAssets[i] = new Property( enterYourParametersHere );
}
I hope this helps...

Efficient way to split an array and organize into multiple array

I got a String[] which contains of multiple user details. Something like this:
Wilson#$20#$Male=#=Raymond#$25#$Male=#=Sophie#$20#$Female
I wanted to split the string up and organize it into multiple array. Such as one array for Name, one array for Age and another array for Gender. Up to this point I managed to split the String[] into something like this.
String[] User = student.split("=#=");
User[0] = Wilson#$20#$Male
User[1] = Raymond#$25#$Male
User[2] = Sophie#$20#$Female
I don't really know how to organize it from this point. Any comments and answers are highly appreciated!
EDIT
Wilson#$20#$Male=#=Raymond#$25#$Male=#=Sophie#$20#$Female
The above part is actually a value that is returned from the server and I wanted to handle this value. Thank you for all the replies. I think I understand a bit in theory wise, but I'm having slightly issue in implementing codes.
I agree with the suggestions of creating a class for each user - it's the Object Oriented way. So I included it in the example below. But you could probably change it easy enough if you want to do arrays or some other structure.
However, what I want to add is a way to use the Java classes java.util.regex.Pattern and java.util.regex.Matcher to extract both records AND fields in one go from your input string. (I haven't programmed for Android, I assume they are available though.)
The general plan for the pattern is: (record delimiter or nothing)(field1)(delim)(field2)(delim)(lastfield)(record delimiter + rest of input)
The algorithm basically loops through the input with the above pattern. The pattern extracts various groups for the fields (depending on how your record's format) and then also a last group that contains the remainder of the input string. This remainder is used as the new input string for the next loop. So each iteration of the loop does one record.
Here is more complete example code which you can run. You might need to study up on regular expressions to understand the pattern, which is the important part of the algorithm. You can start with the Javadoc for the java.util.regex.Pattern class.
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestPatternMatch {
public static void main(String[] args) {
List<User> result = new ArrayList<>();
String input =
"Wilson#$20#$Male=#=Raymond#$25#$Male=#=Sophie#$30#$Female";
Pattern recPatt =
Pattern.compile("^(=#=|.{0})(.+?)#\\$(\\d+)#\\$(.+?)(?==#=)(.*$)");
// ^match start of line
// ^match record delimiter or nothing
// ^match name field (reluctant)
// ^match field delim
// ^match age field
// ^match field delim
// match gender field^
// zero-width (non recording) lookahead for record delimiter^
// match rest of line until end^
Matcher recMatcher;
String workStr = input; // start with whole input
while (workStr != null && workStr.length() > 0) {
recMatcher = recPatt.matcher(workStr);
if (recMatcher.matches() && recMatcher.groupCount() >= 5) {
result.add(
new User(
recMatcher.group(2), //name
Integer.parseInt(recMatcher.group(3)), //age
recMatcher.group(4) //gender
)
);
workStr = recMatcher.group(5); // use tail for next iteration
} else {
workStr = null;
}
}
System.out.println(result); //show result list contents
}
}
class User {
String name;
int age;
String gender;
/** All argument constructor */
public User(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
/** Show contents of object fields */
public String toString() {
return "User ["+ name + ", " + age + ", " + gender + "]";
}
}
The basic pattern structure can be reused for many different record formats.
Create a User object to store all fields (name, age, gender) and create a list to hold all data.
Your best bet here, is to use an object to hold these values. Objects are the standardized way to hold values that relate to one another, in one Object. ie:
public class Person
{
private String name;
private int age;
private String gender;
// Gender could be a boolean value really, but you've stored it as a String.
}
In the constructor you would request each value and assign it to these fields. It would look something like:
public Person(String name, int age, String gender)
{
this.name = name;
// etc etc
}
That way you have one array, with no need to do any tokenizing of Strings to get to individual values :). You will also need to implement some Accessors and Mutators to get at the values within the Object.
Why not create a User class and maintain a list of User instances.
class User {
String name;
String gender;
int age;
}
The best solution would be to create an class User. If you want to avoid it, try:
String[] User = student.split("=#=");
String [][] details=new String[user.length][3];
String [] temp=new String[3];
for(int i=0;i<User.length;i++){
temp=User.split("//");
for(j=0;j<3;j++){
details[i][j]=temp[j];
}
}

Java Remove common elements between 2 ArrayList of objects

I have a Java class as
class Students{
private String fName;
private String lName;
private String uName;
public Students(String fName, String lName, String uName) {
this.fName = fName;
this.lName = lName;
this.uName = uName;
}
public String getuName() {
return uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getfName() {
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getlName() {
return lName;
}
public void setlName(String lName) {
this.lName = lName;
}
}
Also I call this using
public class TestClass {
public static void main(String[] args) {
Students students1 = new Students("xyz","abc","xyzAbc");
Students students2 = new Students("poi","son","poison");
Students students3 = new Students("yog","jos","yogjos");
Students students4 = new Students("xyz","abc","xyzAbc");
Students students5 = new Students("pon","son","xyzAbc");
Students students6 = new Students("yog","jos","someotherUName");
Students students7 = new Students("yog","jos","someotherUName2");
List studentList1 = new ArrayList();
List studentList2 = new ArrayList();
studentList1.add(students1);
studentList1.add(students2);
studentList1.add(students3);
studentList2.add(students4);
studentList2.add(students5);
studentList2.add(students6);
}
}
Now I want a filtered list which would contain only unique "uName" values. Thus I want the comparison between "uName" field of each list and remove common ones.
At the end I would want 2 filtered list for studentList1 and studentList2.
I read about the removeAll method, but it seems to work with List of Integer/String data and not with List of Objects (as in my case).
You can put your list to set and then (if you need) to take it back:
new ArrayList(new HashSet<String>(list)) creates list that contains only unique elements from source list.
1. If you want each list to have unique uName value, then you can use TreeSet from java.util.Collection along with Interface Comparator from java.util.Comparator.
2. If you want to merge both the list and have unique uName, then combine both the list and then use TreeSet and Comparator.
3. Comparator gives the flexibility to compare in more than one way...
You can still use removeAll if the Objects in the List implement equals() properly.
AbstractCollection, which is the base for most kind of List implementations (including ArrayList) uses contains() in its implementation of removeAll. ArrayList's implementation of contains relies on indexOf(), which lastly uses equals().
You could implement equals() in your Student class to specify that an Student is equal to another if and only their uName fields are equal.
Please note that equals has associated semantics (see its javadoc), and you should be careful when choosing how to implement it. Consider if two student instances really represent the same student when their uNames are equal. In my opinion, this sounds like a very specific requirement of how to sort these things out and should not impact the semantics of the class.
You'll be much better off with #AlexR or #KumarVivekMitra's approach.
Firstly, you should be typing your lists:
List<Students> studentList1 = new ArrayList<Students>();
Secondly, implement hashCode() and equals() on your Students class that both delegate to uName:
public boolean equals(Object o) {
return o instanceof Students && ((Students)o).uName.equals(uName);
}
public int hashCode() {
return uName.hashCode();
}
Now removeAll() will work just fine.
Another option is to use Set, which only allows unique values as determined by the equals() method. If you add the above methods to your class, you could just do this:
Set<Students> students = new HashSet<Students>();
then add what you like to it and there will only ever be unique uName students in it.
btw, you should name your class in the singular - ie Student not Students.
You could also try using the apache commons CollectionUtils.disjunction. (link: http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html#disjunction(java.util.Collection, java.util.Collection))
Your class Student should override methods hashcode and equals, so youy object can be unique by name. Here you can read how to do that.
Also note that all objects which are maintained in some collection should have those methods overriden, so you always know how are they compared.
In next step you can use removeAll method or the solution with Set, it's up to you :-)
Set example
List<String> list = new ArrayList(new HashSet<String>(studentList)); // here is your unique list
Or you could use custom Comparator instead of overriding hashcode and equals but if you want your students always unique, you should override them
A full working solution could be as follows.
Class Student{
.....
......
.....
public boolean equals(Object o) {
return o instanceof Students && ((Students)o).uName.equals(uName);
}
public int hashCode() {
return uName.hashCode();
}
}
Set studentList1 = new hashSet();
Set studentList2 = new hashSet();
Put your elements in these Sets.
Also if you want unique non-matching elements in both Sets. then write as follows.
studentList1.removeAll(studentList2 );

Specific Datatype for this situation?

I want to pull data from a database. Name, Age, Sex, Location.(maybe more fields)
I want to hold the data in an object similar to how I would expect it to look in a JSON object.
Like:
myData{
row1[name:beavis, age:48, sex:male, location:Joburg]
row2[name:quintus, age:43, sex:, location:Helsinki]
...up to say 500 rows
}
So i'd like to be able to do tempName = row(i).name and so on in java.
Any suggestions.
// Defines a Person datatype
public class Person {
// fields
private String name;
private int age;
private String location;
// gets the value of a field
public String getName() {
return name;
}
// sets the value of a field
public void setName(aName) {
this.name = aName;
}
}
What I did here was define a Person type with a number of fields. Also I give here an example of a setter and getter for the name field. You can put them in an array or collection. For example:
Person people[] = new Person[2];
people[0] = new Person();
people[0].setName("Alice");
You can also dispense with the setters and getters by making the fields public, but I wouldn't recommend it.
A straight translation of that data structure would be along the lines of
List<Map<String, Object>> myData
so you'd be able to call
tempName = (String) myData.get(i).get("name");
Like the JSON array, this doesn't enforce typing (which you'll have to deal with explicitly in Java) and doesn't limit the fields to only those from the database.
If all the database values are strings, things get cleaner as no casts are necessary.
List<Map<String, String>> myData
tempName = myData.get(i).get("name");

Categories

Resources