Sort JSONArray with single for loop - java

I have a JSONArray with 5 different JSONObject and each of the 5 JSONObject has an identifier string value. The five values are "aa","bb","erer","cc","gg". My requirement is to get the JSONObject with identifier "erer" to first place and the following JSONObjects can be in any order.
The json is:
{
"obj":[
{"identifier":"aa",},
{"identifier":"bb",},
{"identifier":"erer",},
{"identifier":"cc",},
{"identifier":"gg",}
]
}
The final result has to be "erer","aa","bb","cc","gg" and I need to do this in a single loop.
I'm able to do this in two loops.
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject j = jsonArray.getJSONObject(i);
if(j.getString("identifier").equals("erer")) {
sortedJson.put(joPayLoad);
}
}
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject j = jsonArray.getJSONObject(i);
if(!j.getString("identifier").equals("erer")) {
sortedJson.put(joPayLoad);
}
}
But the JsonArrray might also have 10,000 JSONObjects. And so, this 'two for-loops' will cause a performance lag. So, please help me to achieve my above said requirement in a single loop.
Thanks in advance!

Given JsonArray is a List (source) you can just try to swap the value with erer to be the new first element:
for (int i = 0; i < jsonArray.length(); i++) {
JsonValue j = jsonArray.get(i);
if(j.getString("identifier").equals("erer")) {
JsonValue tmp = jsonArray.get(0);
jsonArray.set(0, j);
jsonArray.set(i, tmp);
break;
}
}
Haven't tried it since I don't have EE installed, but maybe you can make it work with the methods provided.

You need two pointers, a read pointer and a write pointer. Both start at the last item. Read the element at the read pointer. If it's "erer," then just decrement the read pointer, otherwise, write the element to the write pointer and decrease both the read pointer and the write pointer. At some point the read pointer will decrease to zero. If the write pointer is >0 it means you found some "erer" elements that you did not write. Write them to the write pointer and decrement the write pointer until it too is zero.
String[] data = { "aa", "gg", "dd", "ee", "erer", "gg", "erer" };
int r = data.length - 1, w = data.length - 1;
while (r >= 0) {
if (!"erer".equals(data[r])) {
data[w] = data[r];
w--;
}
r--;
}
while (w >= 0) {
data[w] = "erer";
w--;
}
Okay, technically there's still two loops here, but it should be clear that we're iterating only once over the array. If you really gotta have one loop, this would work...
int r = data.length - 1, w = data.length - 1;
while (w >= 0) {
if (r >= 0) {
if (!"erer".equals(data[r])) {
data[w--] = data[r];
}
r--;
} else {
data[w--] = "erer";
}
}

Related

ArrayIndexOutOfBounds Exception thrown

public Pasient[] finnPasient(String dato)
{
int j = 0;
Pasient[] p = new Pasient[j];
for(int i = 0; i < pasienter.length; i++)
{
if(pasienter[i] != null && pasienter[i].getFødselsdato().equals(dato))
{
p[j] = pasienter[i];
j++;
}
}
if(j == 0)
return null;
else
return p;
}
that is my method. I think I know what's wrong, but I am not sure how to fix it. I think that the arraylength does not update while the loop is running. Pasienter.length is always 100 for my tests. Ask me if you need any more info to respond, thanks
int j = 0;
Pasient[] p = new Pasient[j];
j is 0, p has no elements at all, so the first element which is at index 0, is out of bounds, this probably happens at the line:
p[j] = pasienter[i];
↑
When you write j++, this doesn't enlarge the array that you've already created. Remember, array's size cannot be changed.
Since you don't know how long should the array be, I advise you to read about ArrayList and do something like:
ArrayList<Pasient> p = new ArrayList<>();
And then,
p.add(pasienter[i]);

How to remove object from array

Please bear within as it might be difficult to understand
I have an array of jbuttons 50 size big, for this example ill use 7 I have jbutton object within 1 2 3 4 6 7 but not 5. These are printed on the screen. I want to remove these jbuttons however all buttons up to 5 are removed while the last two are not.
for(int i = 1; i < 51; i++){
if(seat.buttonArray[i] == null){
remove(seat.buttonArray[i]);
seat.buttonArray[i] = null;}
}
There is no way to remove element from array, assuming you want latter indexes changed after remove. For this purpose, you should use List:
Iterator buttonIterator = seat.buttonList.iterator();
while (buttonIterator.hasNext()) {
Object button = buttonIterator.next(); //or more specific type, if your list was generified
if (button == null) { //or some other criteria, wrote this just as an example
buttonIterator.remove();
}
}
If using array is mandatory, you have two options:
Set seat.buttonArray[i] to null value, indicating it has been removed;
Recreate array each time you deleted something. See System.arraycopy javadoc for details, although I do not recommend this approach because of performance considerations.
You could store the values in a temp array and then copy what you want back into your original array. Somewhat similar to this:
int myArray[50];
int temp[50];
int good;
for (int i = 0; i < 50; i++) {
myArray[i] = i;
}
for (int i = 0; i < 50; i++) {
temp[i] = myArray[i];
}
good = 0;
for (int i = 0; i < 50; i++) {
if (i < 10) {
} else {
myArray[good] = temp[i];
good += 1;
}
}
Looks messier than I first thought... But it essentially does what you're wanting.

working around a null element in an array

In my program, i "deleted" an element by turning it into a null as you can't delete an element from an array so employee [i] = null. However, I was wondering, if I wanted to work with the array that had a null element, like add all the numbers in the array, how do I do this without any problems?
[UPDATE:]
My array contains the first names, last names and ages of 4 employees, I've "deleted" one of the employees details by making it null. As per all of the suggestions I got, I tried to add all the ages using:
int sum = 0;
for (int i = 0; i < employee.length; i++) {
if (employee[i] != null)
sum += employee[i].getAge();
}
but all I get is that sum = 1.
If the only operation you're going to perform on your array is the sum of all elements, it would make more sense to set the deleted elements to 0 instead of null. This way, you will not need the extra null check on every iteration.
You have to check if that element is null or not. If it is, add to the sum. If not, do nothing.
int sum = 0;
for (int i = 0; i < employee.length; i++) {
if (employee[i] != null)
sum += employee[i];
}
public int addAllNums(int[] nums)
{
int sum=0;
for(int i=0;i<nums.length;i++)
{
if(nums[i]!=null)sum+=nums[i];
}
}
You just have to iterate over your array and check if the current employee is not null :
int sum = 0;
for(int i = 0; i < employee.length; i++) {
if(employee[i] != null) {
sum += employe[i].getNumber();
}
}

Rearranging array when it has a null position

I have this code that searches one object in an array and removes it. I'm having a problem with its position, since some other methods work with this array (and it gives me a NullPointerException every time). My method looks like this:
public void deleteHotel(String hotelName) {
for (int i = 0; i < this.hoteis.length; i++) {
if (this.hoteis[i].getName().equalsIgnoreCase(nomeHotel)) { //searches the array, looking for the object that has the inputted name
this.hoteis[i] = null; //makes that object null
if (this.hoteis.length > 1 && this.hoteis[this.hoteis.length - 1] != null) { //for arrays with lenghts bigger than 1 (since there's no problem with an array with one position)
for (int x = i; x < this.hoteis.length; x++) {
this.hoteis[x] = this.hoteis[x + 1]; //makes that null position point to the next position that has an object, and then that position points to the object in the next position and so on
}
this.hoteis[this.hoteis.length - 1] = null; //since the last to positions will be the same, make that last one null
Hotel[] hoteisTemp = new Hotel[this.hoteis.length - 1];
for(int x = 0; x < this.hoteis.length - 1; x++){ //create a new array with one less position, and then copy the objects on the old array into the new array, then point the old array to the new array
hoteisTemp[x] = this.hoteis[x];
}
this.hoteis = hoteisTemp;
}
i = this.hoteis.length;
}
}
}
When I use other methods (for example, one that returns the implemented toString()s of each object) it gives me a NullPointerException. Can you guys identify the error in the code? Much appreciated...
I have tested your function and I see what you mean by it getting a nullpointerexception, this is due to the array not resizing the list - which is due to your conditional:
if (this.hoteis.length > 1 && this.hoteis[this.hoteis.length - 1] != null).
Simply removing this solved the issue, here is the working function:
public static void deleteHotel(String hotelName) {
for (int i = 0; i < hotels.length; i++) {
if (hotels[i].getName().equalsIgnoreCase(hotelName)) { //searches the array, looking for the object that has the inputted name
hotels[i] = null; //makes that object null
for (int x = i; x < hotels.length -1; x++)
hotels[x] = hotels[x + 1]; //makes that null position point to the next position that has an object, and then that position points to the object in the next position and so on
Hotel[] hoteisTemp = new Hotel[hotels.length - 1];
for(int x = 0; x < hotels.length - 1; x++) //create a new array with one less position, and then copy the objects on the old array into the new array, then point the old array to the new array
hoteisTemp[x] = hotels[x];
hotels = hoteisTemp;
break;
}
}
}
Though please consider using a list of some sort when needing to use a list with a changing size.
The fundamental problem is that you're not allowing for where you removed the entry from the array.
Instead of
for(int x = 0; x < this.hoteis.length - 1; x++){
you want
for(int x = 0; x < this.hoteisTemp.length; x++){
(although that's a style choice)
and more significantly, instead of
hoteisTemp[x] = this.hoteis[x];
you want
int y = x < i ? x : x + 1;
hoteisTemp[x] = this.hoteis[y];
You also want to get rid of everywhere you're setting array elements to null, because if your copying logic works correctly, that's unnecessary.
For this use case, I would consider using one of the List implementations.
Consider rewriting your code
List result = new ArrayList();
for (int i = 0; i < this.hoteis.length; i++) {
if (!this.hoteis[i].getName().equalsIgnoreCase(nomeHotel)) {
result.add(this.hoteis[i]);
}
}
return result.toArray();
The point where you're shifting the array elements towards the left
for (int x = i; x < this.hoteis.length; x++) {
this.hoteis[x] = this.hoteis[x + 1];
}
The loop condition should be x < this.hoteis.length - 1 because at the last iteration when x = this.hoteis.length - 1 the index value this.hoteis[x + 1] would throw a NullPointerException.
Try using ArrayList it will simplify your code complexity.Here is the link to documentation.
http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html

Count The Amount Of Data In An Array Including SOME Null

I'm coding in java and I need to create a function that returns the number of data objects that are currently in an ArrayList. At the moment I have this:
int count = 0;
for (int i = 0; i < data.length; i++)
{
if (data[i] != null)
{
count ++;
}
}
return count;
But the problem is that an array list that includes null data is acceptable, and I have to count their null data towards this counter. How do I include the null data that's in the middle of this array, and not the null data that's not supposed to be counted for?
For example, I have some tester code that adds (8),null,null,(23),(25) to the array, and this function should return 5 when the initial array size is 10.
I'm going to assume you're using a regular array (your question is somewhat ambiguous about this). Traverse through the array backwards until you find a non-null element:
public static int count(Object[] a) {
int i = a.length - 1;
for (; i >= 0 ; i--)
if (a[i] != null)
break;
return i + 1;
}
You could also have
public static <T> int count(T[] a) {
int i = a.length - 1;
for (; i >= 0 ; i--)
if (a[i] != null)
break;
return i + 1;
}
Let's test it out, using an example analogous to the one you provided:
Object[] a = new Object[10];
a[0] = new Object();
a[3] = new Object();
a[4] = new Object();
System.out.println(count(a));
Output:
5
You will need two separate counters. The first one will count normally. The second one starts counting when you find null data. Then when you find a non-null data, just add the second counter to the first one and continue counting with the first counter until you find a null again.
int count = 0;
for (int i = data.length - 1; i >= 0; i--)
if (data[i] != null || count > 0)
count += 1;
return count;
At least that's how I understood your requirements - count nulls, except for trailing nulls.
But maybe that's not actually what you meant?
Edit
Unless you're actually using ArrayList (as Jon was asking), where .size() is different from capacity and will count all added elements (including nulls). You can't actually even get the capacity from an ArrayList.

Categories