ArrayList method return - java

I'm working in a project with DB. There are a method that collect info from the DB and set the info in ArrayList:
public ArrayList<Director> listAll(){
ArrayList<Director>list = new ArrayList<Director>();
Director direc = new Director();
int cont=0;
String sql = "select * from director;";
try{
ResultSet res = objBBDD.sentencia.executeQuery(sql);
while(res.next()){
direc.setCode(res.getInt("CODE"));
direc.setName(res.getString("NAME"));
direc.setNationality(res.getString("NATIONALITY"));
direc.setOscar(res.getInt("OSCAR"));
list.add(direc);
// THIS IS USE TO CONFIRM IF IT WORKS ///////////////////////////////////////
// JOptionPane.showMessageDialog(null,"Code:"+list.get(cont).getCode()+"Nombre"+list.get(cont).getName());
// cont++;
}
}catch (SQLException e) {
e.printStackTrace();
}
return list;
}
I use JOptionPane.showMessageDialog to see if I get info from DB and is added correctly to de ArrayList, and it's works.
Now the ArrayList back the invoker class, this is the method:
private void stackArray(){
ArrayList<Director>arrayDir = new ArrayList<Director> ();
ArrayList<Director>arrayDir = conexion.listAll();
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(0).getCode()+"Name"+arrayDir.get(0).getName());
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(1).getCode()+"Name"+arrayDir.get(1).getName());
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(2).getCode()+"Name"+arrayDir.get(2).getName());
}
Again I use the JOptionPane.showMesageDialog to show the first three positions, but it's not work, the problem, as far as I've seen, is all the positions have the same object saved (exactly the last).
Summarizing the ArrayList have the same object (last in DB), there are no problems at run or compile.
I don't know if I write something bad, or just a noob fail.

the problem, as far as I've seen, is all the positions have the same
object saved (exactly the last).
You are changing value of same instance Director. Thats why, you seen the last value of Director object. You should create new instance of Director with iteration of while loop.
ResultSet res = objBBDD.sentencia.executeQuery(sql);
while(res.next){
Director direc = new Director();// Declare Director instance here.
.....
list.add(direc);
}

Related

Trying to get more than 20 followers to display, how can i loop this to give me more? [duplicate]

I have been wondering if there is a way to access all the twitter followers list.
We have tried using call to the REST API via twitter4j:
public List<User> getFriendList() {
List<User> friendList = null;
try {
friendList = mTwitter.getFollowersList(mTwitter.getId(), -1);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (TwitterException e) {
e.printStackTrace();
}
return friendList;
}
But it returns only a list of 20 followers.
I tried using the same call in loop, but it cause a rate limit exception - says we are not allowed to make too many requests in a small interval of time.
Do we have a way around this?
You should definitely use getFollowersIDs. As the documentation says, this returns an array (list) of IDs objects. Note that it causes the list to be broken into pages of around 5000 IDs at a time. To begin paging provide a value of -1 as the cursor. The response from the API will include a previous_cursor and next_cursor to allow paging back and forth.
The tricky part is to handle the cursor. If you can do this, then you will not have the problem of getting only 20 followers.
The first call to getFollowersIDs will need to be given a cursor of -1. For subsequent calls, you need to update the cursor value, by getting the next cursor, as done in the while part of the loop.
long cursor =-1L;
IDs ids;
do {
ids = twitter.getFollowersIDs(cursor);
for(long userID : ids.getIDs()){
friendList.add(userID);
}
} while((cursor = ids.getNextCursor())!=0 );
Here is a very good reference:
https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/friendsandfollowers/GetFriendsIDs.java
Now, if the user has more than around 75000 followers, you will have to do some waiting (see Vishal's answer).
The first 15 calls will yield you around 75000 IDs. Then you will have to sleep for 15 minutes. Then make another 15 calls, and so on till you get all the followers. This can be done using a simple Thread.sleep(time_in_milliseconds) outside the for loop.
Just Change like this and try, this is working for me
try {
Log.i("act twitter...........", "ModifiedCustomTabBarActivity.class");
// final JSONArray twitterFriendsIDsJsonArray = new JSONArray();
IDs ids = mTwitter.mTwitter.getFriendsIDs(-1);// ids
// for (long id : ids.getIDs()) {
do {
for (long id : ids.getIDs()) {
String ID = "followers ID #" + id;
String[] firstname = ID.split("#");
String first_Name = firstname[0];
String Id = firstname[1];
Log.i("split...........", first_Name + Id);
String Name = mTwitter.mTwitter.showUser(id).getName();
String screenname = mTwitter.mTwitter.showUser(id).getScreenName();
// Log.i("id.......", "followers ID #" + id);
// Log.i("Name..", mTwitter.mTwitter.showUser(id).getName());
// Log.i("Screen_Name...", mTwitter.mTwitter.showUser(id).getScreenName());
// Log.i("image...", mTwitter.mTwitter.showUser(id).getProfileImageURL());
}
} while (ids.hasNext());
} catch (Exception e) {
e.printStackTrace();
}
Try This...
ConfigurationBuilder confbuilder = new ConfigurationBuilder();
confbuilder.setOAuthAccessToken(accessToken)
.setOAuthAccessTokenSecret(secretToken)
.setOAuthConsumerKey(TwitterOAuthActivity.CONSUMER_KEY)
.setOAuthConsumerSecret(TwitterOAuthActivity.CONSUMER_SECRET);
Twitter twitter = new TwitterFactory(confbuilder.build()).getInstance();
PagableResponseList<User> followersList;
ArrayList<String> list = new ArrayList<String>();
try
{
followersList = twitter.getFollowersList(screenName, cursor);
for (int i = 0; i < followersList.size(); i++)
{
User user = followersList.get(i);
String name = user.getName();
list.add(name);
System.out.println("Name" + i + ":" + name);
}
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1 , list));
listView.setVisibility(View.VISIBLE);
friend_list.setVisibility(View.INVISIBLE);
post_feeds.setVisibility(View.INVISIBLE);
twit.setVisibility(View.INVISIBLE);
}
This is a tricky one.
You should specify whether you're using application or per user tokens and the number of users you're fetching followers_ids for.
You get just 15 calls per 15 minutes in case of an application token. You can fetch a maximum of 5000 followers_ids per call. That gives you a maximum of 75K followers_ids per 15 minutes.
If any of the users you're fetching followers_ids for has over 75K followers, you'll get the rate_limit error immediately. If you're fetching for more than 1 user, you'll need to build strong rate_limit handling in your code with sleeps and be very patient.
The same applies for friends_ids.
I've not had to deal with fetching more than 75K followers/friends for a given user but come to think of it, I don't know if it's even possible anymore.

Java/Mysql: Get all resulted lines from a stored procedure and not only the last

I have a stored procedure in mysql that returns more than one lines.
My java code to execute it is:
preparedStmt = conn.prepareCall(queryString);
preparedStmt.setString(1, String.valueOf(patient_id));
//System.out.print("select patient data java file 1 ");
boolean results = preparedStmt.execute();
int rowsAffected = 0;
// Protects against lack of SET NOCOUNT in stored procedure
while (results || rowsAffected != -1) {
if (results) {
rs = preparedStmt.getResultSet();
break;
} else {
rowsAffected = preparedStmt.getUpdateCount();
}
results = preparedStmt.getMoreResults();
}
int i = 0;
obj = new JSONObject();
while (rs.next()) {
JSONArray alist = new JSONArray();
alist.put(rs.getString("patient_id"));
alist.put(rs.getString("allergy"));
alist.put(rs.getString("allergy_description"));
alist.put(rs.getString("allergy_onset_date"));
alist.put(rs.getString("agent_description"));
alist.put(rs.getString("agent"));
alist.put(rs.getString("severity"));
obj.put("ps_allergies", alist);
i++;
}
conn.close();
At the end, ps_allergies json object contains only the last line of the query. This is the print output:
["1","week",null,"2017-07-07","vacation home","test2","mobile contact"]
I want ps_allergies to contain something similar to
[["1","hydrogen peroxide","Nuts","2017-07-04","Nursing profressionals","43","Paramedical practinioners"],["1","week",null,"2017-07-07","vacation home","test2","mobile contact"]...]
Do you know how to fix this?
Not exactly knowing what library you use, but it might have something to do with this line:
obj.put("ps_allergies", alist);
A put method in general associates the specified value with the specified key in a map. Since you are constantly overwriting you key 'ps_allergies' in the loop it will only retain the last value.
You might want to associate a list/array to ps_allergies and you then add every alist object in this list/array.
I found the solution. Instead of put I'm using append method.
obj.append("ps_allergies", alist);
The resulted output now is:
[["1","hydrogen peroxide","Nuts","2017-07-04","Nursing professionals","43","Paramedical practitioners"],["1","chlorhexidine","test123","2017-07-15","mobile contact","test232","pager"],["1","Resistance to unspecified antibiotic","Feb3","2017-03-02","mobile contact","test232","pager"],["1","week",null,"2017-07-07","vacation home","test2","mobile contact"]]

returning 2 different values

i'm working with java in eclipse.I am trying to take 2 variables from my database and write it to an excel.My only problem is returning 2 different values(an integer and a string) from db reader method and send it to excel writer method which are in different classes.
Here is my db reader class:
public class DbConnection {
public void createConnection(String choice) {
try {
String myDriver = "com.mysql.jdbc.Driver";
String db = "jdbc:mysql://localhost/digiturkschema";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(db, "root",
"*****");
Statement st = conn.createStatement();
switch (choice) {
case "write":
ResultSet rs = st.executeQuery("SELECT * FROM channelstable");
while (rs.next()) {
int channelId = rs.getInt("channelNo");
String channelName = rs.getString("channelName");
}
}
} catch (Exception exception) {
System.out.print(exception.getStackTrace());
}
}
}
I need to return "channelId" and "channelName" from this method to this method:
public class WritingToExcel {
public void Write() throws IOException {
try {
JFileChooser f = new JFileChooser();
f.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
f.showSaveDialog(null);
System.out.println(f.getCurrentDirectory());
System.out.println(f.getSelectedFile());
String direction = f.getSelectedFile().toString() + "\\DigiTurkKanalListesi.xls";
WritableWorkbook workbook = Workbook.createWorkbook(new File(direction));
WritableSheet sheet = workbook.createSheet("Kanal Listesi", 0);
Label label = new Label(0, 0, "A label record");
sheet.addCell(label);
Number number = new Number(2, 1, 3.1459);
sheet.addCell(number);
workbook.write();
workbook.close();
} catch (WriteException e) {
e.getStackTrace();
}
}}
I know that writingToExcel class is not completed and it's ok,i can finish it if i can take these two variables to this class.By the way i am using MVC pattern so i have a controller class between them.I can write it too if it's necessary.
As #Ascalonian said, you can use Map or HashMap.
for example:
Map<Integer, String> channelInfo = new HashMap<Integer, String>();
You can also (but should not):
Create a new class with the values you need and return that class. (You will be doing extra work which you don't really need to.)
Create setter methods for those variables and use it before calling the method to write to excel. (requires caution as you can end up with undesired values if you mess the code)
There are multiple options
ArrayList<Objects> : During Iterating the resultSet prepare temporary List say tempList insert items into tempList and then after each iteration add tempList to Main List , Since ArrayList is a sequential list. So, insertion and retrieval order is the same. So you can return this from your dbReader() method .Then use them wherever you want
Your Arraylist will look like this
[ [1,Channel 1] , [2,Channel 2] , [3,Channel 3] ]
Map if order is important prefer LinkedHashMap if order is not your primary concern then opt for HashMap

Objects getting copied by reference and replacing all items in ArrayList

I understand that people have faced this issue before and I have gone through the previous posts.
I have an arrayList and I'm trying to add objects to it. During every add call, the same object reference is being copied. Though I have used the 'new' operator and am creating new objects. This is something basic and has worked previously when I create the object again during each iteration.
Any help is much appreciated.
Here is my code.
public List<Actor> readAllActors()
{
String selectMovie = "SELECT * from ACTOR;";
List<Actor> listOfActors = new ArrayList<Actor>();
try {
statement = conn.prepareStatement(selectMovie);
results = statement.executeQuery(selectMovie);
Actor a = new Actor();
while (results.next())
{
a = getActorFromResult(results);
listOfActors.add(new Actor(a.getId(), a.getFirstName(), a.getLastName(), a.getDateOfBirth()));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return listOfActors;
}
private Actor getActorFromResult(ResultSet results) throws SQLException {
// TODO Auto-generated method stub
int id = results.getInt("id");
String fname = results.getString("firstName");
String lname = results.getString("lastName");
String dob = results.getString("dateOfBirth");
Actor actor = new Actor(id, fname, lname, dob );
return actor;
}
I have tried printing the object in each iteration. It is fetching the right row from the table.. the new Actor() seems to have no effect in creating a new object reference!!
Your code is fine and can't pass the same reference all the time. You can check it via a == check of your listed objects.
You could refactor you code to
results = statement.executeQuery(selectMovie);
while (results.next())
{
listOfActors.add(getActorFromResult(results));
}
as you're creating a new Actor and thus a new object with an own reference after fetching the result set. This will also make the code clearer here.
Also return new Actor(id, fname, lname, dob ); will do the job in your result method. You're not using the self-descriptive local variable anyways.
I suspect your problem lies in your database. Try querying it with a database tool.
try to change that line
listOfActors.add(new Actor(a.getId(), a.getFirstName(), a.getLastName(), a.getDateOfBirth()));
to that
listOfActors.add(getActorFromResult(results));
and delete line
a = getActorFromResult(results);
Your references are for sure not the same, please check it in debugger.

Combine for loop and sql in java

I have 2 input dates: myStartDate,myEndDate and a table TEST_TABLE with columns
TEST_ID, TEST_USER,TEST_START, TEST_END
I need to check if the range of dates between myStartDate and myEndDate have corresponding records in the TEST_TABLE.
I also need to ensure that I don't retrieve duplicate records.
Here's a sample of the logic I have so far:
Assuming,
myStartDate=06/06/2012;myEndDate=06/09/2012
int diff = myEndDate - myStartDate; //In this case = 3
String myQuery = "SELECT * FROM TEST_TABLE WHERE"+ myStartDate +"BETWEEN TEST_START AND TEST_END OR "+ (myStartDate +1) +" BETWEEN TEST_START AND TEST_END OR"+ (myStartDate+2)+"BETWEEN TEST_START AND TEST_END OR"+(myStartDate+3)+"BETWEEN TEST_START AND TEST_END";
List <TestTableData> myList = new List();
//Exceute query & save results into myList using add method
Want to know if there's any way to test the range of dates between myStartDate &myEndDate using a for loop in java code, instead of the approach used above in myQuery.Also, how can I avoid duplicates.
New to Java so any help would be appreciated!
Use a ResultSet to iterate over the output, like the code below.
while (res.next()) {
String col1= res.getString("col1");
String col2 = res.getString("col2");
}
If you use an Array implementation , it does not allow for duplicate elements and hence there is no need to check for one.
But if you must use a list then , you could use the following code to remove any duplicate elements.
public static void removeDuplicates(List list)
{
Set set = new HashSet();
List newList = new ArrayList();
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
Object element = iter.next();
if (set.add(element))
newList.add(element);
}
list.clear();
list.addAll(newList);
}
I think what you are asking are some generic questions about how to read a database and how to handle dates in java. I will give you some sample code below. But I suggest you look at the java database tutorial http://docs.oracle.com/javase/tutorial/jdbc/index.html and the java.util.Date api doc http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/Date.html for more info.
Here is some sample code that specifically demonstrates how to implement your question:
// get the input dates
// they are hard coded in this example
// but would probably normally be passed in
String startDateStr = "2/3/03";
String endDateStr = "3/1/03";
// unfortunately, there are 2 "Date" classes in this code and you need to differentiate
// java.util.Date is the standard java class for manipulating dates
// java.sql.Date is used to handle dates in the database
// name conflicts like this are rare in Java
SimpleDateFormat dateFmt = new SimpleDateFormat("M/d/yy");
java.util.Date myStartDate = dateFmt.parse(startDateStr);
java.util.Date myEndDate = dateFmt.parse(endDateStr);
// conneect to the database
// I am using mysql and its driver class is "com.mysql.jdbc.Driver"
// if using a different database, you would use its driver instead
// make sure the jar containing the driver is in your classpath (library list)
// you also have to know the url string that connects to your database
Class.forName("com.mysql.jdbc.Driver").newInstance(); // loads the driver
Connection dbConn = DriverManager.getConnection(
"jdbc:mysql://localhost/testdb", "(db user)", "(db password)"
);
// get the database rows from the db table
// my table is named "testtable"
// my columns are named "DateStart" and "DateEnd"
Statement st = dbConn.createStatement();
String sqlStr = "Select * from testtable";
ResultSet rs = st.executeQuery(sqlStr);
// loop through the rows until you find a row with the right date range
boolean foundRange = false;
while (rs.next()) {
java.util.Date dbStartDate = rs.getDate("DateStart");
java.util.Date dbEndDate = rs.getDate("DateEnd");
if (myStartDate.before(dbStartDate)) continue;
if (myEndDate.after(dbEndDate)) continue;
foundRange = true;
break;
}
if (foundRange) {
// code that executes when range is found in db
} else {
// code that executes if range not found in db
}
dbConn.close();
Hope this helps you get started.

Categories

Resources