I am trying a lot but not able to write a recursive function for this.
For Example I have the below list of list which keeps the mapping (not a map as keys are duplicate):
[[review1, exclusivegateway4],
[exclusivegateway4, inclusivegateway1],
[inclusivegateway1, T_Review],
[inclusivegateway1, L_Review],
[inclusivegateway1, SP_Review],
[inclusivegateway1, M_Review]]
The need is to bypass the mappings which contain string 'gateway'. So as we can see that review1 is mapped to exclusivegateway4 and exclusivegateway4 is mapped to inclusivegateway1 and then inclusivegateway1 is mapped to T_Review, L_Review, SP_Review and M_Review. So bypassing all the 'gateway' string the final mapping should be:
[[review1, T_Review],
review1, L_Review],
review1, SP_Review],
review1, M_Review]]
I need to make this function recursive as there could be more gateways in there. I know that is too much to ask. But I am missing something in the code.
Thanks,
Nitin
Below is the code without recursion
private void decorateList(ArrayList<ArrayList<String>> mappingList ){
for(ArrayList<String> list: mappingList){
String src = list.get(0);
String target = list.get(1);
if(target.contains("gateway")){
listToRemove.add(list);
for(ArrayList<String> list2: mappingList){
String list2Src = list2.get(0);
String list2Target = list2.get(1);
if(list2Src.equals(target)){
if(list2Target.contains("gateway")){
for(ArrayList<String> list4: mappingList){
String list4Src = list4.get(0);
String list4Target = list4.get(1);
if(list4Src.equals(list2Target)){
ArrayList<String> list5 = new ArrayList<String>();
list5.add(src);
list5.add(list4Target);
listToAdd.add(list5);
}
}
break;
}
ArrayList<String> list3 = new ArrayList<String>();
list3.add(src);
list3.add(list2Target);
listToRemove.add(list2);
listToAdd.add(list3);
}
}
}
}
Iterator<ArrayList<String>> itr = mappingList.iterator();
while (itr.hasNext()){
ArrayList<String> list = itr.next();
if (listToRemove.contains(list)){
itr.remove();
}
}
mappingList.addAll(listToAdd);
}
And below is the code which I have written with recursion
ArrayList<ArrayList<String>> mappingList2 = mappingList;
for(ArrayList<String> list : mappingList2){
// Below line is calling the recursive function
mappingList = decorateListRecursive(mappingList, list);
}
private ArrayList<ArrayList<String>> decorateListRecursive(ArrayList<ArrayList<String>> mappingList, ArrayList<String> list){
System.out.println("Count " + count);
count++;
String src = list.get(0);
String target = list.get(1);
if(target.contains("gateway")){
listToRemove.add(list);
Iterator<ArrayList<String>> itr = mappingList.iterator();
while(itr.hasNext()){
ArrayList<String> list2 = itr.next();
String list2Src = list2.get(0);
String list2Target = list2.get(1);
if(list2Src.equals(target)){
if(list2Target.contains("gateway")){
decorateListRecursive(mappingList, list2);
}
ArrayList<String> list3 = new ArrayList<String>();
list3.add(src);
list3.add(list2Target);
listToAdd.add(list3);
}else{
}
}
}
return mappingList;
}
Uh, the recursion (as I understand the task is:)
create empty result list
call getTerminalSymbolFor(firstkey, firstkey, resultlist)
getTerminalSymbolFor(String root, String key, resultlist)
search in ArrayList for key into value
if not found: add root=key to resultlist and return
else: return getTerminalSymbolFor(root, value, resultlist) (do recursion)
From your description I am not sure if you start with any symbol, the first or non-terminal ones. But all can be adjusted. I think you might want to pass in a "resolved list" and instead of returning the found one you add it to the lis
BTW: this is horrible inefficient.
eckes algorithm helped me to get to the solution. I looped through the list and called the list recursively until I found the required Item. Then added that item into resultList.
Thanks
Related
This is my first list:
String[] myList = ["john","Coding","haha","tukku", "Coding/a","Coding/a/b", "folder1/file1.txt", "folder1/folder2/file1.txt"]
String[] lst1 = ["John","Coding/*", "folder1/*"]
finallist = mylist - lst1
I want to remove all the files from myList which have their parent folder name in lst1
expected result
["haha", "tukku"]
If you change lst1 to regular expression then code could be quite simple..
def mylist = ["john","Coding","haha","tukku", "Coding/a","Coding/a/b", 'folder1/file1.txt', 'folder1/folder2/file1.txt']
lst1 = ["john", "Coding/*", "folder1/*"]
def re = lst1.collect{ it.replaceAll('\\*', '.*') }.join('|')
// re = "john|Coding/.*|folder1/.*"
def finallist = mylist.findAll{ !(it==~re) }
This would be one solution. I did not use any streams to keep the solution simple:
String[] myList = {"john","Coding","haha","tukku", "Coding/a","Coding/a/b", "folder1/file1.txt", "folder1/folder2/file1.txt"};
String[] filterList = {"john","Coding/*", "folder1/*"};
ArrayList<String> result = new ArrayList<>();
for(String listElement: myList) // Iterating over each list element
{
String elementParent = listElement.split("/")[0]; // Getting the first parent (the first string before /)
boolean toBeAdded = true; // Variable that keeps track whether this element has to be added to result or not
for(String filterStr: filterList)
{
String filterParent = filterStr.split("/")[0]; // Getting the parent of the Filter String.
if(elementParent.toLowerCase().equals(filterParent.toLowerCase())) // If The element parent and the filter parent are the same, then we do not add it.
{
toBeAdded = false;
break;
}
}
if(toBeAdded)
{
result.add(listElement);
}
}
System.out.println(result);
And this is the output:
[haha, tukku]
I want to merge two corresponding values of two different variables with comma separator in a row :
like
Plate Numbers(Output) : MH 35353, AP 35989, NA 24455, DL 95405.
There is two different variables one is plate State and another is plate Number, I want to merge them together with their corresponding values like 1st values of plate State with 1st value of plate Number after that comma then so on..
I tried this code snippet but didn't work :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
list1.addAll(list2);
use this :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
Iterator iterable = list2.iterator();
List<String> list3 =list1.stream()
.map(x->{
x= x+" "+((String) iterable.next());
return x;})
.collect(Collectors.toList());
String output = String.join(", ", list3);
System.out.println(output);
From ArrayList#addAll Javadoc:
Appends all of the elements in the specified collection to the end of this list[...]
This is not what you want, because you actually don't want to append the objects, you want to merge the String of the first list with the String from the second list. So in a sense, not merge the List but merge the objects (Strings) in the lists.
The easiest (most beginner friendly) solution would be to just create a simple helper method yourself, that does what you need.
Something like this:
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA");
list1.add("DL");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
ArrayList<String> combined = combinePlateNumbers(list1, list2);
System.out.println(combined);
}
private static ArrayList<String> combinePlateNumbers(List<String> list1, List<String> list2) {
ArrayList<String> result = new ArrayList<>();
if (list1.size() != list2.size()) {
// lists don't have equal size, not compatible
// your decision on how to handle this
return result;
}
// iterate the list and combine the strings (added optional whitespace here)
for (int i = 0; i < list1.size(); i++) {
result.add(list1.get(i).concat(" ").concat(list2.get(i)));
}
return result;
}
Output:
[MH 35353, AP 35989, NA 24455, DL 95405]
I'm trying to access data from an Arraylist that is stored in an Arraylist. I'm sure there is a really easy way to do this and I don't want to waste anyone's time but I've tried lots of ways and can't seem to find the answer anywhere. Any help would be really appreciated.
This is my code for creating the Arrays.
public ArrayList SGenresMaster = new ArrayList(new ArrayList());
public ArrayList S1Genres = new ArrayList();
public ArrayList S2Genres = new ArrayList();
public ArrayList S3Genres = new ArrayList();
public void accessArrays(){
SGenresMaster.add(S1Genres);
SGenresMaster.add(S2Genres);
SGenresMaster.add(S3Genres);
}
Basically i need to be able to access any index of S1Genres using SgenresMaster.
So far I've only managed to get the data out as a long string so I thought I'd post my current method for getting the data I need, as i thought it would probably make the pro's here cringe/laugh.
createarray(SGenresMaster.get(i).toString());
public ArrayList createarray(String string){
String sentence = string;
String[] words = sentence.split(", ");
ArrayList temp = new ArrayList();
int b = 0;
for (String word : words)
{
if (b == 0){
//Delete First bracket
temp.add(word.substring(1,word.length()));
System.out.println("First Word: " + temp);
}
else{
temp.add(word.substring(0,word.length()));
System.out.println("Middle Word: " + temp);
}
b++;
}
//Delete last bracket
String h = String.valueOf(temp.get(temp.size() - 1));
temp.add(h.substring(0,h.length() - 1));
temp.remove(temp.size() - 2);
System.out.println("final:" + temp);
return temp;
}
Using raw generic types is a bad practice. You lose all the advantages of generics that way.
That said, for illustration if your sublists are made up of Strings:
ArrayList<List<String>> SGenresMaster = new ArrayList<List<String>>();
ArrayList<String> S1Genres = new ArrayList<String>();
ArrayList<String> S2Genres = new ArrayList<String>();
ArrayList<String> S3Genres = new ArrayList<String>();
SGenresMaster.add(S1Genres);
SGenresMaster.add(S2Genres);
SGenresMaster.add(S3Genres);
SGenresMaster.get(0).get(0); //gets the first element of S1Generes
I hope your got your question right:
for(ArrayList<String> arr: SGenresMaster){
//arr can be any array from SGenresMaster
for(String s : arr){
//do something
}
}
or
SGenresMaster.get(index).get(someOtherIndex);
I have a array list in which I bind the data
This is a example
MyStrings =new ArrayList<String>();
MyStrings.add("Dog");
MyStrings.add("Cat");
MyStrings.add("Can");
MyStrings.add("Ant");
MyStrings.add("Str");
Now I have a string String sweet="c";
Now what OI want is to filter that Arraylist based on my string(sweet)
so the items of the MyStrings will be only Cat and Can
EDIT
I am really sorry for the trouble I got you but my main problem is that sweet is a editable
Ive tried using this code
public void onTextChanged(CharSequence s, int start, int before,int count) {
//adapter2.getFilter().filter(s);
//int length = filterEditText.getText().length();
filterME = filterEditText.getText();
List<String> MySortStrings =new ArrayList<String>();
for(int i=0;i<MyStrings.size();i++)
{
String newString = MyStrings.get(i);
if (newString.startsWith(filterME)){
}
}
//adapter2 = new LazyAdapterGetFriends(MyFriends.this,x);
//list.setAdapter(adapter2);
}
using this declaration
LazyAdapterGetFriends adapter2;
ArrayList<String> MyStrings;
//List<String> MyStrings;
EditText filterEditText;
Sorry for my wrong question..
Foolish me
List<String> MyStrings =new ArrayList<String>();
List<String> MySortStrings =new ArrayList<String>();
MyStrings.add("Dog");
MyStrings.add("Cat");
MyStrings.add("Can");
MyStrings.add("Ant");
MyStrings.add("Str");
String sweet="c";
for(int i=0;i<MyStrings.size();i++)
{
if(MyStrings.get(i).startsWith(sweet.toUpperCase()))
{
MySortStrings.add(MyStrings.get(i));
}
}
System.out.println(MySortStrings.size());
The list MySortStrings contains the Cat & Can
These days you can also use streams to do it easily:
stringList.stream().filter(s -> s.contains("c")).collect(Collectors.toList())
When you would only need to know if there is a string in the list containing your letter (not part of the question but very useful) you can do this:
stringList.stream().anyMatch(s -> s.contains("c"))
Use str.startsWith(String, int index)
Index will tell you from which index in the str it should start comparing
The naive algorithm will be that you just filter everything out like this:
ArrayList<String> filtered = new ArrayList<String>();
for(String s : MyStrings){
if(s.substring(0,1).toLowerCase().equals("c")){
filtered.add(s);
}
}
but then you have access time in O(n).
if you need a more faster way you probably need to use a Key,Value Structure with Key set to the String you need to filter. Or even a http://en.wikipedia.org/wiki/Trie, where you can easily filter on every character in the string. But then you will need extra time in building up this thing.
Okay, this should be it when using your TextWatcher Stuff (untested...)
private List<String> MySortStrings = new ArrayList<String>(); // assume that your data is in here!
private List<String> MySortedStrings = new ArrayList<String>(); // this will be the list where your sorted strings are in. maybe you could also remove all strings which does not match, but that really depends on your situation!
public void onTextChanged(CharSequence s, int start, int before,int count) {
for(String str : MySortStrings){
if(str.startsWith(s.toString()){
MySortedStrings.add(str);
}
}
}
If you want to remove items that don't match from MyStrings rather than create a new ArrayList you will need to use an Iterator as this is the only safe way to modify a ArrayList while iterating over it.
myStrings = new ArrayList<String>();
myStrings.add("Dog");
myStrings.add("Cat");
myStrings.add("Can");
myStrings.add("Ant");
myStrings.add("Str");
String sweet="c";
sweet = sweet.toLowerCase();
Iterator<String> i = myStrings.iterator();
while (i.hasNext()) {
if (! i.next().toLowerCase().startsWith(sweet)) {
i.remove();
}
}
You can use the apache commons-collections library as well:
CollectionUtils.filter(myStrings,
new Predicate() {
public boolean evaluate(Object o) {
return ! ((String)o).startsWith("c");
}
}
};
Any object for which the "evaluate" method of the Predicate class returns false is removed from the collection. Keep in mind, that like the solution above using the Iterator, this is destructive to the list it is given. If that is an issue, you can always copy the list first:
List<String> filtered = new ArrayList<String>(myStrings);
CollectionUtils.filter(filtered, ...);
I'm confused about on how to use this array in a way that is simple. Well I already passed the values from the JSON into a List and now I need to retrieve it using a loop (and just loop) but I don't know how. Tried reading some answers but I found myself really confused in the end. I just want it to be simple as making a String array, loop and fetch data by getting the variable[index] simple as that but all the answers I've found just lead me into confusion. Help please.
As I understand your question..
From Java List class you have to methods add(E e) and get(int position).
add(E e)
Appends the specified element to the end of this list (optional operation).
get(int index)
Returns the element at the specified position in this list.
Example:
List<String> myString = new ArrayList<String>();
// How you add your data in string list
myString.add("Test 1");
myString.add("Test 2");
myString.add("Test 3");
myString.add("Test 4");
// retrieving data from string list array in for loop
for (int i=0;i < myString.size();i++)
{
Log.i("Value of element "+i,myString.get(i));
}
But efficient way to iterate thru loop
for (String value : myString)
{
Log.i("Value of element ",value);
}
public static void main(String[] args) {
List<String> ls=new ArrayList<String>();
ls.add("1");
ls.add("2");
ls.add("3");
ls.add("4");
//Then you can use "foreache" loop to iterate.
for(String item:ls){
System.out.println(item);
}
}
Use the For-Each loop which came with Java 1.5, and it work on Types which are iterable.
ArrayList<String> data = new ArrayList<String>();
data.add("Vivek");
data.add("Vadodara");
data.add("Engineer");
data.add("Feelance");
for (String s : data){
System.out.prinln("Data of "+data.indexOf(s)+" "+s);
}
Try following if your looking for while loop implementation.
List<String> myString = new ArrayList<String>();
// How you add your data in string list
myString.add("Test 1");
myString.add("Test 2");
myString.add("Test 3");
myString.add("Test 4");
int i = 0;
while (i < myString.size()) {
System.out.println(myString.get(i));
i++;
}
List<String> al=new ArrayList<string>();
al.add("One");
al.add("Two");
al.add("Three");
for(String al1:al) //for each construct
{
System.out.println(al1);
}
O/p will be
One
Two
Three
Answer if you only want to use for each loop ..
for (WebElement s : options) {
int i = options.indexOf(s);
System.out.println(options.get(i).getText());
}
pst = con.createStatement();
ResultSet resultSet= pst.executeQuery(query);
String str1 = "<table>";
int i = 1;
while(resultSet.next()) {
str1+= "</tr><td>"+i+"</td>"+
"<td>"+resultSet.getString("first_name")+"</td>"+
"<td>"+resultSet.getString("last_name")+"</td>"+
"<td>"+resultSet.getString("email_id")+"</td>"+
"<td>"+resultSet.getString("dob") +"</td>"+
"</tr>";
i++;
}
str1 =str1+"<table>";
model.addAttribute("list",str1);
return "userlist"; //Sending to views .jsp