How to avoid the null values in String array in java..? - java

String[] m_cPackageName;
int m_size;
int j=0;
List<ApplicationInfo> installedList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
m_size = installedList.size();
m_cPackageName=new String[m_size];
for (PackageInfo pi : pkginfoList) {
try {
m_appinfo = packageManager.getApplicationInfo(pi.packageName, 0);
if ((m_appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
// equal to zoo means system apps, not equal is third party installed apps
m_cPackageName[j]=pi.packageName;
j++;
}
} catch (NameNotFoundException e) {
Log.d(getClass().getSimpleName(), "Name not found", e);
}
Here I'm getting total size of installedList is 56..After filling the value in array it display in null values. how can i eliminate the null values.. Any one Help for me..
OUTPUT :
m_cPackageName=String[56];
m_cPackageName[0]="Myvalue"
m_cPackageName[1]="null"
m_cPackageName[2]="null"
.
.
.
m_cPackageName[55]="null"

Less than m_size elements are being added to the array (of size m_size), which results in unassigned null elements at the end.
This is because j is only increased sometimes - inside a conditional ((m_appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0), and only when an exception is not thrown and caught.
A simple solution is to use an ArrayList, then only add the "approved" elements. Because a List/ArrayList grows on demand, there are no trailing null (unassigned) elements as might be found in a fixed-size array.
// List, not array
List<String> m_cPackageName = new ArrayList<String>();
// ..
if ((m_appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
// Only added to list sometimes, but m_cPackageName.size() is
// always the count of elements that HAVE been added.
m_cPackageName.add(pi.packageName);
}
// Then, if you really need an array, which will now be the proper size
// and not contain null elements because the size is computed based on the
// accepted elements in m_cPackageName which is m_cPackageName.size() ..
String[] arrayOfPackageNames = m_cPackageName.toArray(new String[0]);

add null check before inserting element to array.
if ((m_appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
if(pi.packageName!=null){
m_cPackageName[j]=pi.packageName;
j++;
}
}

if (((m_appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)&& (pi.packageName != null &&!pi.packageName.equals("")) {
// equal to zoo means system apps, not equal is third party installed apps
m_cPackageName[j]=pi.packageName;
j++;
}

You are allocating the array based on the size of installedList, but you are iterating over pkginfoList. A better way to do this is to create a List<String> packageNames = new ArrayList<String>();, and then add to that list in your loop.
That way, you don't have worry about counting or size.

if ((m_appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
// equal to zoo means system apps, not equal is third party installed apps
if(pi.packageName!=null){
m_cPackageName[j]=pi.packageName;
j++;
}
}

If you don't need to disambiguate empty and null strings, consider storing nulls as empty; something like this:
m_cPackageName[j]=pi.packageName == null ? "" : pi.packageName;
This might reduce the risk of things blowing up as NullPointerException-s further down.

Related

ArrayList to Stream in Java by grouping

I would like to get the highest score group by Id .If two highest score's are same then i would like get the highest score based on lowest Optional ID.I would like to get it in Java Stream.So far this code works.Is there any efficient way to rewrite this code in java stream
Example :
records=record.Person(batchNumber);
List<Person> highestRecords = new ArrayList<>();for(
Person s:records)
{
if(!highestRecords.isEmpty()) {
boolean contains = false;
for(Person ns: new ArrayList<>(highestRecords)) {
if(s.Id().compareTo(ns.Id()) == 0) {
contains = true;
if(s.getScore.compareTo(ns.getScore()) > 0
&& s.optionalId().compareTo(ns.optionalId()) < 0) {
highestRecords.remove(ns);
highestRecords.add(s)
}
}
}
if(contains == false) {
highestRecords.add(s);
}
}else {
highestRecords.add(s);
}
}
}
Don't convert this to a stream.
There is no one pure operation happening here. There are several.
Of note is the initial operation:
if(getNewPendingMatches.size() > 0)
That's always going to be false on the first iteration and you're always going to add one element in.
On subsequent iterations, life gets weird because now you're trying to remove elements while iterating over them. A stream cannot delete values from itself while iterating over itself; it only ever processes in one direction.
As written this code should not be converted to a stream. You won't gain any benefits in doing so, and you're going to actively harm readability if you do.

IndexOutOfBoundsException for for-loop in Kotlin

I have two lists in Kotlin, of the same size, foodObjects: MutableList<ParseObject>? and checked: MutableList<Boolean>?. I need to do a for loop and get the objectId from foodObjects every time that an element of checked is true. So it is this in Java:
for (int i = 0; i < foodObjects.size(); i++) {
// here
}
But in Kotlin, I don't know why, there are some problems. In fact, if I do this:
for (i in 0..foodObjects!!.size) {
if (checked?.get(i) == true) {
objectsId?.add(foodObjects.get(i).objectId)
}
}
I've got IndexOutOfBoundsException. I don't know why, it continues the loop also at foodObjects.size. I could do it also with filter and map:
(0..foodObjects!!.size)
.filter { checked?.get(it) == true }
.forEach { objectsId?.add(foodObjects.get(it).objectId) }
but I'm getting the same error. I use this to stop the error and get it to work:
for (i in 0..foodObjects!!.size) {
if (i < foodObjects.size) {
if (checked?.get(i) == true) {
objectsId?.add(foodObjects.get(i).objectId)
}
}
}
Everyone could tell me why in Kotlin I need to do it, when in Java it works good?
Ranges in Kotlin are inclusive, therefore 0..foodObjects!!.size starts at 0 and ends at foodObjects.size, including both ends. This causes the exception when your loop attempts to index the list with its own size, which is one more than the largest valid index.
To create a range that doesn't include the upper bound (like your Java loop), you can use until:
for(i in 0 until foodObjects!!.size) {
// ...
}
You could also clean your code up a bit if you did null checks on the collections you're using up front:
if (foodObjects != null && checked != null && objectsId != null) {
for (i in 0 until foodObjects.size) {
if (checked.get(i) == true) {
objectsId.add(foodObjects.get(i).objectId)
}
}
}
else {
// handle the case when one of the lists is null
}
And to get rid of having to handle indexes altogether, you can use the indices property of a list (plus I use the indexing operator here instead of get calls):
for (i in foodObjects.indices) {
if (checked[i]) {
objectsId.add(foodObjects[i].objectId)
}
}
You could also use forEachIndexed:
foodObjects.forEachIndexed { i, foodObject ->
if (checked[i]) {
objectsId.add(foodObject.objectId)
}
}
Take a look at this example from the Kotlin documentation for ranges:
if (i in 1..10) { // equivalent of 1 <= i && i <= 10
println(i)
}
As you can see
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
will be printed. So, the 10 is included.
The highest index of your collection foodObjects is (foodObjects.size() - 1) because it starts with 0.
So, to fix your problem, just do this:
for(i in 0..(foodObjects.size - 1)) {
// ...
}
A better way to write this would be:
for((i, element) in foodObjects.withIndex()){
// do something with element
println("The index is $i")
}
This way you have the element and the index at once and don't need to worry about ranges.
*I removed the null checks for simplicity.
Here are various ways to ensure the index is valid:
if (index in myList.indices) {
// index is valid
}
// The rangeUntil operator (..<) is still exprimental in Kotlin 1.7.20
if (index in 0..<myList.size) {
// index is valid
}
if (index in 0 until myList.size) {
// index is valid
}
if (index in 0..myList.lastIndex) {
// index is valid
}
if (index >= 0 && index <= myList.lastIndex) {
// index is valid
}
// Note: elements of the list should be non-null
if (myList.getOrNull(index) != null) {
// index is valid
}
// Note: elements of the list should be non-null
myList.getOrNull(index)?.let { element ->
// index is valid; use the element
}

first object of arraylist becomes null, cant seem to figure out why

So here is the issue. my concatinate function for intervals seems to be turning the first value passed into it to null, and i cant for the love of god figure out why.
public static ArrayList<Intervals> ConcatinateIntervals(ArrayList<Intervals> intervals) {
ArrayList<Intervals> concatinatedIntervals = new ArrayList<>();
for (int i=0; i<intervals.size(); i++){
for(int j=0; j<intervals.size(); j++){
if(i==j){
continue;
}
if(intervals.get(i).getMax() < intervals.get(j).getMin() || intervals.get(i).getMin()>intervals.get(j).getMax()){
Intervals interval = intervals.get(i).Clone();
concatinatedIntervals.add(interval);
continue;
}
// 1
if(intervals.get(i).getMin() < intervals.get(j).getMin() && intervals.get(i).getMax()<intervals.get(j).getMax()){
Intervals interval = new Intervals(intervals.get(i).getMin(),intervals.get(j).getMax());
concatinatedIntervals.add(interval);
break;
}//2
if(intervals.get(i).getMin() < intervals.get(j).getMin() && intervals.get(i).getMax()>intervals.get(j).getMax()){
Intervals interval = intervals.get(i).Clone();
concatinatedIntervals.add(interval);
break;
}//3
if(intervals.get(i).getMin() < intervals.get(j).getMax() && intervals.get(i).getMax()>intervals.get(j).getMax()){
Intervals interval = new Intervals(intervals.get(j).getMin(),intervals.get(i).getMax());
concatinatedIntervals.add(interval);
break;
}//4
if(intervals.get(i).getMin() > intervals.get(j).getMin() && intervals.get(i).getMax()<intervals.get(j).getMax()){
Intervals interval = new Intervals(intervals.get(j).getMin(),intervals.get(j).getMax());
concatinatedIntervals.add(interval);
break;
}
}
}
//removes all duplicates
Object[] st = concatinatedIntervals.toArray();
for (Object s : st) {
if (concatinatedIntervals.indexOf(s) != concatinatedIntervals.lastIndexOf(s)) {
concatinatedIntervals.remove(concatinatedIntervals.lastIndexOf(s));
}
}
return concatinatedIntervals;
}
It should be returning a 3 intervals of 10, 100 200,300 and 400,500. but I seem to be getting null. Cant figure out where I'm going wrong. please help.
The idea is that for any input of intervals its going to return a list of intervals either 10-500 og 10-100, 200-300, 400-500 and if any are duplicates its supposed to strip that away and concatinate so they become one larger.
I assume that you mean the ArrayList returned is not null but contains null elements (Intervals), since the reference to concatinatedIntervals is only ever set equal to a constructor call and thus cannot be null. You implemented your own cloning method apparently, as you write Clone() instead of clone(). The only places where Intervals are added to the list add either references that were assigned the result of a constructor call in the previous line (and thus cannot be null) or add the result of a call to Clone(). Thus the Clone() method is the only obvious suspect.
Have you tried stepping through execution of your code line-by-line with a debugger, checking the values of all the Intervals added?

Skip list searching null pointer exception

I keep seeing null pointer exceptions in my search method for the skip list I'm implementing.
public V find(K key, SkiplistMapNode<K,V> header, int level){
SkiplistMapNode<K,V> N = header;
for (int i = level-1; i >= 0; i--){
if ((N != null) && (N.getNext()[i] != null)){
while (N.getNext()[i].getKey().compareTo(key) < 0){
N = N.getNext()[i];
}
}
}
N = N.getNext()[0];
if ((N != null) && (N.getKey().compareTo(key) == 0)) return N.getValue();
else return null;
}
The line with the exception is:
while (N.getNext()[i].getKey().compareTo(key) < 0)
I pretty much copied this from this page though, so I'm not sure what would be wrong with it.
Supposing that N.getNext() advances to the next node, you need to memorize its value without advancing if you access the value more than once.
Same with iterator:
while (iterator.hasNext()) {
if (iterator.next()!=null) {
iterator.next().toString() // advances to the next item, which may be null
}
}
Fixed:
while (iterator.hasNext()) {
Object next=iterator.next(); // advance once
if (next!=null) { // check value
next.toString() // use same value, without advancing
}
}
It's hard to tell from your code where you really want to advance to the next element, and where you need the elements values again. Store the next value in a variable, and check and use this value afterwards, same as in the Iterator example above.
If you access an objects method, you should really make sure that the object isn't null. In your case, in...
while (N.getNext()[i].getKey().compareTo(key) < 0)
These...
N.getNext() //the only really important one you seem not to be checking
N.getNext()[i]
could be null and should be checked and possibly even (though less likely and debatably)
N
N.getNext()[i].getKey()
key

how to see if a arraylist is filled or not

Hello I am creating a application that uses arraylists ( practice purposes not real app )
I have created a method that gives me the answer of a math but only if the arraylist contains no object. for some reason I always see the else in my if/else construction.
Here is how I check if the array list contains objects
public void sluitRegistratie() {
aantalBezoekers = bezoeker.size();
if(!(aantalBezoekers >= 0)) {
String str = "Gemiddelde tijd bezoekers: " + (gesommeerdeTijd / aantalBezoekers);
JOptionPane.showMessageDialog(null, str);
}
else {
JOptionPane.showMessageDialog(null, "Bezoekers zijn nog niet weg");
}
}
ArrayList has an isEmpty() method that will return true if the arraylist is empty, false otherwise. So it looks like you want if(bezoeker.isEmpty())...
The size of an ArrayList can never be negative, so your check for !size()>=0 will never be true. Just check if size()==0.
if(!(aantalBezoekers >= 0))
Is the same as:
if(aantalBezoekers < 0)
In other words, when the length is less than zero, but this cannot happen.
if(!(aantalBezoekers >= 0)) {
Basically means that only execute if when aantalBezoekers is NOT greater than zero.
If you want to check if your list is of size zero use something like below:
if(bezoeker.size()>0){
System.out.pritnln("bezoeker is greater than zero " + bezoeker..size());
}
else {
System.out.pritnln("Mahn, my bezoeker is Empty " + bezoeker..size());
}
you could also simply use ArrayList.isEmpty() method to check if an arraylist is empty.
if(bezoeker.isEmpty()) {
An ArrayList can hold 0 elements at minimum, so !(aantalBezoekers >= 0) will always be false, and you'll always be in the else part.
thats because
!(aantalBezoekers >= 0)
means
not greater than or equal to zero
which is equivalent to
less than zero
which can never happen.

Categories

Resources