Java ArrayList.removeAll(), but for indices

Is there a way to do something like this:

ArrayList<String>.removeAll(ArrayList<Integer>)

With the ArrayList<Integer> being the indices that I want deleted. I know that I could iterate through the indices list and use remove(index), but I was wondering if there is a one-command way of doing so.

I know how to put this iteration into one line, my question is, if there is a way implemented by oracle.

Solution:

You can use a Stream to iterate through the indices to remove. However, take care to remove the highest index first, to avoid shifting other elements to remove out of position.

public void removeIndices(List<String> strings, List<Integer> indices)
{
     indices.stream()
         .sorted(Comparator.reverseOrder())
         .forEach(strings::remove);
}

For removing from a list of Strings this will work, calling the proper remove(int) method. If you were to try this on a List<Integer>, then you will have to avoid calling remove(E) by calling .mapToInt(Integer::intValue) before calling forEach.

Java ArrayList, how to ignore a value from the object when using contains()

I have a class like that:

public class Student implements Serializable{
  private String name;
  private int age;
  private Image img;
}

I store a few students in an ArrayList and write them to a file. When I restart the application I load them from that file again. However, the Image img variable is constantly changing. That means when I use arrayList.contains(studentA) it’s not the same object anymore, so arrayList.remove(studentA) won’t work.

Is there an easy way to either: Only check for the name of the student or ignore the Image field when using contains()?

Solution:

Yes.

Just implement the equals/hashcode without the Image attribute.

public class Student implements Serializable {

    private String name;
    private int age;
    private Image img;

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }

}

oldData in ArrayList implementation

I’m reading ArrayList implementation and can’t understand one thing in this method:

public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
            newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

I don’t understand what this oldData array is used for:

Object oldData[] = elementData;

To me it seems like there is absolutely no sense in this local variable inside ensureCapacity method.

Solution:

Yes, The line is completely redundant there and left it without refactored.

Looks like that method got addressed with Java 7 version and the whole method got refactored the logic of increasing the backed array.

Authers created another method called grow() and moved the logic there from version 7.

public void  ensureCapacity(int minCapacity) {
191         int minExpand = (elementData != EMPTY_ELEMENTDATA)
192             // any size if real element table
193             ? 0
194             // larger than default for empty table. It's already supposed to be
195             // at default size.
196             : DEFAULT_CAPACITY;
197 
198         if (minCapacity > minExpand) {
199             ensureExplicitCapacity(minCapacity);
200         }
201     }
202 
203     private void  ensureCapacityInternal(int minCapacity) {
204         if (elementData == EMPTY_ELEMENTDATA) {
205             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
206         }
207 
208         ensureExplicitCapacity(minCapacity);
209     }
210 
211     private void  ensureExplicitCapacity(int minCapacity) {
212         modCount++;
213 
214         // overflow-conscious code
215         if (minCapacity - elementData.length > 0)
216             grow(minCapacity);
217     }

    private void grow(int minCapacity) {
    234         // overflow-conscious code
    235         int oldCapacity = elementData.length;
    236         int newCapacity = oldCapacity + (oldCapacity >> 1);
    237         if (newCapacity - minCapacity < 0)
    238             newCapacity = minCapacity;
    239         if (newCapacity - MAX_ARRAY_SIZE > 0)
    240             newCapacity = hugeCapacity(minCapacity);
    241         // minCapacity is usually close to size, so this is a win:
    242         elementData = Arrays.copyOf(elementData, newCapacity);
    243     }
    244 
    245     private static int More ...hugeCapacity(int minCapacity) {
    246         if (minCapacity < 0) // overflow
    247             throw new OutOfMemoryError();
    248         return (minCapacity > MAX_ARRAY_SIZE) ?
    249             Integer.MAX_VALUE :
    250             MAX_ARRAY_SIZE;
    251     }

Are elements of ArrayList in Java reallocated in the memory when new ones are added If the size of the ArrayList has been passed to the constructor?

I am trying to write the method that efficiently wraps each element in the List passed to this method and returns the created ArrayList with wrapped elements.

According to the documentation:

The size(), isEmpty(), get(), set(), iterator(), and listIterator() operations run in constant time. The add operation runs in amortized constant time, that is, adding n elements requires O(n) time. All of the other operations run in linear time (roughly speaking). The constant factor is low compared to that for the LinkedList implementation.

Do I understand it right that If I create an ArrayList and pass the initial capacity to the constructor, the elements in ArrayList won’t be reallocated in memory when new ones are added?

Example:

public static <T> ArrayList<RequestToExternalSource<T>> wrapExternalSources(List<ExternalSource<T>> externalSources, BiConsumer<Integer, T> publishResult) {
    ArrayList<RequestToExternalSource<T>> requests = new ArrayList<>(externalSources.size());

    ListIterator<ExternalSource<T>> externalSourcesIterator = externalSources.listIterator();
    int index = 0;

    while (externalSourcesIterator.hasNext()) {
        requests.add(new RequestToExternalSource<>(
                index++,
                externalSourcesIterator.next(),
                publishResult));
    }
    return requests;
}  

Solution:

To answer this, we can look directly at the source code of ArrayList#add. We first see the following method:

public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}

The method above calls the following private, overloaded add method:

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

We can see that elementData (the Object[] that holds the data) will only grow when s (the size parameter, equal to ArrayList#size in our case) equals the length of the data array. For this reason, elementData is not grown even if we add n elements to an ArrayList initialized with a capacity of n, which is good!

Do I understand it right that If I create an ArrayList and pass the initial capacity to the constructor, the elements in ArrayList won’t be reallocated in memory when new ones are added?

For these reasons, yes, you’re correct, until you add more elements than the capacity specified.

Only returning the last element in ArrayList

I’ve been teaching myself java and I’ve stuck on a problem that no matter what I do can’t seem to solve. I’ve done some research but all the options provided don’t seem to work. Hopefully you guys might be able to teach me something.

I have a .txt file that contains:

AccountName1:Password1  
AccountName2:Password2  
AccountName3:Password3  
AccountName4:Password4  
AccountName5:Password5   

The elements of the file are then read and inserted into a List:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public abstract class AccountFileReader {

  private static Scanner sc;

  public static void main(String[] args) {  

      try {         
        // Enables ability to find file in any OS.
           String file = File.separator + "some folder name"
                         + File.seperator + "AccNamePw.txt";

           File f = new File(file);
           sc = new Scanner(f);

           List<AccountInfo> accounts = new ArrayList<AccountInfo>();
           String name = "";
           String password = "";

           while (sc.hasNext()){
            // Reads and checks if there is a new line
               String line = sc.nextLine();
            // Creates delimiter to make the different elements on file f
               String[] details = line.split(":");
            // Initializes 1st element
               name = details[0];
            // Initializes 2nd element
               password = details[1];           
            // Creates new object "a" that has the 2 elements from each line
               AccountInfo a = new AccountInfo(name, password);
            // Adds the "a" object to the "accounts" List
               accounts.add(a);
           }
        // Iterates list and prints out the list
           for(AccountInfo a: accounts){
        // The hiccup is in here somewhere. This for loop isn't working in 
        // a way I think it's supposed to.

        // Create new object of the getter, setter class to use in this loop
           AccountInfo namPw = new AccountInfo(name, password);
              name = namPw.getName();
              password = namPw.getPassword();               
              System.out.println(a.toString() + "         " + name 
                                 + " " + password);
           }
        } catch (FileNotFoundException e) {e.printStackTrace();}
    }
}

The getter/setter class is as follows:

public class AccountInfo{
private String name;
private String password;

public AccountInfo(String name, String password) {
    this.setName(name);
    this.setPassword(password);
}

public void setName(String name) { this.name = name; }

public String getName() { return name; }

public void setPassword(String password) { this.password = password; }    

public String getPassword() { return password; }

public String toString(){ return name + " "+ password; }
}

My output is:

AccountName1:Password1      AccountName5:Password5  
AccountName2:Password2      AccountName5:Password5  
AccountName3:Password3      AccountName5:Password5  
AccountName4:Password4      AccountName5:Password5  
AccountName5:Password5      AccountName5:Password5  

But I want it to return:

AccountName1:Password1      AccountName1:Password1  
AccountName2:Password2      AccountName2:Password2  
AccountName3:Password3      AccountName3:Password3  
AccountName4:Password4      AccountName4:Password4  
AccountName5:Password5      AccountName5:Password5  

I know that the a.toString() is returning correctly but my namPw.getName() and namPw.getPassword() are only giving me the last element of the List.

What am I not understanding and or missing? How do I get namPw.getName() and namPw.getPassword() to return the List correctly?

Solution:

The problem is the declaration of nameand password right before the while loop. These variables store the last encountered username and password. When the while loop ends, these variables store the values AccountName5 and Password5 respectively.

When you enter the second for-loop, you first create a new UserAccount with using nameand password which store AccountName5 and Password5.

If you just want to print this list, you do not need to create a copy of the contents of the list. Just do:

 for(AccountInfo a : accounts) {
     System.out.println(a.toString() + " " + a.getName() + " " + a.getPassword());
 }

What is difference between of listofIntegers.add(ValueOf(50)); and listofIntegers.add(50); in Java

what is difference between of these 2 codes

Arraylist<Integer> listofIntegers = new Arraylist<Integer>();
listofIntegers.add(666);
System.out.println("First Element of listofIntegers = " + listofIntegers.get(0));

and

Arraylist<Integer> listofIntegers = new Arraylist<integer>();
listofIntegers.add(Integer.ValueOf(666));
System.out.println("First Element of listofIntegers = " + listofIntegers.get(0));

both of them have save output.

thank you

Solution:

The boxing conversion uses Integer.valueOf implicitly, so there’s no difference between the two.

For example, consider this code:

public static void main(String[] args) {
    Integer x = 100;
    Integer y = Integer.valueOf(100);
}

The byte code for that (as shown by javap) is:

public static void main(java.lang.String[]);
    Code:
       0: bipush        100
       2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: bipush        100
       8: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      11: astore_2
      12: return

As you can see, the two pieces of code are identical.

Although the language specification section on boxing doesn’t guarantee that it will be implemented by valueOf, it does guarantee limited caching:

If the value p being boxed is the result of evaluating a constant expression (§15.28) of type boolean, char, short, int, or long, and the result is true, false, a character in the range ‘\u0000’ to ‘\u007f’ inclusive, or an integer in the range -128 to 127 inclusive, then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.

This is the same guarantee made by Integer.valueOf.

Grouping arraylist of objects and getting max value per group in java

I have an arraylist called ResultList. This arraylists consists of objects (Results) which in turn have a reference to a Participant object and Competition object as attributes. What I need to do is to group this arraylist (ResultList) by Participant and then put the max result (measurement) for each Participant in a new list.

Result class:

public class Result {

private double measurement;
private int participantID;
private Participant participant;
private Competition competition;

public Result(double measurement, int participantID, Competition competition, Participant participant) {
    this.measurement = measurement;
    this.participant = participant;
    this.competition = competition;
}

Participant class:

public class Participant {

private String firstName;
private String lastName;
private int id;
private String gender;
private String teamName;

public Participant(String firstName, String lastName, int id, String gender, String teamName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.id = id;
    this.gender = gender;
    this.teamName = teamName;
}

Finally I have the ResultList class:

public class ResultList {

private Scanner sc;

private String listName;
private ArrayList<Result> resultList = new ArrayList<Result>();

public ResultList(Scanner sc, String name) {
    this.sc = sc;
    this.listName = name;
}

In the ResultList class I have a method to sort the list using a comparator, after having iterated through it to find the results for a specific competition:

public void listResultsForCompetition(String competitionName) {
Iterator<Result> it = resultList.iterator();
boolean nothingFound = true;
ArrayList<Result> tempResultList = new ArrayList<Result>();
while (it.hasNext()) {
    Result nextItem = (Result) it.next();
    if (nextItem.getCompetitionName().equalsIgnoreCase(competitionName)) {
        nothingFound = false;
        tempResultList.add(nextItem);
    }
}
    if (nothingFound) {
        System.out.println("Error: No results found for this event. ");
    }
    Collections.sort(tempResultList, Result.ResultComparatorMeasurement);

}

So now I have an arraylist called tempResultList which has all the results for a specific competition ordered by the “measurement” attribute in the Result object. What I need to do now is to somehow get the top result from each participant in the tempResultList, and store this in another list, in order to produce a list of top results by participant for a specific competition.

I’ve googled for hours but I can’t make sense of the answers I’ve found, as most of them only have a simple list of integers or similarly. I’ve seen multiple references to maps, stream and collection methods but I can’t make sense of it.

Any help would be greatly appreciated!

EDIT: There is no fixed amount of results or participants in the arraylist.

Solution:

In case you have to sort something, List is not a perfect match of the collection. Depending on results, you have to choose best collection.

In your example, I do not see how you want to use List<Result> tempResultList. It seems, that you use is only as temporary collection to get you main objective – get top resulst of all participant. But I can see following things:

First: You already have a List<Result> tempResultList with sorted results (top results at the beginning). All you need is just iterate over this list and for each participant get the first result:

Map<Integer, Result> topResults =  new LinkedHashMap<>();

for(Result result : tempResultList) {
    if(!topResults.containsKey(result.getParticipant().getId()))
        topResults.put(result.getParticipant().getId(), result);
}

Notes: hree I got throug your tempResultList and fill a map, where key is a participant’s id and a value – participant’s result. If paraticipant is not in a map, then add his result to it (first one in the sorted list will be the top result). You can use here LinkedHashMap to sort keys in map according it apperas in the tempResultList, or TreeMap – to sort it by participant’s id. Or even – ‘HashMap’, when you do not care about an order of topResults.values().

Second: You can build tempResultList and then sort the top rated results at the same time, using Map<Integer, Set<Result>> res. You already has a comparator you need Result.ResultComparatorMeasurement. Key of the map – is a participant’s id, value – sorted list of participant’s results, with top results first.

public List<Result> listResultsForCompetition(String competitionName) {
    Map<Integer, Set<Result>> participantResults = new HashMap<>();

    for (Result result : resultList) {
        int participantId = result.getParticipant().getId();

        if (!participantResults.containsKey(participantId))

// TreeSet will sort results according to given comparator (top results first)
participantResults.put(participantId, new TreeSet<>(Result.ResultComparatorMeasurement));

        participantResults.get(participantId).add(result);
    }

    Map<Integer, Result> topParticipantResults = new HashMap<>();

    for (Map.Entry<Integer, Set<Result>> entry : participantResults.entrySet())
        topParticipantResults.put(entry.getKey(), entry.getValue().iterator().next());

    List<Result> topResults = new ArrayList<>(topParticipantResults.values());

    return topResults;
}

Notes: I do not use stream API here to make it maximum clear. I use TreeSet<Result>(comparator) to receive a sorted set of results (ATTENTION!!!Set use comparator to fined and exclude duplication, so your comparator should not only compare results, but work correctly where two instance of Result have same measurement). Map<Integer, Set<Result>> participantResults contains all results grouped by participant’s id.

There are other way to solve this task. I gave you only 2 ideas how to do it.

Eliminate null key from hashmap which is present inside an arraylist

I am looking for an optimized solution to remove null keys from a HashMap. This HashMap is present inside an ArrayList. Please find the example below.

public class Car {
    String year;
    String model;
    Map<String,String> colors;
}

List<Car> listOfCars = new ArrayList<Car>();

Sample of the colors map could be like this:

{
   red(1),
   blue(2),
   green(3),
   black(4),
   null(5)
}

I need a solution to iterate over the listOfCars, get the map of colors and remove the null key from that. Trying to see any other options in Java8 rather than using an Iterator.

Thanks!

Solution:

Considering a map cannot contain duplicate keys, we can, therefore, say that each Map instance of a Car instance will only ever have at most one entry with a null key.

The solution using the Java-8 forEach construct is:

listOfCars.forEach(e -> e.getColors().remove(null));

Although it can be done with a for loop or an enhanced for loop as well.

Putting multiple element from ArrayList to a single Array?

Need some help to understand how I can put all the elements from an ArrayList to a single Array. Not sure if its possible to do it in a single Array.

Declaration

List componentNameList = new ArrayList(); 
String[] componentNameItem = soapApiCall.getComponentNames(); 
componentNameList.add(Arrays.toString(componentNameItem));

Here is the element of the ArrayList:

[[Index, Pattern, Smart, Intell][Index, Tree, Pet, Intel][Index, Pattern, Bear, Intell, Dog][Sky, Intern, Blond]]

Expected output for the Array

<Index><Pattern><Smart><Intell><Index><Tree><Pet><Intel><Index><Pattern><Bear><Intell><Dog><Sky><Intern><Blond>

Thanks in advance.

Solution:

First, I’d suggest you not use raw types, nor do I suggest to add the string representation of an array to a raw type list.

Thus, change this:

List componentNameList = new ArrayList();

to this:

List<List<String>> componentNameList = new ArrayList<>();

then change this:

componentNameList.add(Arrays.toString(componentNameItem));

to this:

 componentNameList.add(new ArrayList<>(Arrays.asList(componentNameItem)));

Then you can accomplish the task at hand with streams like below:

String[] resultSet = componentNameList.stream() 
                                      .flatMap(List::stream) // flatten
                                      .toArray(String[]::new); // collect to array

then print:

 System.out.println(Arrays.toString(resultSet));