Array getting overwritten with the last item java - java

I am having my array overwritten by the last Object and Am not sure why as a System.out.println() on the same Location prints all the items correctly. I am attempting to update a table containing Student scores with their ranks but all students get the last item on the array.
public static void updateSubjectRank(String subject, String extype, int academicyear, int semester, int level) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Criteria cr = session.createCriteria(EduResults.class);
cr.add(Restrictions.eq("subject", subject));
cr.add(Restrictions.eq("extype", extype));
cr.add(Restrictions.eq("acedemicyear", academicyear));
cr.add(Restrictions.eq("semester", semester));
cr.add(Restrictions.eq("level", level));
ScrollableResults items = cr.scroll();
int count = 0;
double[] scores = getSubjectScores(subject, extype, academicyear, semester, level);//this gets all the scores in a double array
int[] ranks = Rank.getRank(scores);//this gives me the ranks of the scores above
while (items.next()) {
EduResults res = (EduResults) items.get(0);
for (int i : ranks) {
res.setSubjectRank(i + 1);//this updates the database with the last item in the array
System.out.println(i+1);///this prints the ranks properly
session.saveOrUpdate(res);
}
if (++count % 100 == 0) {
session.flush();
session.clear();
}
}
tx.commit();
} catch (Exception asd) {
log.debug(asd.getMessage());
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
}
I have seen similar questions but this looks strange as the System out prints them correctly. I'm I missing something here?

res.setSubjectRank(i + 1); is not this line updating the subject rank repeatedly in the loop? What do you expect this to do? In the first iteration it will update it and will keep updating till the last iteration and the last iteration will have the last item from the ranks array.

I finally found a way around this. I am going to post the Answer for the sake of anyone that might be experiencing the same problem. Since the Students having the same score will have the same rank, you can iterate for each score and Update the Rank. Like this:
public static void updateSubjectRank(String subject, String extype, int academicyear, int semester, int level) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
double[] scores = getSubjectScores(subject, extype, academicyear, semester, level);
int[] ranks = Rank.getRank(scores);
for (double d : scores) {
Criteria cr = session.createCriteria(EduResults.class);
int rank = Rank.getRank(Rank.getRank(scores), Rank.getArrayIndex(scores, d)) + 1;
cr.add(Restrictions.eq("subject", subject));
cr.add(Restrictions.eq("extype", extype));
cr.add(Restrictions.eq("acedemicyear", academicyear));
cr.add(Restrictions.eq("semester", semester));
cr.add(Restrictions.eq("level", level));
cr.add(Restrictions.eq("scorePcnt", d));
ScrollableResults items = cr.scroll();
int count = 0;
while (items.next()) {
EduResults res = (EduResults) items.get(0);
res.setSubjectRank(rank);
System.out.println(rank);
session.saveOrUpdate(res);
if (++count % 100 == 0) {
session.flush();
session.clear();
}
}
}
tx.commit();
} catch (Exception asd) {
log.debug(asd.getMessage());
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
}

Related

How to display and add tasks to file according to priorities using Java

I need to display/list the contents of a txt file in the ascending order of priority. So, should I need to take a seperate input for priority of task or can I splice the input line?
private static void show() {
String[] items = getData("task.txt");
if (items.length == 0) {
System.out.println("There are no pending tasks!");
} else {
for (int i = items.length - 1; i >=0; i--) {
System.out.printf("[%d] %s\n", i + 1, items[i]);
}
}
My getData looks like this:
private static String[] getData(String file) {
ArrayList<String> dataList = new ArrayList<>();
Scanner s=null;
try {
s = new Scanner(new FileReader(file));
while (s.hasNextLine()){
dataList.add(s.nextLine());
}s.close();
} catch (Exception e) {
System.out.println("Problem to open \"task.txt\".");
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
}
}
}
String[] items = new String[dataList.size()];
for (int i = 0; i < items.length; i++) {
items[i] = dataList.get(i);
}
return items;
}
Input:
10 the thing i need to do
5 water the plants
11 clean house
Output: 5 water the plants
10 the thing i need to do
11 clean house
You can just sort the ArrayList datalist:
(I am assuming that the "priority item" format is already in it)
dataList.sort((o1, o2) -> {
Integer priority1 = Integer.parseInt(o1.split(" ")[0]);
Integer priority2 = Integer.parseInt(o2.split(" ")[0]);
return priority1.compareTo(priority2);
});
Put this right after the try-catch-finally-block.

Calculate column data

i'm trying to create a void method that will read csv file and count the reputaion number of state such that how many times TX,how many times Oh and how many times of Dc. the out should be-TX=4; Oh=2;DC=2. but my out put is "For input string: "F" "- and i really couldn't get where is the problem.can someone help me?
"Crimerate.csv"
State county Rate
Tx,DALLAs,39
TX,Aderson,10
Oh,Archer,20
DC,DC,50
Tx,Houston,31
TX,Claude,13
Oh,Bexar,10
DC,SE,40
public static void countnumber()
{
try{
List<String>number=Files.readAllLines(Paths.get("Crimerate.csv"));
double sum=0,num=0;
for (String line:number){
if(num==0){
++num;
continue;
}
line=line.replace("\"","");
String []result=line.split(",");
double close = Double.parseDouble(result[6]);
String numberAsString = Double.toString(close);
if(numberAsString.equals("Tx"))
{
sum++;
System.out.println("number of Tx =" + sum);
}
else if(numberAsString.equals("Oh"))
{
sum++;
System.out.println("number of Oh =" + sum);
}
else if(numberAsString.equals("Dc"))
{
sum++;
System.out.println("number of Dc =" + sum);
}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
public static void main (String args[])
{
countnumber();
}
While the previously suggested answers will address the specific question of why there was only a single response (a result of having only a single sum variable), they have two issues.
They are not accounting for the fact that in the example data, Texas is shown both as "Tx" and "TX". Thus, the current other answers will not give the correct result of 4 for Texas (they will only show 2).
The approaches assume that the full data set was shown. If other states are present, then the code would need to be continually expanded to support the new states.
This solution handles both situations.
public static void main(String[] args)
{
Map<String, Integer> countByState = new HashMap<>();
List<String> number;
try {
number = Files.readAllLines(Paths.get("f:/tmp/Crimerate.csv"));
int cntr = 0;
for (String line : number) {
// skip first line
if (cntr++ == 0) {
continue;
}
String []result=line.split(",");
// should add error checking
String state = result[0].toUpperCase();
Integer cnt = countByState.get(state);
if (cnt == null) {
cnt = new Integer(0);
}
countByState.put(state, ++cnt);
}
System.out.println(countByState);
}
catch (IOException e) {
e.printStackTrace();
}
}
Sample Results based upon the data presented in the question (there is only one DC in that data):
{TX=4, OH=2, DC=1}
int txCount = 0;
int ohCount = 0;
int dcCount = 0; //create this variables inside the class(instance variables)
if(numberAsString.equals("Tx"))
{
++txCount;
System.out.println("number of Tx =" + txCount);
}
else if(numberAsString.equals("Oh"))
{
++ohCount;
System.out.println("number of Oh =" + ohCount);
}
else if(numberAsString.equals("Dc"))
{
++dcCount;
System.out.println("number of Dc =" + dcCount);
} //its better if u use equalsIgnoreCase on if Statements
you were referring to same sum variable on each if loops, i have fixed that .
i assume that the code you have written on reading the file is correct.
You just need different sum variables for each sum. And print the results after the loop.
try{
List<String>number=Files.readAllLines(Paths.get("Crimerate.csv"));
double sumTx=0,sumOh=0,sumDc=0,num=0;
for (String line:number){
if(num==0){
++num;
continue;
}
line=line.replace("\"","");
String []result=line.split(",");
double close = Double.parseDouble(result[6]);
String numberAsString = Double.toString(close);
if(numberAsString.equals("Tx")) {
sumTx++;
} else if(numberAsString.equals("Oh")){
sumOh++;
} else if(numberAsString.equals("Dc")){
sumDc++;
}
}
System.out.println("number of Tx =" + sumTx);
System.out.println("number of Oh =" + sumOh);
System.out.println("number of Dc =" + sumDc);
}catch(Exception e){
System.out.println(e.getMessage());
}
}

java removing element from hashset breaks while loop and leaves nul error

i have a hashset of room objects that are made in another function based on user input and are added to the hashset. here, we iterate through the rooms in the hashset and then iterate through the users and increases the room count based on how many of them are in the room. this works perfectly except when a room needs to be deleted.log.error(ex.getMessage()); leaves a null error, and it doesnt continue to iterate through the rest of the elements and the stringbuilder is left empty. the next time sendroomlist fires though it adds the rooms and their count to the stringbuilder but i need it to do this all in one go any help at all to put me on the right track please
heres my hashset
private Set<Room> rooms = Collections.synchronizedSet(new HashSet<Room>());
heres where i'm having the problem if you need to see where i add the rooms to the rooms hashset lmk
private void sendRoomList()
{
StringBuilder sb = new StringBuilder();
String strRoom;
int roomCount = 0;
int spaghetticount = 0;
// Room objRoom;
try
{
synchronized (rooms)
{
// {
// Iterator<Room> iterRoom = rooms.iterator();
// while (iterRoom.hasNext())
// {
// Room s = (Room) iterRoom.next();
// if ( (s.getName().toString().equalsIgnoreCase(roomName)) )
// { return true;
// }
//Iterator<String> iterRoom = rooms.iterator();
Iterator<Room> iterRoom = rooms.iterator();
while (iterRoom.hasNext())
{
//Room s = (Room) iterRoom.next();
Room objRoom = (Room) iterRoom.next();
strRoom = (String) objRoom.getName();
synchronized (sessions)
{
roomCount = 0;
Iterator<IoSession> iterSessions = sessions.iterator();
while (iterSessions.hasNext())
{
IoSession s = (IoSession) iterSessions.next();
if (s.isConnected())
{
if (s.getAttribute("room").toString().equalsIgnoreCase(strRoom))
{
roomCount++;
}
}
}
}
if (roomCount <= 0 && strRoom != defaultRoom)
{
synchronized (rooms)
{
rooms.remove(objRoom);
}
}
else
{
sb.append(strRoom + "|" + roomCount + "~");
}
}
}
}
catch (Exception ex)
{
log.error(ex.getMessage());
}
broadcastRoomList(sb.toString());
}
Use iterRoom.remove() instead of rooms.remove(objRoom).

Exhausted Resultset when calling a method inside the while(rset.next)

I'm getting an Exhausted resultset form the following code.
I've tried a few different things now and can't find a solution,
if I don't call the songs method it works, but the songs method works when it's called, can't get my head around it, hoping I'm missing something simple.
public void refreshList() {
rset = po.getProduct();
if (plist.size() > 0) {
for (int i = plist.size() - 1; i >= 0; i--) {
plist.remove(i);
}
}
try {
while (rset.next()) {
songs(rset.getString(1));
CD c = new CD(alist);
Product p = new Product(rset.getString(1),
rset.getString(2),
rset.getString(3),
rset.getDouble(4),
rset.getDouble(5),
rset.getInt(6),
rset.getString(7),
rset.getString(8),
rset.getString(9),
rset.getDouble(10), c);
plist.add(p);
}
} catch (Exception ex) {
System.out.println(ex);
}
}
public void songs(String ID)
{
rset = po.getSongs();
alist = new ArrayList<Song>();
try {
while (rset.next()){
Song s = new Song(rset.getString(1),
rset.getString(2),
rset.getString(3));
slist.add(s);
}
}
catch (Exception ea) {
System.out.println(ea);
}
for(int i = 0; i < slist.size(); i++)
{
if(slist.get(i).getSong_id().equals(ID))
{
alist.add(slist.get(i));
}
}
}
Inside refreshList you have while (rset.next()) loop, on each iteration of it you have songs(rset.getString(1));, which itself has while(rset.next(). This leads to result set exhaustion, because when you return from songs() you try to take some more data from the current position of result set, while in songs() you got out of while (rset.next()) loop, i.e. retrieved all its rows. Consider refactoring your code to avoid nested loops based on result set.

How to read a List in batches

I have a function which reads a List of Notifications Object. Now I have to read the Notifications object in batches of 100(suppose) and update it.
public boolean addBSInfoToTemp(List<ParentNotification> pNotify)
throws DaoException, BatchUpdateException {
int cnt = 0;
final String query = "insert into Temp values ?,?,?,'Y','N',?,?,?,?";
while (!pNotify.isEmpty()) {
try {
pst = getConnection().prepareStatement(query);
for (ParentNotification pn : pNotify) {
cnt++;
pst.setInt(1, pn.getUserId());
pst.setString(2, pn.getEmail());
pst.setString(3, pn.getNotificationType());
Date createdDate = (Date) pn.getCreatedDate();
pst.setDate(4, createdDate);
pst.setString(5, pn.getCreatedBy());
Date icsesCreatedDate = (Date) pn.getIcsesCreatedDate();
pst.setDate(6, icsesCreatedDate);
pst.setString(7, pn.getMiscellaneous());
pst.addBatch();
if(cnt==batchCount){
break;
}
}
int[] batch = pst.executeBatch();
if (batch.length != 0) {
flag = true;
}
} catch (BatchUpdateException b) {
flag = false;
} catch (SQLException sqlx) {
flag = false;
} finally {
close(pst, null);
}
}
return flag;
}
What I am trying to do is read the List with batchCount = 100 then update and go back to 101 record and then update another 100 records untill the List is empty.
You have this:
while (!pNotify.isEmpty()) {
but I don't see that you ever remove objects from the list, so you have infinite loop. I would just make the outside loop to loop through all of the elements like this:
for (int i=0; i<=pNotify.size(); i++){
// and inside check if it is devisible by batch length
if(i % batchCount == 0){
break;
}
}

Categories