This is a drive method for two other classes. which i posted here
https://codereview.stackexchange.com/questions/33148/book-program-with-arraylist
I need some help for the
private static ArrayList getAuthors(String authors) method. I am kind a beginner. so please help me finish this drive method. or give me some directions.
Instruction
some of the elements of the allAuthors array contain asterisks “*” between two authors names. The getAuthors method uses this asterisk as a delimiter between names to store them separately in the returned ArrayList of Strings.
import java.util.ArrayList;
public class LibraryDrive {
public static void main(String[] args) {
String[] titles = { "The Hobbit", "Acer Dumpling", "A Christmas Carol",
"Marley and Me", "Building Java Programs",
"Java, How to Program" };
String[] allAuthors = { "Tolkien, J.R.", "Doofus, Robert",
"Dickens, Charles", "Remember, SomeoneIdont",
"Reges, Stuart*Stepp, Marty", "Deitel, Paul*Deitel, Harvery" };
ArrayList<String> authors = new ArrayList<String>();
ArrayList<Book> books = new ArrayList<Book>();
for (int i = 0; i < titles.length; i++) {
authors = getAuthors(allAuthors[i]);
Book b = new Book(titles[i], authors);
books.add(b);
authors.remove(0);
}
Library lib = new Library(books);
System.out.println(lib);
lib.sort();
System.out.println(lib);
}
private static ArrayList<String> getAuthors(String authors) {
ArrayList books = new ArrayList<String>();
// need help here.
return books;
}
}
try this
private static ArrayList<String> getAuthors(String authors) {
ArrayList books = new ArrayList<String>();
String[] splitStr = authors.split("\\*");
for (int i=0;i<splitStr.length;i++) {
books.add(splitStr[i]);
}
return books;
}
What I would suggest is to use String.split like here (but keep in mind that this method uses a regex as parameter):
private static ArrayList<String> getAuthors(String authors) {
ArrayList books = new ArrayList<String>();
String[] strgArray = authors.split("\\*");
books.addAll(Arrays.asList(strgArray));
return books;
}
or
private static ArrayList<String> getAuthors(String authors) {
String[] strgArray = authors.split("\\*");
ArrayList books = Arrays.asList(strgArray);
return books;
}
Try this one but actually i do not understant why you remove zero indexed element of ArrayList in for loop.
private static ArrayList<String> getAuthors(String authors) {
ArrayList<String> array = new ArrayList<String>();
String[] authorsArray = authors.split("\\*");
for(String names : authorsArray );
array.add(names);
return array;
}
Take a look at String#split method, this will help you to separate authors by asterisk. This method returns an array so you will need to check how many authors are in this array and then store each of them into the ArrayList.
Here's how you can go about doing it.
Split the authors string you're getting as the method param based on the asterisk symbol. (Using String.split(delim) method)
The resultant string[] array needs to be iterated over using a for loop and each iterated element should be added to your list. (Using List.add(elem) method)
Once done, return that list(you are already doin that).
Now that you know how to do it, you need to implement the code by yourself.
Related
I would like to compare two arrays. I have the following
ArrayList<String> time_durations = new ArrayList<String>();
time_durations.add("1200-1304")
time_durations.add("6-7")
Then the other array has the following structure
ArratList<FetchedData> apiresult = new ArrayList<FetchedData>();
apiresult.add(new FetchedData("1200-1304", //an array of data))
The class fetched data has
class FetchedData{
private String duration_range;
private ArrayList data;
//then setters and getters
//and also a constructor
}
So i want to compare the two arrays and get all items contained in time_durations but not in apiresult
Samples of them both in a json format is
time_durations = ["1200-1304", "6-7"]
apiresult = [{duration_range:"1200-1304", data:["item1", "item 2"]}
So by comparison i expect it to return the item in array time_durations6-7 that is index 1
So i have tried
if (Arrays.equals(time_durations, apiresult)) {
//this throws an error
}
But the above attempt doesnt work and am stuck.How do i achieve this?
I have checked on This question but still fails
Your code doesn't work as you expected because the first ArrayList is an array of String and the second is an Array of FetchedData. You basically try to compare two ArrayList of different type and this return false by default.
If you want to reach the goals you must map the ArrayList of FetchedData into an ArrayList of String and with Java8 it is possible to do this with a Map function and after you are enable to comparing the two array
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static java.util.stream.Collectors.toList;
import static org.junit.Assert.assertArrayEquals;
public class TestClass {
#Test
public void arrayListComparation(){
List<String> expected = Arrays.asList("6-7");
ArrayList<String> time_durations = new ArrayList<String>();
time_durations.add("1200-1304");
time_durations.add("6-7");
ArrayList<FetchedData> apiresult = new ArrayList<>();
List<String> data = Arrays.asList("item1","item2");
apiresult.add(new FetchedData("1200-1304", data));
List<String> apiResultDurationRanges = apiresult.stream().map(FetchedData::getDuration_range).collect(toList());
time_durations.removeAll(apiResultDurationRanges);
assertArrayEquals(time_durations.toArray(),expected.toArray());
}
}
In this example you have on time_durations all element that not appear into apiResult
Iterate over the API results, get each duration and put them into a set. Remove the elements of the set from the list.
Set<String> apiDurations = apiresult.stream()
.map(FetchedData::getDuration)
.collect(Collectors.toSet());
time_durations.removeAll(apiDurations);
You can use Collection.removeAll:
List<String> apiResult_durations = apiresult.stream()
.map(FetchedData::getDuration_range)
.collect(Collectors.toList());
time_durations.removeAll(apiResult_durations);
After this code, time_durations is only [6-7]
Important to note that this will modify time_durations inline.
If you'd rather not modify it inline, then you can make a copy:
List<String> time_durations_copy = new ArrayList<>(time_durations);
time_durations_copy.removeAll(apiResult_durations);
I think you need the operation of set difference.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> time_durations = new ArrayList<String>();//The list with some elements
ArrayList<String> otherList = new ArrayList<String>();//Another list
ArrayList<String> difference = new ArrayList<String>();//The result
time_durations.add("1200-1304");//Add some data
time_durations.add("6-7");
otherList.add("1200-1304");
for (int i = 0; i < time_durations.size(); i++) {
if (!otherList.contains(time_durations.get(i))) {
difference.add(time_durations.get(i)); // get all items contained in time_durations but not in apiresult
}
}
for (String string : difference) {
System.out.println(string);
}
}
}
I have defined a few ArrayLists that are already populated. I have the names of all of the ones I want to iterate through in an array 'tagArrays'. Is it possible to iterate through each of them in a similar logic to mine. I know this code is not going to work however I'm not sure how the code is supposed to look. This is my attempt:
These are already populated and are defined in main method.
ArrayList<String> KEYWORDS = new ArrayList<String>();
ArrayList<String> CUSTOMERS = new ArrayList<String>();
ArrayList<String> SYSTEM_DEPS = new ArrayList<String>();
ArrayList<String> MODULES = new ArrayList<String>();
ArrayList<String> DRIVE_DEFS = new ArrayList<String>();
ArrayList<String> PROCESS_IDS = new ArrayList<String>();
This is the logic I'm using
public void genericForEachLoop(POITextExtractor te) {
final String[] tagArrays = {"KEYWORDS", "CUSTOMERS", "SYSTEM_DEPS", "MODULES", "DRIVE_DEFS", "PROCESS_IDS"};
ArrayList<String> al = new ArrayList<String>();
for(int i=0; i<tagArrays.length; i++) {
System.out.println(tagArrays[i]);
al = tagArrays[i];
for (String item : al) {
if (te.getText().contains(item)) {
System.out.println(item);
}
}
}
}
I want the for each loop to be different every time e.g. once go through KEYWORDS, then go through CUSTOMERS etc.
You cannot reference variables with string values in Java.
What you try to do could be performed with reflection.
But I don't encourage it : it is less readable, more brittle/error prone and slower as the "classical" way.
As alternative you can provide a varargs of List<String> as last parameter of the method:
public void genericForEachLoop(POITextExtractor te, String[] tagArrays, List<String>... lists ) {
int i = 0;
for(List<String> list : lists) {
System.out.println(tagArrays[i]);
for (String item : list) {
if (te.getText().contains(item)) {
System.out.println(item);
}
}
i++;
}
}
And invoke it in this way :
genericForEachLoop(te,
new String[]{"KEYWORDS", "CUSTOMERS", "SYSTEM_DEPS", "MODULES", "DRIVE_DEFS", "PROCESS_IDS"},
KEYWORDS, CUSTOMERS,SYSTEM_DEPS,MODULES,DRIVE_DEFS,PROCESS_IDS);
I have tried following things with respect to Java 8. Below is the working example of your code, I have modified some of the code. Please check.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainClass {
public static void main(String... args) {
String[] strings = {"KEYWORDS", "CUSTOMERS", "SYSTEM_DEPS", "MODULES", "DRIVE_DEFS", "PROCESS_IDS"};
ArrayList<String> KEYWORDS = new ArrayList<String>();
KEYWORDS.add("goto");
ArrayList<String> CUSTOMERS = new ArrayList<String>();
CUSTOMERS.add("Royal Lotus");
ArrayList<String> SYSTEM_DEPS = new ArrayList<String>();
SYSTEM_DEPS.add("MAC BOOK");
ArrayList<String> MODULES = new ArrayList<String>();
MODULES.add("TETS MODULE");
ArrayList<String> DRIVE_DEFS = new ArrayList<String>();
DRIVE_DEFS.add("TEST DRIVE");
ArrayList<String> PROCESS_IDS = new ArrayList<String>();
PROCESS_IDS.add("-15153213");
Map<String, List<String>> mapOfLists = new HashMap<>();
mapOfLists.put("KEYWORDS", KEYWORDS);
mapOfLists.put("CUSTOMERS", CUSTOMERS);
mapOfLists.put("SYSTEM_DEPS", SYSTEM_DEPS);
mapOfLists.put("DRIVE_DEFS", DRIVE_DEFS);
mapOfLists.put("PROCESS_IDS", PROCESS_IDS);
mapOfLists.put("MODULES", MODULES);
genericForEachLoop(mapOfLists, strings);
}
public static void genericForEachLoop(Map<String, List<String>> mapOfLists, String[] listsToIterate) {
Arrays.stream(listsToIterate).forEach((listName -> mapOfLists.get(listName).stream().forEach(str -> System.out.println(str))));
}
}
I have taken out the String[] and providing it as an input to method so I can change it. Only those arrays where I want to iterate I can pass them. Further more building on top of #Eran's answer I am using the Map<String, List<String> for storing all the available ArrayLists.
Please modify the code as per your need. I have tried to use the streams and foreach methods from Java8.
Rather creating String array you can create Array of ArrayList, which will help you to iterate dynamically like below.
public static void main(String[] args)
{
ArrayList<String> KEYWORDS = new ArrayList<String>();
ArrayList<String> CUSTOMERS = new ArrayList<String>();
ArrayList<String> SYSTEM_DEPS = new ArrayList<String>();
ArrayList<String> MODULES = new ArrayList<String>();
ArrayList<String> DRIVE_DEFS = new ArrayList<String>();
ArrayList<String> PROCESS_IDS = new ArrayList<String>();
final String[] tagNames = {"KEYWORDS", "CUSTOMERS", "SYSTEM_DEPS", "MODULES", "DRIVE_DEFS", "PROCESS_IDS"};
final List<String> tagNameList=Arrays.asList(tagNames);
final ArrayList[] tagList = { KEYWORDS, CUSTOMERS, SYSTEM_DEPS, MODULES, DRIVE_DEFS, PROCESS_IDS };
for (ArrayList<String> list : tagList) {
for(String str :list){
if(str.contains(""))
{
}
}
}
How can I combine the following two string[] arrays into a two dimensional ArrayList?
private String[] titles = {
"Apple", "Orange", "Banana"};
private String[] details = {
"Red Fruit", "Orange Citrus Fruit", "Yellow Fruit"};
//In reality, these data sets are full.
It needs to fit in a wrapper class. The methods need to look like this, in order to be compatible with the other classes.
private ArrayList<DataObject> getDataSet() {
ArrayList results = new ArrayList<>();
return results; //Just a rough view of the class.
}
The output should be two-dimensional ArrayList with String[] titles at the 1st dimension and String[] details at the 2nd one.
Essentially
results.add("Apple", "Red Fruit");
and do it for all the items in titles and details.
If we go to the way of your provided sample then this should do.
private ArrayList<DataObject> mess() {
ArrayList results = new ArrayList<>();
for (int index = 0; index < titles.length; index++) {
DataObject obj = new DataObject(titles[index],
details[index]);
results.add(index, obj);
}
return results;
}
Note that, if these two arrays(titles and details) of yours have different length then this won't work.
You can achive by using below lines of code
ArrayList<String> a = new ArrayList<>();
a.addAll(Arrays.asList(titles));
a.addAll(Arrays.asList(details));
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, ...);
In my String, I can have an arbitrary number of words which are comma separated. I wanted each word added into an ArrayList. E.g.:
String s = "a,b,c,d,e,.........";
Try something like
List<String> myList = new ArrayList<String>(Arrays.asList(s.split(",")));
Arrays.asList documentation
String.split documentation
ArrayList(Collection) constructor documentation
Demo:
String s = "lorem,ipsum,dolor,sit,amet";
List<String> myList = new ArrayList<String>(Arrays.asList(s.split(",")));
System.out.println(myList); // prints [lorem, ipsum, dolor, sit, amet]
This post has been rewritten as an article here.
String s1="[a,b,c,d]";
String replace = s1.replace("[","");
System.out.println(replace);
String replace1 = replace.replace("]","");
System.out.println(replace1);
List<String> myList = new ArrayList<String>(Arrays.asList(replace1.split(",")));
System.out.println(myList.toString());
In Java 9, using List#of, which is an Immutable List Static Factory Methods, become more simpler.
String s = "a,b,c,d,e,.........";
List<String> lst = List.of(s.split(","));
Option1:
List<String> list = Arrays.asList("hello");
Option2:
List<String> list = new ArrayList<String>(Arrays.asList("hello"));
In my opinion, Option1 is better because
we can reduce the number of ArrayList objects being created from 2 to 1. asList method creates and returns an ArrayList Object.
its performance is much better (but it returns a fixed-size list).
Please refer to the documentation here
Easier to understand is like this:
String s = "a,b,c,d,e";
String[] sArr = s.split(",");
List<String> sList = Arrays.asList(sArr);
Ok i'm going to extend on the answers here since a lot of the people who come here want to split the string by a whitespace. This is how it's done:
List<String> List = new ArrayList<String>(Arrays.asList(s.split("\\s+")));
If you are importing or you have an array (of type string) in your code and you have to convert it into arraylist (offcourse string) then use of collections is better. like this:
String array1[] = getIntent().getExtras().getStringArray("key1"); or String array1[] = ... then
List allEds = new ArrayList(); Collections.addAll(allEds, array1);
You could use:
List<String> tokens = Arrays.stream(s.split("\\s+")).collect(Collectors.toList());
You should ask yourself if you really need the ArrayList in the first place. Very often, you're going to filter the list based on additional criteria, for which a Stream is perfect. You may want a set; you may want to filter them by means of another regular expression, etc. Java 8 provides this very useful extension, by the way, which will work on any CharSequence: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#splitAsStream-java.lang.CharSequence-. Since you don't need the array at all, avoid creating it thus:
// This will presumably be a static final field somewhere.
Pattern splitter = Pattern.compile("\\s+");
// ...
String untokenized = reader.readLine();
Stream<String> tokens = splitter.splitAsStream(untokenized);
If you want to convert a string into a ArrayList try this:
public ArrayList<Character> convertStringToArraylist(String str) {
ArrayList<Character> charList = new ArrayList<Character>();
for(int i = 0; i<str.length();i++){
charList.add(str.charAt(i));
}
return charList;
}
But i see a string array in your example, so if you wanted to convert a string array into ArrayList use this:
public static ArrayList<String> convertStringArrayToArraylist(String[] strArr){
ArrayList<String> stringList = new ArrayList<String>();
for (String s : strArr) {
stringList.add(s);
}
return stringList;
}
Let's take a question : Reverse a String. I shall do this using stream().collect(). But first I shall change the string into an ArrayList .
public class StringReverse1 {
public static void main(String[] args) {
String a = "Gini Gina Proti";
List<String> list = new ArrayList<String>(Arrays.asList(a.split("")));
list.stream()
.collect(Collectors.toCollection( LinkedList :: new ))
.descendingIterator()
.forEachRemaining(System.out::println);
}}
/*
The output :
i
t
o
r
P
a
n
i
G
i
n
i
G
*/
This is using Gson in Kotlin
val listString = "[uno,dos,tres,cuatro,cinco]"
val gson = Gson()
val lista = gson.fromJson(listString , Array<String>::class.java).toList()
Log.e("GSON", lista[0])
I recommend use the StringTokenizer, is very efficient
List<String> list = new ArrayList<>();
StringTokenizer token = new StringTokenizer(value, LIST_SEPARATOR);
while (token.hasMoreTokens()) {
list.add(token.nextToken());
}
If you're using guava (and you should be, see effective java item #15):
ImmutableList<String> list = ImmutableList.copyOf(s.split(","));