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],[]]
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.
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 );
}
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.
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.
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]});
}
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);
Related
I have modified the code and trying to get an ArrayList and the String stored in an Arraylist of Objects on a specific condition(say 'str' string equal to 2). I'm not able to convert the Stream to ArrayList. Please help me understand what needs to be done to get the ArrayList from this stream.
I have a class 'SampleClass' like below:
import java.util.ArrayList;
public class SampleClass {
String str;
ArrayList<String> al;
String check;
public SampleClass(String str, ArrayList<String> al, String check) {
super();
this.str = str;
this.al = al;
this.check = check;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public ArrayList<String> getAl() {
return al;
}
public void setAl(ArrayList<String> al) {
this.al = al;
}
public String getCheck() {
return check;
}
public void setCheck(String check) {
this.check = check;
}
}
I have another class 'GetTheArrayListStoredInAnotherArrayList' like below where I'm trying to get the ArrayList stored inside the ArrayList of objects. Please correct me where I'm wrong.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
public class GetTheArrayListStoredInAnotherArrayList{
public static void main(String[] args) {
String test = "qw,rer,try,try,erh5,wertgw45t,45";
ArrayList<String> al = new ArrayList<String>();
al.addAll(new ArrayList<String>(Arrays.asList(test.split(","))));
System.out.println(al);
ArrayList<SampleClass> sca = new ArrayList<SampleClass>();
SampleClass sc1 = new SampleClass("1", al,"ch1");
SampleClass sc2 = new SampleClass("2", al,"cc2");
SampleClass sc3 = new SampleClass("3", al,"fr3");
SampleClass sc4 = new SampleClass("4", al,"fg4");
sca.add(sc1);
sca.add(sc2);
sca.add(sc3);
sca.add(sc4);
ArrayList<String> als1 = null;
ArrayList<String> als = sca.stream().filter( s -> s.getStr().equals("2")).flatMap(sc -> sc.getAl().stream()).collect(Collectors.toCollection(ArrayList::new));
System.out.println(als);
String ch = (String) sca.stream().filter(s -> s.getStr().equals("1")).map(ac -> ac.getCheck());
System.out.println(ch);
}
}
I got the below error when I executed the code :
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot cast from Stream<String> to String
at GetTheArrayListStoredInAnotherArrayList.main(GetTheArrayListStoredInAnotherArrayList.java:24)
Not entirely sure what you are trying to do, but you need to change your code a bit:
List<String> als = sca.stream()
.filter(s -> s.getStr().equals("2"))
.flatMap(sc -> sc.getAl().stream())
.collect(Collectors.toList());
A few things :
flatMap must return a Stream (in your case you are returning a List)
Collectors.toList makes no guarantee of the List in returns, so the assignment is to a List, not an ArrayList.
EDIT
This:
Stream<String> stream = sca.stream().filter(s -> s.getStr().equals("1"))
.map(ac -> ac.getCheck());
Will produce a Stream<String>. You can't simply cast that to a String, you have to collect/reduce that to whatever you want. Like let's say a List:
List<String> list = sca.stream()
.filter(s -> s.getStr().equals("1"))
.map(ac -> ac.getCheck())
.collect(Collectors.toList());
Or a single String for example:
String r = sca.stream()
.filter(s -> s.getStr().equals("1"))
.map(ac -> ac.getCheck())
.collect(Collectors.joining(","));
This is actually basic stuff... you should really study some samples and the documentation.
Change
ArrayList<String> als = sca.stream().filter( s -> s.getStr().equals("2")).flatMap( sc -> sc.getAl());
To
ArrayList<String> als = sca.get(0).getAl();
First you have to use List instead of ArrayList. So with List you code will looks like
List<String> als1 = null;
List<String> als = sca.stream().
filter(s -> s.getStr().equals("2")). //Comparing
map(s -> s.getAl()) // Converting List<SampleClass> to list of all al list inside all SampleClass in format List<List<Straing>>
.flatMap(ArrayList::stream) //Creating a flat list from list of list of List :: List<List<Straing>> --To--> List<String>
.collect(Collectors.toList()); // Collecting as list
I have commented this code with details. But here if there are two SampleCalss objects in the list with str=2 then it will merge the al list of both objects. hope it will help you .
I'm trying to get the ArrayList stored inside the ArrayList of objects.
Well, the basic algorithm is as follows: Filter sca so it only leaves elements where str is "2" -> Get a single element from all the left over elements -> Get the al stored inside of that element.
You have done the first part correctly:
sca.stream().filter( s -> s.getStr().equals("2"))
But now you need to get a single element from the filtered result (filter can result in multiple elements being left over), so you call findFirst:
.findFirst().get()
This get call will throw an exception if there is no element left after the filter. If you don't want it to throw an exception, you can replace it with an orElse call:
.findFirst.orElse(new SampleClass("", null))
If you use orElse, the method chain will evaluate to null if no element with str being "2".
Now you just need to get the array list by calling getAl():
.getAl();
Now we combine all this together:
ArrayList<String> als = sca.stream()
.filter( s -> s.getStr().equals("2"))
.findFirst().orElse(new SampleClass("", null)).getAl();
This is my starting code for a van rental database.
List<String> manual = new LinkedList<>();
List<String> automatic = new LinkedList<>();
List<String> location = new LinkedList<>();
manual.add("Queen");
manual.add("Purple");
manual.add("Hendrix");
automatic.add("Wicked");
automatic.add("Zeppelin");
automatic.add("Floyd");
automatic.add("Ramones");
automatic.add("Nirvana");
location.add("CBD");
location.add("Penrith");
location.add("Ceremorne");
location.add("Sutherland");
How can I link the cars to the location.
For example, location CBD has Wicked,Zepplin and Floyd, and Penrith has Queen.
So if the command line arguement has "Print CBD" then it must show the vans available in CBD.
Any help will be appreciated.
This is hardly a database. They are just three separate data pieces. Use some object-oriented design technique to create classes, such as a class called Van. For example, it's not java code exactly, just for example.
Class Van {
string name;
VanType type; // e.x, Enum {auto, manual}
Location location; // another class
}
I think you would be better off using the approach explained In This Post. I believe this would be a much clearer implementation.
I hope this helps.
Ok thats the code.
We are using only linked list as you wanted.
(linked list keeps track on the input order so we are using that too)
As it is one to many relation we should have some kind of "foreign key" so we can see the related object. For each car you add no matter manual or auto, you should add a key for the location as you can see below
for example rels[0] = 3; means that your first car will have relation with 4th object of the locations list. thats implemented in the code - take a look.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TestMain {
public static void main(String[] args) {
List<String> manual = new LinkedList<String>();
List<String> automatic = new LinkedList<String>();
List<String> location = new LinkedList<String>();
int[] rels = new int[8];
//cars with relations
rels[0] = 1;
manual.add("Queen");
rels[1] = 1;
manual.add("Purple");
rels[2] = 1;
manual.add("Hendrix");
rels[3] = 1;
automatic.add("Wicked");
rels[4] = 0;
automatic.add("Zeppelin");
rels[5] = 0;
automatic.add("Floyd");
rels[6] = 1;
automatic.add("Ramones");
rels[7] = 2;
automatic.add("Nirvana");
//key-0
location.add("CBD");
//key-1
location.add("Penrith");
//key-2
location.add("Ceremorne");
//key-3
location.add("Sutherland");
//here is the value that you have from your input args[] for example
String desiredLocation = "CBD";
int index = getLocationIndex(location, desiredLocation);
//if desired location not found we will print nothing
if(index==-1)return;
List mergedCars = new LinkedList<String>();
mergedCars.addAll(manual);
mergedCars.addAll(automatic);
for (int i = 0; i < rels.length; i++) {
if(index == rels[i])
{
System.out.println(mergedCars.get(i));
}
}
}
private static int getLocationIndex(List<String> location, String desiredLocation) {
int counter=0;
for (Iterator iterator = location.iterator(); iterator.hasNext();) {
String temp = (String) iterator.next();
if(temp.equals(desiredLocation))
{
return counter;
}
counter++;
}
return -1;
}
}
This question already has answers here:
Java Beginner: How do I link one linked list to another?
(6 answers)
Closed 8 years ago.
I hava list of LinkedList and I want to make (unable to modified) One connected LinkedList .
and not change the original linkedLists.
LinkedLists<String> a=new LinkedList<String>();
LinkedLists<String> b=new LinkedList<String>();
LinkedLists<String> c=new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
b.add("as");
b.add("sa");
c.add("bb");
c.add("d");
c.add("ya");
the new LinkedList contain ya d bb sa as bb sa as
so I want to make one Linked List.I preffer Not copy the items casue this consume memory.
Only connect theme for go all over the items not to modified the items.
Thanks!
Try Collections#unmodifiableList()
Sample code:
LinkedList<String> a = new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
a.add("as");
a.add("sa");
a.add("bb");
a.add("d");
a.add("ya");
List<String> b = Collections.unmodifiableList(a.subList(0, 3));
List<String> c = Collections.unmodifiableList(a.subList(5, 8));
b.set(0, "aa"); // not allowed
c.add("zz"); // not allowed
a.set(6, "zz"); // allowed and List c is also updated.
Try subclassing List. Here's a quick example I put together below. It's largely incomplete but you'll get the idea.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Experiment {
public static void main(String[] args) throws Exception {
LinkedList<String> a = new LinkedList<String>();
LinkedList<String> b = new LinkedList<String>();
LinkedList<String> c = new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
b.add("as");
b.add("sa");
c.add("bb");
c.add("d");
c.add("ya");
MyLinkedList<String> list = new MyLinkedList<String>();
list.add(a);
list.add(b);
list.add(c);
for (String s : list) {
System.out.println(s);
}
}
private static class MyLinkedList<T> extends LinkedList<T> {
private List<List<T>> lists = new LinkedList<List<T>>();
public void add(LinkedList<T> list) {
lists.add(list);
}
#Override
public Iterator<T> iterator() {
return new MyLinkedIterator<T>(lists);
}
}
private static class MyLinkedIterator<T> implements Iterator<T> {
private List<List<T>> lists;
private int listIndex = 0;
private int currentIndex = 0;
private T next;
public MyLinkedIterator(List<List<T>> lists) {
this.lists = lists;
}
public boolean hasNext() {
if (listIndex >= lists.size()) return false;
List<T> list = lists.get(listIndex);
if (currentIndex >= list.size()) {
currentIndex = 0;
listIndex++;
return hasNext();
}
next = list.get(currentIndex++);
return true;
}
public T next() {
return next;
}
public void remove() {
}
}
}
How about this:
LinkedList<String> a=new LinkedList<String>();
LinkedList<String> b=new LinkedList<String>();
LinkedList<String> c=new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
b.add("as");
b.add("sa");
c.add("bb");
c.add("d");
c.add("ya");
LinkedList<String> unionList = new LinkedList<String>();
unionList.addAll(a);
unionList.addAll(b);
unionList.addAll(c);
LinkedList<String> unmodifiableUnion = Collections.unmodifiableList(unionList);
It uses addAll() to add all lists into a new one and returns an unmodifiable list from it using Collections.unmodifiableList()
Update
If memory consumption is your problem, the standard JDK is not enough. You will have to implement your own or use an existing one.
To implement your own you can usa a LinkedList<List<T>> to store your linked lists and implement the List interface. mprivat started an implementation for you.
To use an existing one, you could use:
Trove: it is considered really good and fast if no fastest with least memory consumption, at least that is what I have observed in my usages of it.
this implementation: it is a singly linked list so it consumes less memory and has a merge method that will merge 2 linked lists using their "pointers" as you would expect.
I have an array list which when populated has a key and a value I want to know if there is a way of splitting it on repeating keys for example my current data is like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom, RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave, RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
I want it to come out more like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom]
[RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave]
[RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
Is there a way to split it on say role id or am I going about this the wrong way?
You can try by using HashMap
private static class MyItemHashMap extends HashMap {
public Item add(Item item) {
get(item).add(item);
return item;
}
public List get(Item key) {
List list = (List) get(createItemKey((Item) key));
return list == null ? createItemEntry((Item) key) : list;
}
private List createItemEntry(Item item) {
List list = new ArrayList();
put(createItemKey(item), list);
return list;
}
private Object createItemKey(Item item) {
return item.getSplitterProperty();
}
}
public static void main(String[] args) {
MyItemHashMap itemMapped = new MyItemHashMap();
List items = Arrays.asList(new Object[]{new Item("A"), new Item("B"),
new Item("C")});
for (Iterator iter = items.iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
itemMapped.add(item);
}
}
If it is an ArrayList, there is no built-in function to split data like this; you will have to do it manually. If you know the number of consecutive fields that make a single structure, this shouldn't be too hard; something like this:
// 6 because there are 6 fields
for (int i = 0; i < arrayList.size(); i = i + 6) {
List thisList = arrayList.subList(i, i + 5);
// ... Now do whatever you want with thisList - it contains one structure.
}
If the number of fields can change then you'll have to do something a little more dynamic and loop through looking for a RoleID field, for example.
I'd use a HashMap to seperate the data instead of one long ArrayList ( you shouldn't have stored the data like this in the first instance )
HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>;
// For each list:
ArrayList<String> arr = new ArrayList<String>;
arr.add("each element");
hm.put("RoleID_123.0", arr);
This way you will end up with a three dimensional structure with a key ( "RoleID..." ) pointing to its child elements.
Try this
String[] str=new String[]{"RoleID_123.0", "UserHandel_tom", "Password_12345.0", "prevPassword_null", "userCaption_thomas", "Email_tom#tom.tom", "RoleID_124.0", "UserHandel_dave", "Password_ghadf", "prevPassword_sdfsd", "userCaption_david", "Email_dave#dave.dave", "RoleID_125.0", "UserHandel_trevor", "Password_tre", "prevPassword_null", "userCaption_trev", "Email_trev#trev.trev"};
List<String> list=new ArrayList<>(Arrays.asList(str));
List<String> subList=list.subList(0,5);
You can try something similar to this
If you feel like taking a Linq-ee Libraried approach, this is about as good as it gets, and it requires use of a couple delegate objects:
import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Collections2.transform;
//...
final List<String> yourList = //...
final int RECORD_LENGTH = 6;
Collection<String> roleIdValues = filter(yourList, new Predicate<String>() {
public boolean apply(#Nullable String input) {
return input != null && input.startsWith("RoleID");
}
});
Collection<Collection<String>> splitRecords = transform(roleIdValues, new Function<String, Collection<String>>() {
#Nullable public Collection<String> apply(#Nullable String input) {
return yourList.subList(yourList.indexOf(input), RECORD_LENGTH);
}
});
If Oracle had delivered Java 8 on time you would be able to do this in a way more slick manor. Ironically the reason you cant was provided by the same people providing the guava library
I want to print or retrieve all the words stored in Trie Data Structure. This is because I want to compute Edit distance between a misspelled word and a word in Dictionary.
Therefore I was thinking of retrieving each word from Trie and compute Edit distance.
But I am not able to retrieve. I want some code snippet for this.
This is how I have implemented the Trie using HashMap in Java
Now please tell me how to write code for printing all words stored in Trie. Any help is very much appreciated
TrieNode.java
package triehash;
import java.io.Serializable;
import java.util.HashMap;
public class TrieNode implements Serializable {
HashMap<Character, HashMap> root;
public TrieNode() {
root = new HashMap<Character, HashMap>();
}
}
TrieDict.java
package triehash;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;;
import java.io.Serializable;
import java.util.HashMap;
import java.io.Serializable;
public class TrieDict {
public TrieNode createTree()
{
TrieNode t = new TrieNode();
return t;
}
public void add(String s, TrieNode root_node) {
HashMap<Character, HashMap> curr_node = root_node.root;
s = s.toLowerCase();
for (int i = 0, n = s.length(); i < n; i++) {
Character c = s.charAt(i);
if (curr_node.containsKey(c))
curr_node = curr_node.get(c);
else {
curr_node.put(c, new HashMap<Character, HashMap>());
curr_node = curr_node.get(c);
}
}
curr_node.put('\0', new HashMap<Character, HashMap>(0)); // term
}
public void serializeDict(TrieNode root_node)
{
try{
FileOutputStream fout = new FileOutputStream("/home/priya/NetBeansProjects/TrieHash/dict.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(root_node);
oos.close();
System.out.println("Done");
}catch(Exception ex){
ex.printStackTrace();
}
}
public void addAll(String[] sa,TrieNode root_node) {
for (String s: sa)
add(s,root_node);
}
public static void main(String[] args)
{
TrieDict td = new TrieDict();
TrieNode tree = td.createTree();
String[] words = {"an", "ant", "all", "allot", "alloy", "aloe", "are", "ate", "be"};
for (int i = 0; i < words.length; i++)
td.add( words[i],tree);
td.serializeDict(tree); /* seriliaze dict*/
}
}
First, it's worth noting that the declared type of the root instance variable is a little odd. (Specifically, the value type of HashMap<Character,HashMap> excludes some of the generics you'd rather it used.) The code below should work, but you'll get some warnings as a result of this. You might try refactoring your code to use the type HashMap<Character,TrieNode> instead. Sorry if that's pedantic. :)
Try this, added as methods to TrieNode:
public Set<String> computeWords() {
Set<String> result;
if(root.size() == 0)
result = new HashSet<String>();
else
result = computeWords(root, "");
return result;
}
protected static Set<String> computeWords(HashMap tree, String prefix) {
Set<String> result=new HashSet<String>();
if(tree.size() == 0)
result.add(prefix);
else
for(Object o : tree.keySet()) {
Character c=(Character) o;
prefix = prefix+c;
result.addAll(computeWords((HashMap) tree.get(c), prefix));
prefix = prefix.substring(0, prefix.length()-1);
}
return result;
}
For a given TrieNode object t, t.computeWords() would return the set of all words words encoded in t.
I believe this answers the question you were trying to ask. However, to answer the question as stated in the header, you'd print all the words for the same t like this:
for(String word : t.computeWords())
System.out.println(word);
Also, this definitely isn't the most efficient implementation, especially since we create a bunch of HashSet objects in computeWords(HashMap,String), but it should work!
EDIT: This code also assumes that you terminate words with an empty HashMap. If you terminate words with null instead, you'd need to update the if(tree.size() == 0) check in the static method with if(tree == null). Sorry, should have called that out.
EDIT: Explained how to print all the words, just in case it wasn't clear.
EDIT: Fixed empty trie case.