Adding objects to an array based on a String attribute? - java

I'm coding an application for a year-long school project, and its purpose is to display articles for teens to read that educate them on current events.
I want to make several different ArrayLists of categories to store the Articles in. The objects are Article(String URL, String Category, String title)
I'm wondering if, instead of doing this:
Article p = new Article(
"http://www.google.com", "economics", "Potato Article");
if(category.equals("elections"))
elections.add(p);
if(category.equals("economics"))
economics.add(p);
// etc.
If there is some thing I can do like this:
String name = category;
(something).something(name);
name.add(p);
So basically I want to add the article to an ArrayList of the same name as its category, assuming the ArrayList is made already, and the category of the particular article matches the desired ArrayList.

Data structure should be Map<String, List<Article>>, so a sample code could be as follows :
Map<String, List<Article>> map =
new HashMap<String, List<Article>>();
map.put("elections", new ArrayList<Article>());
map.put("economics", new ArrayList<Article>());
Article article1 = new Article(
"http://www.google.com", "economics", "Potato");
Article article2 = new Article(
"http://www.yyy.com", "elections", "xxx");
map.get(article1.getCategory()).add(article1);
map.get(article2.getCategory()).add(article2);

Related

How to parse a CSV with multiple key-value pairs?

I have a CSV in this format:
"Account Name","Full Name","Customer System Name","Sales Rep"
"0x7a69","Mike Smith","0x7a69","Tim Greaves"
"0x7a69","John Taylor","0x7a69","Brian Anthony"
"Apple","Steve Jobs","apple","Anthony Michael"
"Apple","Steve Jobs","apple","Brian Anthony"
"Apple","Tim Cook","apple","Tim Greaves"
...
I would like to parse this CSV (using Java) so that it becomes:
"Account Name","Full Name","Customer System Name","Sales Rep"
"0x7a69","Mike Smith, John Taylor","0x7a69","Tim Greaves, Brian Anthony"
"Apple","Steve Jobs, Tim Cook","apple","Anthony Michael, Brian Anthony, Tim Greaves"
Essentially I just want to condense the CSV so that there is one entry per account/company name.
Here is what I have so far:
String csvFile = "something.csv";
String line = "";
String cvsSplitBy = ",";
List<String> accountList = new ArrayList<String>();
List<String> nameList = new ArrayList<String>();
List<String> systemNameList = new ArrayList<String>();
List<String> salesList = new ArrayList<String>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile)))
{
while ((line = br.readLine()) != null) {
// use comma as separator
String[] csv = line.split(cvsSplitBy);
accountList.add(csv[0]);
nameList.add(csv[1]);
systemNameList.add(csv[2]);
salesList.add(csv[3]);
}
So I was thinking of adding them all to their own lists, then looping through all of the lists and comparing the values, but I can't wrap my head around how that would work. Any tips or words of advice are much appreciated. Thanks!
By analyzing your requirements you can get a better idea of the data structures to use. Since you need to map keys (account/company) to values (name/rep) I would start with a HashMap. Since you want to condense the values to remove duplicates you'll probably want to use a Set.
I would have a Map<Key, Data> with
public class Key {
private String account;
private String companyName;
//Getters/Setters/equals/hashcode
}
public class Data {
private Key key;
private Set<String> names = new HashSet<>();
private Set<String> reps = new Hashset<>();
public void addName(String name) {
names.add(name);
}
public void addRep(String rep) {
reps.add(rep);
}
//Additional getters/setters/equals/hashcode
}
Once you have your data structures in place, you can do the following to populate the data from your CSV and output it to its own CSV (in pseudocode)
Loop each line in CSV
Build Key from account/company
Try to get data from Map
If Data not found
Create new data with Key and put key -> data mapping in map
add name and rep to data
Loop values in map
Output to CSV
Well, I probably would create a class, let's say "Account", with the attributes "accountName", "fullName", "customerSystemName", "salesRep". Then I would define an empty ArrayList of type Account and then loop over the read lines. And for every read line I just would create a new object of this class, set the corresponding attributes and add the object to the list. But before creating the object I would iterate overe the already existing objects in the list to see whether there is one which already has this company name - and if this is the case, then, instead of creating the new object, just reset the salesRep attribute of the old one by adding the new value, separated by comma.
I hope this helps :)

Replacing ArrayLists with HashMaps

I am currently working on a project where I am replacing the ArrayLists in my code with HashMaps and I've run into a problem. In this section of my code I am creating a new "Book" from my book class and in the "get book" section is where I am having the problem. I am trying to check the (now)HashMap books to see if the book ID from the getId() method match the bookID of the book object. How Should I go about Iterating over my HashMap with the Book object?
This is my HashMap: HashMap<String, String> books = new HashMap<String, String>();
if (users.containsValue(new User(userID, null, 0))
&& books.containsValue(new Book(bookID, null))) {
// get the real user and book
Book b = null;
User u = null;
// get book
for (Book book : books) {
if (book.getId().equalsIgnoreCase(bookID)) {
b = book;
break;
}
}
You probably needs something like this. I've used names instead of ID's, but I hope you get the drift...
// setting up the test
HashMap<String, String> borrowers = new HashMap<String, String>();
borrowers.put("Lord of the Rings", "owlstead");
borrowers.put("The Hobbit", "sven");
borrowers.put("Vacuum Flowers", "owlstead");
// find out what I borrowed from the library
String userID = "owlstead";
List<String> booksBorrowed = new ArrayList<>();
// iterating through the books may not be very efficient!
for (String bookName : borrowers.keySet()) {
if (borrowers.get(bookName).equals(userID)) {
booksBorrowed.add(bookName);
}
}
// print instead of a return statement
System.out.println(booksBorrowed);
There are only Strings in your Hashmap.
No Books.
As there are no Books in the HashMap, you will never be able to get a Book object out of it.
If you want to identify Book objects with String objects, a HashMap works, but you have to set it up in this way:
HashMap<String, Book> books = new HashMap<String, Book>();
Here's a full working example of how a Hashmap could be used with Book objects:
import java.util.HashMap;
public class Book
{
private String title;
private int pages;
public Book(String title, int pages)
{
this.title = title;
this.pages = pages;
}
public String toString()
{
return title + ", " + pages + "p.";
}
public static void main(String[] args)
{
//creating some Book objects
Book theGreatBook = new Book("The great Book of awesomeness", 219);
Book klingonDictionary = new Book("Klingon - English, English - Klingon", 12);
//the Map:
HashMap<String, Book> library = new HashMap<String, Book>();
//add the books to the library:
library.put("ISBN 1", theGreatBook);
library.put("ISBN 2", klingonDictionary);
//retrieve a book by its ID:
System.out.println(library.get("ISBN 2"));
}
}
Why do you use Strings to identify objects?
The Strings are not unique, so if two books have the same ID, you will run into problems.
I would add the ID of an object as a data field to the object itself.
Making the association of an ID to an object in a HashMap works, but is very lose.
Without the map, the association is gone.
It's also prone to error, as typos in your Strings cannot be cached by the compiler.
Maybe you run into a NullPointerException at runtime.
Especially because also your User class has such an "ID" I am wondering if you add this to every class and would like to say that there really is no need to do this (unless you have other reasons).
To identify an object, simply use the reference to the object.
If you have a typo in one of your variable names that reference an object, the compiler will be able to tell you so.

convert fetched data into string , string array map

i am fetching a data from sqlite in android which is as follows
URL PHONE
---------------------------------
/test/img1.png 98989898
/test/img1.png 61216121
/test/img2.png 75757575
/test/img2.png 40404040
/test/img3.png 36363636
now i want to create such a map which stores the data as follows
/test/img1.png [98989898 , 61216121 ]
/test/img2.png [75757575 , 40404040 ]
/test/img3.png [36363636]
so that i can pass the whole map to the function which function eventually in background pick up the image url and send the data to the arrays listed to the phone number. so how can i transform the data that i have fetched into the key to string array style ?
I'd create a Map<String, List<String>> (aka "multi-map"). You don't have to know how many phone numbers for a given URL before you start if you use List<String>. That's not so if you choose the array route.
Map<String, List<String>> results = new HashMap<String, List<String>>();
while (rs.next()) {
String url = rs.getString(1);
String phone = rs.getString(2);
List<String> phones = (results.contains(url) ? results.get(url) : new ArrayList<String>());
phones.add(phone);
results.put(url, phones);
}
Google Collections has a multi-map that you can use out of the box, but I think you'll agree that this is sufficient.
If you want to store more items (e.g. name) you should start thinking about an object that encapsulates all of them together into one coherent thing. Java's an object-oriented language. You sound like you're guilty of thinking at too low a level. Strings, primitives, and data structures are building blocks for objects. Perhaps you need a Person here:
package model;
public class Person {
private String name;
private Map<String, List<String>> contacts;
// need constructors and other methods. This one is key
public void addPhone(String url, String phone) {
List<String> phones = (this.contacts.contains(url) ? this.contacts.get(url) : new ArrayList<String>());
phones.add(phone);
this.contacts.put(url, phones);
}
}
I'll leave the rest for you.
If you go this way, you'll need to map a result set into a Person. But you should see the idea from the code I've posted.

Using ArrayList to store variables

I'm coding a project to store an array of objects, probably in an arraylist.
So, my object has data elements, getters and setters. I do not have an idea how to access the elements of the object.
For example my object is a book which has the following data elements.
Book
->Author
->Price
->Date
If the price of a certain book changes, how do I update the arrayList? Do I need a 2d arrayList? I think indexOf would not work because it is an object? Not really sure.
I'm just a newbie in programming, so I'm not sure if arrayList is the right data structure to use. Thank you very much for reading this, your help will be appreciated.
You can access an object in an ArrayList by it's index. Say you want the third book:
List<Book> lisOfBooks = someFunctionWhichGetsListOfBooks();
Book book = listOfBooks.get(2);
(Remember indexes start at 0 in java) Then you can do:
String Author = book.getAuthor();
or to set the price:
book.setPrice(newPrice);
If you do not know where in the list the particular book is you have 2 choices: 1) iterate through the list until you find the book you want or 2) you can use a HashMap. But you need to decide what to key the book on (what makes each book unique?). Let's say you'll be looking up books by id. Then you can put all your books in a HashMap keyed by an Integer id:
HashMap<Integer, Book> bookHash = new HashMap<Integer, Book>();
for (Book book : listOfBooks) {
bookHash.put(book.getId(), book);
}
Then to retrieve any book you can do:
Book book = bookHash.get(bookId);
Obviously this assumes your Book class has appropriate getter and setter methods. E.g:
public class Book {
private int id;
private String author;
...
public String getAuthor() {
return author;
}
public void setPrice(price) {
this.price = price;
}
...
}
An ArrayList is a good implementation if you need to store your objects in a list. A good alternative for a collection of books: a Map implementation. This is useful if every book can be identified by a unique key (name, ISBN number, ...) and you use that key to "get" a book from the collection.
A book is an object on its on and should be modeled with a Book class. So if you want to store books in list structure, this would be OK:
List<Book> books = new ArrayList<Book>();
books.add(new Book("Robert C. Martin","Clean Code"));
books.add(new Book("Joshua Bloch","Effective Java"));
For a map, a code fragment could look like this:
Map<String, Book> books = new HashMap<String, Book>();
books.put("978-0132350884", new Book("Robert C. Martin","Clean Code"));
books.put("978-0321356680", new Book("Joshua Bloch","Effective Java"));
Edit - finding a book and updating the price
With a list, you have to iterate through the list until you find the object that represents the book you're looking for. It's easier with the map shown above, if you always can use the ISBN, for example. With the list, it goes like this:
List<Book> books = getBooks(); // get the books from somewhere
for (Book book:books) {
if (matchesSearchCriteria(book)) { // some method to identify a book, placeholder!
book.setPrice(newPrice); // modify the books price
break;
}
}
You need to create a custom "datatype", basically a POJO (Plain old java object) that will have fields for all the parameters you want. Let's call it Book:
class Book {
public String author;
public double price;
public Date date;
}
Of course it's better to have private fields and encapsulate with getters and setters, i jsut wrote that for simplicity.
Then you can create a List of Book objects.
List<Book> books = new ArrayList<Book>();
And add Books to it which you can then later iterate through like this:
for (Book book : books) {
System.out.println(book.getAuthor());
}
I'd be looking at some sort of lookup data structure like a hashmap, for example
HashMap<String, Hashmap<String,String>> books = new Hashmap<String, HashMap<String, String>>();
HashMap<String, String> bookelements = new HashMap<String,String>();
bookelements.put("Author","J.K Rowling");
bookelements.put("Price","£5");
bookelements.put("Year","2000");
books.put("harry potter",bookelements);
//Get elements like so
String author = (String)books.get("harry potter").get("Author");

dynamic filtering of java object

I have following java object
Obj:
----
String id;
List<A>;
A:
--
String A_ID;
String A_PROPERTY;
What I am looking for is to be able to search in a given object. ex: search in a list where A.A_ID = 123
I need to dynamically pass
A_ID = 123
and it would give me
A_Property
I know I could search through a list through iterator, but is there already frameworks out there which lets you do this?
thanks
lambdaj is a very nice library for Java 5.
For example:
Person me = new Person("Mario", "Fusco", 35);
Person luca = new Person("Luca", "Marrocco", 29);
Person biagio = new Person("Biagio", "Beatrice", 39);
Person celestino = new Person("Celestino", "Bellone", 29);
List<Person> people = asList(me, luca, biagio, celestino);
it is possible to filter the ones having more than 30 years applying the following filter:
List<Person> over30 = filter(having(on(Person.class).getAge(), greaterThan(30)), people);
Something like Quaere. From their site:
Quaere is an open source, extensible framework that adds a querying syntax reminiscent of SQL to Java applications. Quaere allows you to filter, enumerate and create projections over a number of collections and other queryable resources using a common, expressive syntax.
why do you need a framework? how about
public String lookupPropertyById(String id)
{
for (A a : myList)
{
if (id.equals(a.id))
return a.property;
}
return null; // not found
}
Hashmap if you only search by one property which has the same type for every inputed object. For example, a string.
The object 1 has the string "Obj1" for key and the second object has the string "Test2"
for key. When you use the get method with the parameter "Obj1", it will return the first object.
P.S. It's really hard to read your "pseudo-code".
Using a hashmap.
Map<String,A> map = new HashMap<String,A>();
A a = new A();
a.id = "123";
a.property="Hello there!";
map.put( a.id , a );
Later
map.get( "123"); // would return the instance of A and then a.property will return "Hello there!"

Categories