ArrayList manipulation in java - java

Arraylist<Books> booksdtoList=new ArrayList<>();
List<Object[]> modelList =null;
modellist=repostory.getbooks("FICTION");
booksdtoList =mapdto(booksdtoList,modellist);
modellist=repostory.getbooks("COMIC");
booksdtoList =mapdto(booksdtoList,modellist);
Arraylist<Books> booksdtoList mapDto(Arraylist<Books> booksdtoList, List<Object[]> modelList){
Books books=null;
for (model:modelList){
books=new Books((String)model[0],(String)model[1]));
booksdtoList.add(books);
}
return booksdtoList;
}
Will booksdtoList contain all the list of books or will it override any object within list?
Is it best practice to send ArrayList as argument and add? If not please suggest best one.

I can't say really what is best practice but I would probably instantiate the List in the mapping method if it is always expected to be empty before calling it:
List<Books> mapDTO(List<Object[]> modelList) {
List<Books> booksDTOList = new ArrayList<>();
Books books = null;
for (Object[] model : modelList){
books = new Books((String)model[0], (String)model[1]);
booksDTOList.add(books);
}
return booksDTOList;
}
Note also that it's best to use the List interface for the object.
To collect all books from multiple calls:
List<Books> booksDTOList=new ArrayList<>();
// ....
booksDTOList.addall(mapDTO(modelList1));
booksDTOList.addall(mapDTO(modelList2));
booksDTOList.addall(mapDTO(modelList3));
If you do choose to pass the list to the mapping method, you don't need to return it since Java is pass by reference (the list object that is inside the mapping method is the same object instance as in the caller).
void mapDTO(Arraylist<Books> booksDTOList, List<Object[]> modelList){
Books books = null;
for (Object[] model : modelList){
books = new Books((String)model[0], (String)model[1]);
booksDTOList.add(books);
}
}
To answer your first question, adding objects to a List (ArrayList or otherwise) will not overwrite already existing elements in the list.
Edit I updated all examples with camelCase method and object names (and corrected some syntax errors).
One more change you could do (based on the information available) is to change the modelList to contain String arrays:
void mapDTO(Arraylist<Books> booksDTOList, List<String[]> modelList){
Books books = null;
for (String[] model : modelList){
books = new Books(model[0], model[1]);
booksDTOList.add(books);
}
}

Related

How to loop through a List of Objects

I have a class called Group. Inside Group there is a list the contains objects of type Customer, like so:
Group.java:
private List<Customers> customers;
public List<Customer> getCustomers() {
return customers;
}
Then, like above, the class Customer has list that contains object of type EmailAddress, like so:
Customer.java:
private List<EmailAddress> emailAddresses;
public List<EmailAddress> getEmailAddress() {
return emailAddresses;
}
I want to be able to put this list of email addresses into my own list that I can then manipulate how I want. So in my Main.java I have:
Main.java:
List<Customer> customerList = group.getCustomers(); //group is the object to get <Customer> List
for (int i=0; i<customerList.size(); i++) {
List<EmailAddress> emails = customerList.get(i).getEmailAddresses();
}
Will I then, outside of this for loop, have a List of all the emails of the customers that I can use? Is this the correct way to populate a list that I can then utilize and pull data from outside of this loop? Outside of the loop I want to be able to look at different parts of the list like:
emails.get(3);
or
emails.get(7);
at my own discretion.
You need to initialize the list outside the for cycle
List<EmailAddress> emails = new ArrayList<>();
for (int i=0; i<customerList.size(); i++) {
emails.add(customerList.get(i).getEmailAddresses());
}
List<Customer> customerList = group.getCustomers();
List<EmailAddress> finalEmailAddressList = new ArrayList<>();
for (Customer : customerList) {
if (customer != null) {
finalEmailAddressList.add(customer.getEmailAddresses());
}
}
This should give you a list of all email addresses in the end. You can also use the addAll method to add a collection to a collection (at specific indexes also), in this case, a list.
If access to data is required from an outer scope, the data has to exist in the outer scope. Therefore, you need to declare it in the outer scope of the loop:
List<Customer> customerList = group.getCustomers();
List<EmailAddress> emails = new ArrayList<>(customerList.size());
for (Customer customer : customerList) {
emails.addAll(customer.getEmailAddresses();
}
You can do it with streams:
List<Group> groupList = ...
List<EmailAddress> address = groupList
.stream()
.flatMap(g -> g.getCustomers().stream())
.flatMap(c -> c.getEmailAddresses().stream())
.collect(Collectors.toList());
You can do it in functional style:
List<EmailAddress> emails = costumerList.stream()
.map(Customer::getEmailAddresses)
.flatMap(Collection::stream)
.collect(Collectors.toList());
The most interesting part here is the flatMap() method which does two things:
It maps a List<EmailAddress> to a Stream<EmailAddress> by using method reference of the Collection.stream() method
It flattens the result so that the result is of type Stream<EmailAdress>
Consequently, the result of the collect() method will be of type List<EmailAdress>
In contrast, if the flatMap() line was omitted, the result would be of type List<List<EmailAddress>>.
Similarly, if the map() method was used instead of flatmap(), the result would be of type List<Stream<EmailAddress>>

Access Values from an ArrayList That is inside another ArrayList

java.util.List records = new java.util.ArrayList();
java.sql.ResultSet rs = selectestatement.executeQuery(query1);
while (rs.next()) {
java.util.List record = new java.util.ArrayList();
record.add(rs.getString("WHLO").trim());
record.add("888509018579");
record.add(rs.getString("ITEM_CODE").trim());
record.add(rs.getString("ARRIVAL_DATE").trim());
record.add(rs.getString("PAIRS_PER_CASE").trim());
record.add(rs.getString("ATS").trim());
records.add(record);
}
In this code, Final arraylist is the "records array". This records arraylist contents few record arrays.
How can i access the 1st element of record arraylist from the records arraylist?
Don't use raw types:
List<List<String>> records = new ArrayList<>();
List<String> record = new ArrayList<>();
...
records.add(record);
This way records.get(i) will return a List<String> instead of an Object, so you can access the elements of the inner List:
String first = records.get(0).get(0);
What you really want is a class containing your row data.
class RecordData {
public String whlo;
public long someNumber = 888509018579;
public String itemCode;
public String arrivalDate;
public String pairsPerCase;
public String ats;
}
and then do
java.util.List<RecordData> records = new java.util.ArrayList<>();
while (rs.next()) {
RecordData record = new RecordData();
record.whlo = rs.getString("WHLO").trim();
record.itemCode = rs.getString("ITEM_CODE").trim();
record.arrivalDate = rs.getString("ARRIVAL_DATE").trim();
record.pairsPerCase = rs.getString("PAIRS_PER_CASE").trim();
record.ats = rs.getString("ATS").trim();
records.add(record);
}
In fact, you want to make the members private and accessible via getters and setters, and use LocalDate for the arrivalDate and int for the pairsPerCase member, but the first point is not using a List to store the retrieved values but wrap it in a business-oriented class.
You can do something like this
((ArrayList)records.get(0)).get(0) to access the first element of the array list that is in the first position of the records array list.
Please note that if you specify what does the records contains (in this case records will contains array lists) then you won't need to cast the element to array list.
List<List<String>> records = new ArrayList<ArrayList>();
{...}
records.get(0).get(0); //You don't need the cast because Java already knows that what it is inside records are Lists

How to compare and reorder an ArrayList of objects based on a list of another objects?

I have 2 arraylists, one of type String and the other is a custom class Person.
List names = new ArrayList<String>();
List people = new ArrayList<Person>();
Both lists are populated like so:
names.add("bob");
names.add("joe");
names.add("tom");
people.add(new Person("joe")); //Assuming Person has a name property
people.add(new Person("tom"));
people.add(new Person("bob"));
Notice that the same names have been used in both lists, but added in different order. How can I sort the people arraylist in the same order as the names?
Strange requirement, but you can do it by using a Map:
Map<String, Person> personMap = new HashMap<>();
//Assuming people is declared rightfully as List<Person> rather than just List
for (Person people : people) {
personMap.put(person.getName(), person);
}
List<Person> results = new ArrayList<>();
for (String name : names) {
if (personMap.containsKey(name)) {
results.add(personMap.get(name));
}
}
//in case you need to work with people only
people.clear();
people.addAll(results);
Since the names array can apparently be in an arbitrary order, the concept of "sorting" isn't very applicable. The most direct approach, I think, is to rebuild the people array from the given names array by using a map. Something like this might work:
void reoderPeople(ArrayList<Person> people, ArrayList<String> names) {
// first build the map
Map<String, Person> map = new HashMap<>();
for (Person p : people) {
map.add(p.getName(), p);
}
// now re-create the people array
people.clear();
for (String name : names) {
people.add(map.get(name));
}
}
This assumes that there is a one-to-one correspondence between the elements of names and people based on the name. If that's not a correct assumption, then this approach would have to be modified accordingly.
Use a comparator for sorting people which uses ordering of names list. (Untested code below)
Collections.sort(people, new Comparator<Person>(){
public int comapre(Person a, Person b) {
Integer indexA = names.indexOf(a.getName());
Integer indexB = names.indexOf(b.getName());
return indexA.compareTo(indexB);
}
});

Add ArrayList to another ArrayList in java with Iterator

I have a huge problem with my code:
public class BookStore
{
private ArrayList<Book> books;
}
/**
* This method takes the author's name as a String parameter and returns an
* arraylist of all the books written by that author. It uses a while loop
* and an iterator, locates the books written by that author (case-insensitive)
* and adds them to another arraylist.
*/
public ArrayList<Book> getBooksByAuthor(String authorName){
ArrayList<Book> getBooksByAuthor = new ArrayList<Book>();
Iterator<Book> aBook = books.iterator();
while(aBook.hasNext()){
Book aBookd = aBook.next();
if (authorName.equalsIgnoreCase(aBookd.getAuthor())){
books.add(getAuthor());
books.addAll(getBooksByAuthor);
}
}
return getBooksByAuthor.size();
}
Those 3 lines
books.add(getAuthor());
books.addAll(getBooksByAuthor); and the
return getBooksByAuthor.size();
I'm pretty sure that they are completely wrong. I tried different ways to do it ,but it didn't work. I really don't understand how to do that. Could someone help me?. Thank you for your time!
I'm fairly certain you wanted to add the book(s) with matching author's name to a new List. Something with an implicit iterator using a for-each loop
List<Book> al = new ArrayList<>();
for (Book book : books) {
if (authorName.equalsIgnoreCase(book.getAuthor())) {
al.add(book);
}
}
return al;
or using an explicit Iterator like
List<Book> al = new ArrayList<>();
Iterator<Book> iter = books.iterator();
while (iter.hasNext()) {
Book book = iter.next();
if (authorName.equalsIgnoreCase(book.getAuthor())) {
al.add(book);
}
}
return al;
is there any specific need for the iterator and a while-loop instead of a foreach loop?
what (i think) you'd like to achive is in normal language is: we have an empty collection/list as result. for each book in the list of books, check if the author has an equal name to the given name - if the names are equal, we add the book to the resulting collection/list.
that in code looks like:
public ArrayList<String> getBooksByAuthor(String authorName) {
ArrayList<Book> result = new ArrayList<Book>();
for (Book aBook : books) { //[for each notation in java ][1]
if (authorName.equals(aBook.getAuthor())) {
result.add(aBook);
}
}
return result;
}
if you'd like to use a while loop, read up the foreach/while loop conversion in the this link.
in addition and as mentioned in the comments, your code has some semantic and syntactic errors:
your return type is wrong (int instead of ArrayList)
your class definition closing brace ends before your method definition
you add the author object (probably a string) to your books-collection
you never add any book to your resulting collection
you try to addAll objects of your (empty) collection getBooksByAuthor to your books, instead of adding some/single books to your getBooksByAuthor collection
[1] http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html

Difference bettween transformTuple and For loop on query Result - Hibernate

I have an HQL as select p,c from Person p,ContactCard c where c.fk_pid=p.id I executed this query as HQL using this code:
List<Person> personsWithContactCard = new ArrayList<Person>();
List<object[]> quryResult = new ArrayList<object[]>();
String qry = "select p,c from Person p,ContactCard c where c.fk_pid=p.id";
quryResult = session.createQuery(qry).list();
for(object[] obj : quryResult )
{
Person person = new Person();
person = (Person)obj[0];
person.setContactCard = (ContactCard )obj[1];
personsWithContactCard.add(person);
person=null;
}
By taking query result in list of object array and looping on query result I fill persons list.
But after reading about ResultTransformer Interface I come to know that with this interface I can transform queryResult in to desired list so I changed my code To :
String qry = "select p,c from Person p,ContactCard c where c.fk_pid=p.id";
personsWithContactCard = session.createQuery(qry).setResultTransformer(new ResultTransformer() {
#Override
public Object transformTuple(Object[] tuple, String[] aliases)
{
Person person = new Person();
person = (Person)obj[0];
person.setContactCard = (ContactCard )obj[1];
return person ;
}
#Override
public List transformList(List collection)
{
return collection;
}
}).list();
This code gives me persons list with for looping.
So my question is : What is the difference between transformTuple and For loop?
Does the both are same in performance and processing sense?
Which will be more good as per performance?
And what is the use of transformList()?
Update :
After understanding use of ResultTransformer as explained in answer given by #bellabax I did one small change in code as follows:
personsWithContactCard = session.createQuery(qry).setResultTransformer(new ResultTransformer() {
#Override
public Object transformTuple(Object[] tuple, String[] aliases)
{
Person person = new Person();
person = (Person)obj[0];
person.setContactCard = (ContactCard )obj[1];
return person ;
}
#Override
public List transformList(List collection)
{
return null;
}
}).list();
I changed transformList() method to return null if I execute this code I am getting null personsWithContactCard list. Why transformList() method is need to return collection when I am not using it? And when I supposed to use transformList() and transformTuple() means how I can decide which to use?
There aren't differences in terms of result usually, but using a ResultTransformer:
is the standard Hibernate method to process tuple and future (break) changes about how HQL is processed and tuple returned will be masked by a ResultTransformer without code changes
give you the possibilities to decorate or delegate (for example)
so the choice is the ResultTransformer.
About ResultTransformer.transformList():
Here we have an opportunity to perform transformation on the query
result as a whole
instead in transformTuple you can manipulate only one row of returned set.
EDIT:
As quoted above the javadoc of ResultTransformer.transformList() is pretty clear: this function allow to modify the whole list to remove duplicate, apply type conversion and so on and the result of ResultTransformer.transformList() is forwarded to Query.list() method so, return null from transformList whill return null from list().
This is how Query and ResultTransformer are tied.

Categories

Resources