Reputation: 85
I have two arraylists
ArrayList<File> filesImage= new ArrayList<File>();
ArrayList<File> filesBox= new ArrayList<File>();
I want to merge into third arraylist like this
ArrayList<File[]> combinedFiles=new ArrayList<File[]>();
How can I do this? Output should be like:
[[ first object of filesImage, first object of filesBox],[second Object],[]]
Upvotes: 2
Views: 318
Reputation: 61
You can use function toArray of List to make array.
ArrayList<File> filesImage= new ArrayList<File>();
ArrayList<File> filesBox= new ArrayList<File>();
ArrayList<File[]> combinedFiles=new ArrayList<File[]>();
//add content to 2 lists here
File[] arrayFiles;
//add array image
arrayFiles = new File[filesImage.size()];
arrayFiles = filesImage.toArray(arrayFiles);
combinedFiles.add(arrayFiles);
//add array box
arrayFiles = new File[filesBox.size()];
arrayFiles = filesBox.toArray(arrayFiles);
combinedFiles.add(arrayFiles);
System.out.println(combinedFiles);
Upvotes: 0
Reputation: 11925
Assuming that the two lists are of equal length, here is a solution using Java8 streams and zip().
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Demo {
public static void main( String[] args ) {
List<String> filesImage = Arrays.asList("a","b","c");
List<String> filesBox = Arrays.asList("1","2", "3");
List<String[]> result = zip(filesImage.stream(), filesBox.stream(), (a,b) -> new String[] {a,b}).collect( Collectors.toList() );
for ( String[] e : result ) {
System.out.println( Arrays.asList(e) );
}
}
public static <A, B, C> Stream<C> zip(Stream<A> streamA, Stream<B> streamB, BiFunction<A, B, C> zipper) {
final Iterator<A> iteratorA = streamA.iterator();
final Iterator<B> iteratorB = streamB.iterator();
final Iterator<C> iteratorC = new Iterator<C>() {
@Override
public boolean hasNext() {
return iteratorA.hasNext() && iteratorB.hasNext();
}
@Override
public C next() {
return zipper.apply(iteratorA.next(), iteratorB.next());
}
};
final boolean parallel = streamA.isParallel() || streamB.isParallel();
return iteratorToFiniteStream(iteratorC, parallel);
}
public static <T> Stream<T> iteratorToFiniteStream( Iterator<T> iterator, boolean parallel) {
final Iterable<T> iterable = () -> iterator;
return StreamSupport.stream(iterable.spliterator(), parallel);
}
}
I borrowed the implementation of zip from Karol Krol here. Zip is the name from the functional world for this pattern of combining two lists in this manner. Also note that while Demo uses String's instead of File, the concept remains exactly the same.
Upvotes: 2
Reputation: 12019
Normally I wouldn't answer a question where OP doesn't show what they've tried, but since I'm seeing a flood of incorrect answers and interpretations...
List<File> filesImage= new ArrayList<File>();
List<File> filesBox= new ArrayList<File>();
List<File[]> combinedFiles=new ArrayList<File[]>();
for (int i = 0; i < filesImage.size(); ++i) {
File[] temp = new File[2];
temp[0] = filesImage.get(i);
temp[1] = filesBox.get(i);
combinedFiles.add(temp);
}
Something like this is known as "zipping" in functional programming, by the way. I'd suggest a solution with Java 8 lambdas, but there doesn't seem to be a zip function in Java SE and the above is quite simple.
Upvotes: 1
Reputation: 3944
Given that the two arrays are of equal length that you wish to combine, i'd personally do something like this.
List<File[]> combinedFiles= new ArrayList<File[]>();
for(int i = 0; i < filesBox.size(); i++){
combinedFiles.add(new File[] {filesImage.get(i), filesBox.get(i)});
}
Apologies if my methods are incorrect, its been a while since i've programmed in java.
Upvotes: 5
Reputation: 201
Should work similar to this pseudo code
List<File[]> merge = new ArrayList<>();
for(int i=0;i<filesImage.legth&&i<filesBox.length;i++{
merge.add(new File[]{i<filesImage.legth?filesImage[i]:null,i<filesBox.legth?filesBox[i]});
}
Upvotes: 0
Reputation: 88757
First, I'd create a class that holds the file references, e.g. like this:
class FileElement {
File image;
File box;
}
Then I'd create a list of those instead of arrays:
List<FileElement> combinedFiles = ...;
Then I'd iterate over both lists simultaneously:
Iterator<File> imgItr = filesImages.iterator();
Iterator<File> boxItr = filesBox.iterator();
//This assumes it's ok if both lists have different sizes.
//If it isn't you could try && instead, i.e. stop once you'd miss an image or a box
while( imgItr.hasNext() || boxItr.hasNext() ) {
FileElement e = ...;
if( imgItr.hasNext() ) {
e.image = imgItr.next();
}
if( boxItr.hasNext() ) {
e.box= boxItr.next();
}
combinedFiles.add( e );
}
Upvotes: 5