This question already has answers here:
NullPointerException when Creating an Array of objects [duplicate]
(9 answers)
Closed 6 years ago.
Why won't it compile? I am trying to sort a list of school courses by one int property: courseLevel, in ascending order.
I have a class named UCFCourse with several objects courses[]. I am assigning the property values to each object while incrementing x.Here is my code in my main:
courses[x] = new UCFCourse(courseCode, courseLevel, courseHours, replaceString, eitherCourse);
This is where I added my courses[].If I print out ListOne I get a massive list containing all my courses.
List<UCFCourse> ListOne = new ArrayList<UCFCourse>();
for (int i = 0; i < courses.length; i++) {
ListOne.add(courses[i]);
}
//I added all my courses[] to a List
List<UCFCourse> ListOne = new ArrayList<UCFCourse>();
Collections.sort(ListOne, new CourseComparator());
Comparator class:
import java.util.Comparator;
public class CourseComparator implements Comparator<UCFCourse> {
public int compare(UCFCourse Course1, UCFCourse Course2) {
return Course1.getCourseLevel() - Course2.getCourseLevel();
}
}
When I initially created my object it looked like this:
UCFCourse[] courses = new UCFCourse[75];
Not sure if this bit is relevant since I added all of them into an Array list already but I want to be thorough.
Errors:
Exception in thread "main" java.lang.NullPointerException
List<UCFCourse> ListOne = new ArrayList<UCFCourse>();
<add your items to list here>
Collections.sort(ListOne, new CourseComparator());
As this code stands, you are sending a blank list to the Comparator. If you are sure you have items in the list, check that the Course1 and Course2 items being passed actually have a value. You can test quickly by taking the 'getCourseLevel()' off of them and returning the values back to the calling method.
You're just creating a new object on your ListOne variable and that variable is still empty that's why you're getting a NullPointerException.
And try to use a camel case so that you can identify your code properly.
From the code snippet you've provided I can tell you the following:
UCFCourse[] courses = new UCFCourse[75];
only creates an array full with null objects. Lopping through this array and adding each object into your ArrayList will not instantiate them.
List<UCFCourse> ListOne = new ArrayList<UCFCourse>();
for (int i = 0; i < courses.length; i++) {
ListOne.add(courses[i]);
}
The consequence is that the Comparator#compare(UCFCourse c1, UCFCourse c2) method parameters, c1 and c2, will be null, which leads to the NullPointerException.
What you need to do before adding them to the ArrayList is to create your UCFCourse objects, e.g.:
for (int i = 0; i < courses.length; i++) {
courses[i] = new UCFCourse(...);
}
Related
I'm having trouble wording the question, so hopefully the example helps. I am trying to figure out why within the List collection in Java, where the method get() is overloaded by get(O Object) and get(int index), that one of these snippets work and the other doesn't.
edit: some context for the code, I'm trying to come up with an alternative way to check hits/miss on a LRU cache. ListB is a list containing data values, and listA is the cache of arbitrary length. I'm trying to figure out how come the first snippet works when coming across an int from listB that is contained within the cache (listA) which in turn removes, and then adds the element to bring it to the front of the list.
If I declare an Integer object and pass it through the get method it does not work. But if I declare a new Integer object within the get method, it does. For example:
This works This snippet will remove the first occurrence of Integer i it comes accorss
List<Integer> ListA= new ArrayList<Integer>();
for(int i: ListB){
if(ListA.contains(i)){
ListA.remove(new Integer(i));
}}
This does not work even though an Integer object is being passed through, this does not work
List<Integer> ListA= new ArrayList<Integer>();
for(int i = 0; i < ListB.size(); i++){
Integer obj = new Integer(ListB.get(i));
if(ListA.contains(obj)){ //or list.contains(i), neither work
ListA.remove(obj); //Does not work
}}
You shoudn't be creating a new Integer instance when retreive it from the list:
List<Integer> ListA= new ArrayList<Integer>();
for(int i = 0; i < ListB.size(); i++){
Integer obj = ListB.get(i); // Get the object from List B, do not create a new object from a reference in List B
if(ListA.contains(obj)) {
ListA.remove(obj);
}}
This question already has answers here:
Why does one arraylist change when a copy of it is modified
(6 answers)
Closed 3 years ago.
I'm setting a temporary ArrayList equal to a pre-established ArrayList. Changes to the temporary ArrayList seem to also transfer over to the pre-established one. Why does this occur and how can I keep the pre-established ArrayList unchanged?
I know that this phenomenon does not occur in situations that involve ints.
ArrayList<Integer> array = new ArrayList<>();
for (int i = 0; i < 3; i++){
array.add(i);
}
ArrayList<Integer> tempArr = array;
tempArr.remove(0);
I expect array to be [0,1,2], but I get [1,2]. I would like the output to be array = [0,1,2] and tempArr = [1,2].
You just copied the reference of the list to the new variable. That means you have 2 references array and tempArr that are pointing to the same object. You could create a new ArrayList from the old one:
ArrayList<Integer> tempArr = new ArrayList<>(array);
Variables array and tempArr booth point to same instance of ArrayList<Integer> object, hence modifying one will make changes to other.
What you need is to create new instance and then transfer all elements to it:
ArrayList<Integer> array = new ArrayList<>();
for (int i = 0; i < 3; i++){
array.add(i);
}
ArrayList<Integer> tempArr = new Arraylist<>();
tempArr.addAll(array);
tempArr.remove(0);
This code can also be simplified since Arraylist<> is offering you constructor that will add elements from another collection:
ArrayList<Integer> tempArr = new Arraylist<>(array);
tempArr.remove(0);
This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 5 years ago.
I'm currently learning Java, I'm just curious about the code that I wrote a minute ago, it works, but I want to know if there is a better alternative (that isn't "use the clear method").
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("A");
al.add("B");
al.add(5);
System.out.println(al.size());
Iterator i = al.iterator();
while (i.hasNext()) {
Object next = i.next();
System.out.println("Removing " + next.toString() + "...");
al.remove(next);
i = al.iterator();
}
System.out.println(al.size());
}
Especially, because I don't really know what can be in a specific position in an ArrayList (they contains objects of every kind), I used a generic "Object next" variable. I don't know if it is acceptable.
I know that there are methods to clear an ArrayList, I just wanted to try to understand how ArrayLists works, thank you.
You don't need to fetch each element before you remove it. You can simply remove elements by it's index:
ArrayList al = new ArrayList();
// ... add elements skipped...
// now clear it
int size = al.size();
for (int index = size-1; index >= 0; index--) {
al.remove(index);
}
but I want to know if there is a better alternative
Yes.
because I don't really know what can be in a specific position in an
ArrayList (they contains objects of every kind.
Make List<T> generic : it will allow you to add only some specific type of Object.
Replaced ArrayList al = new ArrayList(); by
List<String> al = new ArrayList<>();
This question already has answers here:
How do I remove repeated elements from ArrayList?
(40 answers)
Closed 7 years ago.
public static ArrayList<Character> removeDuplicates (ArrayList<Character> data) {
ArrayList<Character> newList = new ArrayList<Character>();
for (int i = 0; i < data.size() - 1; i++) {
if (!newList.contains(data.get(i)))
newList.add(0,(data.get(i)));
}
return newList;
}
Here is my code so far. I'm not understanding how this is not working
You can use a Set. A Set is a Collection that doesn't let duplicates of Objects.
I'm not sure what Object type your List is of, but let's say your were using String:
//replace all instances of 'String' with whatever Object type you are using
Set<String> mySet = new HashSet<>();
for(String s : data){
mySet.add(s);
}
Then if you want to send the data to a List, do:
ArrayList newList = new ArrayList(mySet);
There are 2 problems with your implementation.
You're not counting all of the items in the array. You should do either i <= data.size() - 1 or i < data.size(). Right now you're missing the last item.
You're not adding items to the end of the list. Instead, you're repeatedly overwriting the zeroth (first) value. EDIT: Sorry, that was incorrect. You're inserting at the beginning of the list, which will work but is inefficient for the most commonly used lists (e.g. ArrayList).
Here is the fixed version. The problem areas are commented out with /* */.
List<Object> newList = new ArrayList<Object>();
for (int i = 0; i < data.size() /* - 1 */ ; i++) {
if (!newList.contains(data.get(i)))
newList.add( /* 0, */ (data.get(i)));
}
return newList;
EDIT: Using contains(...) on a list is slow. You can optimize and simplify this by using a Set. A set is a collection which has unique values. Adding the same value twice has no effect. We can take it a step further and use a LinkedHashSet as the implementation class, which will maintain the same ordering as was in the original list.
return new ArrayList<Object>(new LinkedHashSet<Object>(data));
I have a nested ArrayList of the form
ArrayList<ArrayList<PointF>> nestedArraylist
I want to create a "copy" nestedArraylistCopy of nestedArraylist in the following sense:
The elements of nestedArraylistCopyshould be independent copies of the elements in nestedArraylist, i.e. should be ArrayLists holding the references to the same PointF objects in the original nestedArraylist.
Can I somehow use Collections.copy(dest, src) to do what I want? The documentation is not exactly detailed unfortunately...
Does the following code do what I want?
for(int i = 0; i < nestedArraylist.size(); i++)
nestedArraylistCopy.add(new ArrayList<PointF>(nestedArraylist.get(i)));
Is there a more efficient and or elegant solution?
Q1: after you Collections.copy, your new List object will contain the same elements as src (assuming the size is the same) which means, it holds same ArrayList<PointF> objects, hence the PointF objects are the same too. If you cannot get the info you want from the api java doc, read the source codes.
Q2: What you did is different from Collections.copy, since your copied arrayList has new Arraylist<PointF> as elements, but they contain the same elements (PointF) as the source list.
Q3: I don't know. because I don't know what do you want to have eventually. All new objects? Only ArrayList should be new objects, or all references?
According to my knowledge your solutions will update only references, as does Collection.copy(). You can use the below method, which I prefer:
List<ArrayList<PointF>> newList = new ArrayList<ArrayList<PointF>>(oldList);
A change of the old list would not affected to new list.
I tested your second option and it also has the property that changes to the old one will not affect the new List.
Note - These will also update only the references. If you change elements in your new list it will update old list too. I think Your second array will create brand new objects, but I am not 100% sure about that. I am adding my testing code below for you reference.
package test;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Lasitha Benaragama on 4/28/14.
*/
public class StckTest {
public static void main(String[] args) {
List<String> oldList = new ArrayList<String>();
oldList.add("AAAAA");
oldList.add("BBBBB");
oldList.add("CCCCC");
oldList.add("DDDDDD");
oldList.add("EEEEEE");
StckTest test = new StckTest();
List<String> newListCopy = new ArrayList<String>(oldList);
List<String> newListClone = new ArrayList<String>();
for(int i = 0; i < oldList.size(); i++)
newListClone.add(oldList.get(i));
test.printArray(newListCopy);
test.changeList(oldList);
test.printArray(oldList);
test.printArray(newListCopy);
test.printArray(newListClone);
}
public void changeList(List<String> oldList) {
oldList.remove(2);
oldList.add("FFFFF");
}
public void printArray(List<String> oldList){
for(int i = 0; i < oldList.size(); i++){
System.out.print(oldList.get(i)+",");
}
System.out.println();
}
}
You can use the clone() method to make a shallow copy of your object.
ArrayList<ArrayList<String>> nestedArraylist=new ArrayList<ArrayList<String>>();
ArrayList<String> x=new ArrayList<String>();
x.add("Deepak");
nestedArraylist.add(x);
System.out.println(nestedArraylist);
ArrayList<ArrayList<String>> nestedArraylistcopy=(ArrayList<ArrayList<String>>)nestedArraylist.clone();
System.out.println(nestedArraylistcopy);