How can I instantiate multiple objects into a list? - java

I need to instantiate a list with multiple String objects. I am not allowed to manually add objects 1 by 1.
I tried multiple ways, cannot get method to accept it.
scrambleOrRemove(["TAN", "ABRACADABRA", "WHOA", "APPLE", "EGGS"]);
Method:
public static void scrambleOrRemove(List<String> list)
{
int length = list.size()-1;
for(int i=0;i<length;i++)
{
String otherword = list.get(i);
if(scrambleWord(otherword).equals(otherword))
{
list.remove(i);
}
}
System.out.println(list);
}

Call it like this:
scrambleOrRemove(
new ArrayList<String>(
Arrays.asList(
"TAN", "ABRACADABRA", "WHOA", "APPLE", "EGGS"
)
)
);
Now that you have your solution, read the manuals and explain why this works and why it was necessary for your case.

You can use java.util.Arrays.asList() method. So for your example -
Arrays.asList({"TAN", "ABRACADABRA", "WHOA", "APPLE", "EGGS"});
Perhaps not relevant to your example as you are removing elements from your list later but you can also look into ImmutableList of Guava for doing this in general - https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/ImmutableList.html
ImmutableList.of("TAN", "ABRACADABRA", "WHOA", "APPLE", "EGGS");

Related

why is everything getting removed from my arraylist?

I'm trying to answer this question:
Program the method findIngredients. This method takes in a String called
foodInStock, and an ArrayList of Strings called ingredients. The method should return an
ArrayList of ingredients that were not found in foodInStock.
for example if:
foodInStock = “tomatopotatocornturkeycarrotstuffing”
ingredients = {“potato”, “corn”, “salt”, “chicken”, “turkey”}
returns {“salt”, “chicken”}
I tried writing some code but for some reason everything is getting removed when I use the above example on my program. Where did my program go wrong?
Here's my code:
public static ArrayList<String> findIngredients(String foodInStock, ArrayList<String> ingredients){
ArrayList<String> ingredientsNotFound = new ArrayList<String>();
int i = 0;
for (; i < ingredients.size(); i++) {
for (int x = 0; x < foodInStock.length()-(ingredients.get(i).length())+1; x++) {
if (ingredients.get(i) == foodInStock.substring(x, (x + ingredients.get(i).length()))) {
ingredients.remove(i);
i = 0;
break;
}
}
}
ingredients = ingredientsNotFound;
return ingredientsNotFound;
}
I think there are two main things to cover here.
First, the way to build the final result. You are currently removing items from the original input; a better strategy is to add items to a new list (partially because it's simpler to think about and partially because you generally don't want to modify a list while iterating over it).
You also are, probably accidentally, overwriting your list with an empty list at the end.
Second, the way to determine whether or not the ingredient is in the string input. Rather than looping over the whole string and inspecting substrings, you can instead use the indexOf() method to see whether or not the string includes the current item.
public static ArrayList<String> findIngredients(String foodInStock, ArrayList<String> ingredients) {
ArrayList<String> results = new ArrayList<>();
for (String ingredient : ingredients) {
if (foodInStock.indexOf(ingredient) == -1) {
results.add(ingredient);
}
}
return results;
}
Here we initialize a new list for the results. We then loop over every individual ingredient in the input list, and ask whether or not that ingredient is present in the string input. When it is not (indexOf() returns -1), we add it to the results list. At the end, the results contains every ingredient not found.

Finding the max of a list of arrays using custom comparator

I have a Breakfast class that looks like this:
class Breakfast {
String[] fruits;
...
// Getter and Setter here
...
}
The fruits field will always be a size two array containing one of three possible values: {"apple", "pear"} , {"apple", "grape"}, {"pear", "grape"}
I have designed a custom order for the three values, like this:
String[] orderOne = {"apple", "pear"};
String[] orderTwo = {"apple", "grape"};
String[] orderThree = {"pear", "grape"};
And I wrote my own custom comparator:
List<String[]> breakfastOrder = Arrays.asList(orderOne, orderTwo, orderThree);
Comparator<Breakfast> orderComparator = Comparator.comparing(b -> breakfastOrder.indexOf(new String[] {breakfast.getFruits()[0], breakfast.getFruits()[1]});
When working with a list of Breakfast objects, I am hoping to find the "Max" fruit combination.
In other words, if {"pear", "grape"} is found, {"pear", "grape"} would be the "Max". If {"pear", "grape"} is not found, but {"apple", "grape"} is found, {"apple", "grape"} would be the max.
How do I find the "Max" when I have a list of Breakfast objects? The stream has a max function, could I use it with my custom comparator?
I was thinking something like this:
List<Breakfast> bList = //initialize the list
String[] max = bList.stream.max(orderComparator).get().getFruits();
Please let me know if any part has changed in Java 11. Also, please let me know if there anything wrong with my code or if my logic/implementation is flawed.
If you can override equals/hashCode for Breakfast, simplified here (don't write equals like this):
#Override
public int hashCode() {
return Arrays.hashCode(fruits);
}
#Override
public boolean equals(Object other) {
Breakfast b = (Breakfast) other;
return Arrays.equals(b.getFruits(), getFruits());
}
You could create a Map and keep indexes (you can think about it as a Comparator strength if you want):
Map<Breakfast, Integer> MAP = ImmutableMap.of(
new Breakfast(new String[]{"pear", "grape"}), 1,
new Breakfast(new String[]{"apple", "grape"}), 2,
new Breakfast(new String[]{"apple", "pear"}), 3);
And sorting them via:
Breakfast max = Collections.max(
yourListOfGrapes,
Comparator.comparingInt(b -> Optional.ofNullable(MAP.get(b)).orElse(0))
.reversed());
Because you are manually defining the order/priority of the pair. You can make your job easier by adding order# in the String array to make it of 3 elements size.
Now you can sort/max/min with the 3rd member of the array.
String[] orderOne = { "apple", "pear", "1" };
String[] orderTwo = { "apple", "grape", "2" };
String[] orderThree = { "pear", "grape", "3" };
List<String[]> bList = Arrays.asList(orderOne, orderTwo, orderThree);
String[] max = bList.stream().max((a, b) -> a[2].compareTo(b[2])).get();
System.out.println(Arrays.toString(max));

Check if List <String> contains substring

I'm developing an Android app where I get a List of names (Strings) from a SQLite database. Then, I show them on a List of Cardviews.
I'm also given a substring, so I'd like to check if any of the elements of the original List contains that substring on it.
I'm having problems using LIKE in the SQLite query, so I've just fixed it with a try{ } catch (Exception e) { }, but I don't feel so comfortable with it.
Anyway, since I originally have all of the names stored in the List of Strings, I don't really need to fecth the new ones again from the database, I can just search them on the original List of Strings. But I don't know how.
For example, let's say the List of String has this 5 elements:
Hello
Wall
Helicopter
Chair
Hell
And I'm given the substring Hel. I should get the Hello, Helicopter and Hell strings, since all of them contain the substring Hel.
Any ideas on how to achieve this goal?
It's not that I want to fix it this way. I sincerely would like to know what's the most efficient, if retrieveing the data again from the database, or search it from the List of Strings.
EDIT: I originally said that I was using the CONTAINS query, but I missed the word. I just meant the LIKE query. I'm actually using it, and it works fine but I don't really know what's the most efficient in my case.
Thanks in advance.
Here is my suggestion
public boolean isSubstring(String str, String key) {
if(key.length() > str.length()) return false;
for(int i = 0; i <= str.length() - key.length(); i++) {
if( key.equals(str.substring(i, i + key.length())) ) return true;
}
return false;
}
public List<String> findStings(List<String> list, String key) {
List<String> newList = new ArrayList<>();
for(int i = 0; i < list.size(); i++) {
if(isSubstring(list.get(i), key)) {
newList.add(list.get(i));
}
}
return newList;
}
If you are working with Java 8 you can replace the for-loop of the second method as:
for(String str: list) {
if(isSubstring(str, key)) newList.add(str);
}
or simply as:
list.stream().filter((str) -> (isSubstring(str, key))).forEach((str) -> { newList.add(str); });
If you're using Java 8:
List<String> filteredList = myList.stream().filter(s -> s.contains("Hel")).collect(Collectors.toList());
If you're using anything earlier, use a for each loop:
List<String> filteredList = new ArrayList<String>();
for(String s : myList)
if(s.contains("Hel")
filteredList.add(s);

Java Compare Two Lists

I have two lists ( not java lists, you can say two columns)
For example
**List 1** **Lists 2**
milan hafil
dingo iga
iga dingo
elpha binga
hafil mike
meat dingo
milan
elpha
meat
iga
neeta.peeta
I'd like a method that returns how many elements are same. For this example it should be
3 and it should return me similar values of both list and different values too.
Should I use hashmap if yes then what method to get my result?
Please help
P.S: It is not a school assignment :) So if you just guide me it will be enough
EDIT
Here are two versions. One using ArrayList and other using HashSet
Compare them and create your own version from this, until you get what you need.
This should be enough to cover the:
P.S: It is not a school assignment :) So if you just guide me it will be enough
part of your question.
continuing with the original answer:
You may use a java.util.Collection and/or java.util.ArrayList for that.
The retainAll method does the following:
Retains only the elements in this collection that are contained in the specified collection
see this sample:
import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
public class Repeated {
public static void main( String [] args ) {
Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));
listOne.retainAll( listTwo );
System.out.println( listOne );
}
}
EDIT
For the second part ( similar values ) you may use the removeAll method:
Removes all of this collection's elements that are also contained in the specified collection.
This second version gives you also the similar values and handles repeated ( by discarding them).
This time the Collection could be a Set instead of a List ( the difference is, the Set doesn't allow repeated values )
import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;
class Repeated {
public static void main( String [] args ) {
Collection<String> listOne = Arrays.asList("milan","iga",
"dingo","iga",
"elpha","iga",
"hafil","iga",
"meat","iga",
"neeta.peeta","iga");
Collection<String> listTwo = Arrays.asList("hafil",
"iga",
"binga",
"mike",
"dingo","dingo","dingo");
Collection<String> similar = new HashSet<String>( listOne );
Collection<String> different = new HashSet<String>();
different.addAll( listOne );
different.addAll( listTwo );
similar.retainAll( listTwo );
different.removeAll( similar );
System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different);
}
}
Output:
$ java Repeated
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga]
Two:[hafil, iga, binga, mike, dingo, dingo, dingo]
Similar:[dingo, iga, hafil]
Different:[mike, binga, milan, meat, elpha, neeta.peeta]
If it doesn't do exactly what you need, it gives you a good start so you can handle from here.
Question for the reader: How would you include all the repeated values?
You can try intersection() and subtract() methods from CollectionUtils.
intersection() method gives you a collection containing common elements and the subtract() method gives you all the uncommon ones.
They should also take care of similar elements
If you are looking for a handy way to test the equality of two collections, you can use org.apache.commons.collections.CollectionUtils.isEqualCollection, which compares two collections regardless of the ordering.
Are these really lists (ordered, with duplicates), or are they sets (unordered, no duplicates)?
Because if it's the latter, then you can use, say, a java.util.HashSet<E> and do this in expected linear time using the convenient retainAll.
List<String> list1 = Arrays.asList(
"milan", "milan", "iga", "dingo", "milan"
);
List<String> list2 = Arrays.asList(
"hafil", "milan", "dingo", "meat"
);
// intersection as set
Set<String> intersect = new HashSet<String>(list1);
intersect.retainAll(list2);
System.out.println(intersect.size()); // prints "2"
System.out.println(intersect); // prints "[milan, dingo]"
// intersection/union as list
List<String> intersectList = new ArrayList<String>();
intersectList.addAll(list1);
intersectList.addAll(list2);
intersectList.retainAll(intersect);
System.out.println(intersectList);
// prints "[milan, milan, dingo, milan, milan, dingo]"
// original lists are structurally unmodified
System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]"
System.out.println(list2); // prints "[hafil, milan, dingo, meat]"
Of all the approaches, I find using org.apache.commons.collections.CollectionUtils#isEqualCollection is the best approach. Here are the reasons -
I don't have to declare any additional list/set myself
I am not mutating the input lists
It's very efficient. It checks the equality in O(N) complexity.
If it's not possible to have apache.commons.collections as a dependency, I would recommend to implement the algorithm it follows to check equality of the list because of it's efficiency.
Using java 8 removeIf
public int getSimilarItems(){
List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
int initial = two.size();
two.removeIf(one::contains);
return initial - two.size();
}
Simple solution :-
List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "d", "c"));
List<String> list2 = new ArrayList<String>(Arrays.asList("b", "f", "c"));
list.retainAll(list2);
list2.removeAll(list);
System.out.println("similiar " + list);
System.out.println("different " + list2);
Output :-
similiar [b, c]
different [f]
Assuming hash1 and hash2
List< String > sames = whatever
List< String > diffs = whatever
int count = 0;
for( String key : hash1.keySet() )
{
if( hash2.containsKey( key ) )
{
sames.add( key );
}
else
{
diffs.add( key );
}
}
//sames.size() contains the number of similar elements.
I found a very basic example of List comparison at List Compare
This example verifies the size first and then checks the availability of the particular element of one list in another.
public static boolean compareList(List ls1, List ls2){
return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false;
}
public static void main(String[] args) {
ArrayList<String> one = new ArrayList<String>();
one.add("one");
one.add("two");
one.add("six");
ArrayList<String> two = new ArrayList<String>();
two.add("one");
two.add("six");
two.add("two");
System.out.println("Output1 :: " + compareList(one, two));
two.add("ten");
System.out.println("Output2 :: " + compareList(one, two));
}
protected <T> boolean equals(List<T> list1, List<T> list2) {
if (list1 == list2) {
return true;
}
if (list1 == null || list2 == null || list1.size() != list2.size()) {
return false;
}
// to prevent wrong results on {a,a,a} and {a,b,c}
// iterate over list1 and then list2
return list1.stream()
.filter(val -> !list2.contains(val))
.collect(Collectors.toList())
.isEmpty() &&
list2.stream()
.filter(val -> !list1.contains(val))
.collect(Collectors.toList())
.isEmpty();
}

Python-like list comprehension in Java

Since Java doesn't allow passing methods as parameters, what trick do you use to implement Python like list comprehension in Java ?
I have a list (ArrayList) of Strings. I need to transform each element by using a function so that I get another list. I have several functions which take a String as input and return another String as output. How do I make a generic method which can be given the list and the function as parameters so that I can get a list back with each element processed. It is not possible in the literal sense, but what trick should I use ?
The other option is to write a new function for each smaller String-processing function which simply loops over the entire list, which is kinda not so cool.
In Java 8 you can use method references:
List<String> list = ...;
list.replaceAll(String::toUpperCase);
Or, if you want to create a new list instance:
List<String> upper = list.stream().map(String::toUpperCase).collect(Collectors.toList());
Basically, you create a Function interface:
public interface Func<In, Out> {
public Out apply(In in);
}
and then pass in an anonymous subclass to your method.
Your method could either apply the function to each element in-place:
public static <T> void applyToListInPlace(List<T> list, Func<T, T> f) {
ListIterator<T> itr = list.listIterator();
while (itr.hasNext()) {
T output = f.apply(itr.next());
itr.set(output);
}
}
// ...
List<String> myList = ...;
applyToListInPlace(myList, new Func<String, String>() {
public String apply(String in) {
return in.toLowerCase();
}
});
or create a new List (basically creating a mapping from the input list to the output list):
public static <In, Out> List<Out> map(List<In> in, Func<In, Out> f) {
List<Out> out = new ArrayList<Out>(in.size());
for (In inObj : in) {
out.add(f.apply(inObj));
}
return out;
}
// ...
List<String> myList = ...;
List<String> lowerCased = map(myList, new Func<String, String>() {
public String apply(String in) {
return in.toLowerCase();
}
});
Which one is preferable depends on your use case. If your list is extremely large, the in-place solution may be the only viable one; if you wish to apply many different functions to the same original list to make many derivative lists, you will want the map version.
The Google Collections library has lots of classes for working with collections and iterators at a much higher level than plain Java supports, and in a functional manner (filter, map, fold, etc.). It defines Function and Predicate interfaces and methods that use them to process collections so that you don't have to. It also has convenience functions that make dealing with Java generics less arduous.
I also use Hamcrest** for filtering collections.
The two libraries are easy to combine with adapter classes.
** Declaration of interest: I co-wrote Hamcrest
Apache Commons CollectionsUtil.transform(Collection, Transformer) is another option.
I'm building this project to write list comprehension in Java, now is a proof of concept in https://github.com/farolfo/list-comprehension-in-java
Examples
// { x | x E {1,2,3,4} ^ x is even }
// gives {2,4}
Predicate<Integer> even = x -> x % 2 == 0;
List<Integer> evens = new ListComprehension<Integer>()
.suchThat(x -> {
x.belongsTo(Arrays.asList(1, 2, 3, 4));
x.is(even);
});
// evens = {2,4};
And if we want to transform the output expression in some way like
// { x * 2 | x E {1,2,3,4} ^ x is even }
// gives {4,8}
List<Integer> duplicated = new ListComprehension<Integer>()
.giveMeAll((Integer x) -> x * 2)
.suchThat(x -> {
x.belongsTo(Arrays.asList(1, 2, 3, 4));
x.is(even);
});
// duplicated = {4,8}
You can use lambdas for the function, like so:
class Comprehension<T> {
/**
*in: List int
*func: Function to do to each entry
*/
public List<T> comp(List<T> in, Function<T, T> func) {
List<T> out = new ArrayList<T>();
for(T o: in) {
out.add(func.apply(o));
}
return out;
}
}
the usage:
List<String> stuff = new ArrayList<String>();
stuff.add("a");
stuff.add("b");
stuff.add("c");
stuff.add("d");
stuff.add("cheese");
List<String> newStuff = new Comprehension<String>().comp(stuff, (a) -> { //The <String> tells the comprehension to return an ArrayList<String>
a.equals("a")? "1":
(a.equals("b")? "2":
(a.equals("c")? "3":
(a.equals("d")? "4": a
)))
});
will return:
["1", "2", "3", "4", "cheese"]
import java.util.Arrays;
class Soft{
public static void main(String[] args){
int[] nums=range(9, 12);
System.out.println(Arrays.toString(nums));
}
static int[] range(int low, int high){
int[] a=new int[high-low];
for(int i=0,j=low;i<high-low;i++,j++){
a[i]=j;
}
return a;
}
}
Hope, that I help you :)

Categories

Resources