Unit Testing Android function - java

I want to unit test a function within my code, but when I try to input a ArrayList into it it gives me array initializer not allowed here
here is my code:
public class CreateActivityTest {
ArrayList<String> items;
public String Add(String item, ArrayList<String> items) {
if (items.contains(item.toLowerCase().trim())) {
return null;
}
else if (item == null || item.trim().equals("")) {
return null;
} else {
return item.toLowerCase().replaceAll("\\s+", "");
}
}
#Test
public void addTest () throws Exception {
items = {"strawberry", "raspberry"};
String input = Add("Strawberry ", items);
String expected = null;
assertEquals(input, expected);
}
}

items = Arrays.asList("strawberry", "raspberry");
Or, if you want exactly arraylist, just
items = new ArrayList<>();
items.add("strawberry");
items.add("raspberry");

Related

Using java streams to compare two lists of objects with fields

I need to compare two list of objects with their field values using streams
for example
List<Object> originalObjectList
List<Object> modifiedObjectList
i need to find differences in objects from two lists at field levels and get list of difference as below
I am trying with this approach
originalObjectList
.stream()
.map(originalObject -> modifiedObjectList
.stream()
.map(modifiedObject -> findDifferences(originalObject.getField1(), modifiedObject.getField1())
.collect(// not understanding how to collect the result returned from findDifferences)
//Method
Result findDifferences(String originalValue, String modifiedValue){
Result result = new Result();
if(StringUtils.isEmpty(originalValue) && StringUtils.isNotEmpty(modifiedValue)){
result.setStatus("ADDED");
result.setValue(modifiedValue);
}
else if(StringUtils.isNotEmpty(originalValue) && StringUtils.isEmpty(modifiedValue)){
result.setStatus("DELETED");
result.setValue(originalValue);
}
else if(!originalValue.equals(modifiedValue)){
result.setStatus("MODIFIED");
result.setValue(modifiedValue);
}
return result;
}
Result should contain value of the field and status of the field like 'Deleted' 'Modified' or 'Added'
Please suggest if there is any better way to achieve this? I am new to java streams
Something like this. Feel free to ask questions.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class App6 {
public static final String ADDED = "ADDED";
public static final String DELETED = "DELETED";
public static final String MODIFIED = "MODIFIED";
public static final String NOT_MODIFIED = "NOT_MODIFIED";
public static void main(String[] args) {
List<A> originalObjectList = Arrays.asList(new A("a"), new A(""), new A("a"), new A("a"));
List<A> modifiedObjectList = Arrays.asList(new A("a"), new A("b"), new A("b"), new A(""));
List<Result> results = IntStream
.range(0, originalObjectList.size())
.mapToObj(i -> {
A original = originalObjectList.get(i);
A modified = modifiedObjectList.get(i);
return compare(original, modified);
})
.collect(Collectors.toList());
System.out.println(results);
}
public static Result compare(A or, A mod) {
if (or == null || mod == null) {
throw new IllegalArgumentException("Comparable objects should not be null");
}
if (or.field == null || mod.field == null) {
throw new IllegalArgumentException("Comparable fields of objects should not be null");
}
if (or.field.equals(mod.field)) {
return new Result(NOT_MODIFIED, or.field);
} else if (or.field.isEmpty() && !mod.field.isEmpty()) {
return new Result(ADDED, mod.field);
} else if (!or.field.isEmpty() && mod.field.isEmpty()) {
return new Result(DELETED, or.field);
} else {
return new Result(MODIFIED, mod.field);
}
}
}
class A {
String field;
public A(String field) {
this.field = field;
}
}
class Result {
String status;
String value;
public Result(String status, String value) {
this.status = status;
this.value = value;
}
#Override
public String toString() {
return "Result{" +
"status='" + status + '\'' +
", value='" + value + '\'' +
'}';
}
}

How to return two values in java from a method

I have a method from which I need to return two values.I m confused as to how can I return two values.
public List<Class1> getCode(Long Code)
{
String Query1="Some Query";
List<Object[]> value = repos.getQuery(Query1);
List<Class1> counts = new ArrayList<>();
if (null != value)
{
Iterator<Object[]> rowItr = value.iterator();
while (rowItr.hasNext())
{
Class1 count = new Class1();
Object[] obj = rowItr.next();
if (null != obj)
{
if (null != obj[0])
{
count.setValuess1(obj[0].toString());
}
if (null != obj[1])
{
count.setValuess2(obj[1].toString());
}
}
counts.add(count);
return (List<Class1>) counts;
}
String Query2="SomeQuery" ;
List<Object[]> value2 = repos.getQuery(Query2);
List<Class2> count1s = new ArrayList<>();
if (null != value2)
{
Iterator<Object[]> rowItr1 = value2.iterator();
while (rowItr.hasNext())
{
Class2 countt = new Class2();
Object[] obj1 = rowItr1.next();
if (null != obj1)
{
if (null != obj1[0])
{
countt.setValuess1(obj1[0].toString());
}
if (null != obj1[1])
{
countt.setValuess2(Long.valueOf(obj1[1].toString()));
}
}
count1s.add(countt);
}
}
return (List<Class2>)count1s;
}
}
This is my Class1
public class1
{
private String valuess1;
private String valuess2;
private List<Class2>class2;
}
This is My Class2
public class Class2
{
private String valuess1;
private Long valuess2;
}
How can I return count1s and counts together .I have tried returning the value by the use of casting but it does not accept it.I have seen quiet a few solutions but none of them has worked for me.Any help would be appreciated.
You can return a Pair.
Pair<List<Class1>,List<Class2>> res = new Pair(counts, count1s);
return res;
Or you can create a class that represents the return values and return it.
public class Res {
public List<Class1> l1;
public List<Class2> l2;
public Res(List<Class1> l1, List<Class2> l2){
this.l1 = l1;
this.l2 = l2;
}
}
Whenever you want to return more than one values, you better return an array holding values you want, so when you call you can initialize the returned array and the loop through it. Hope that helps

how to add object in Arraylist which contains matched items only java

I have two Arraylist one List that is ShoppingList which contains item such as [tea,milk,sugar]
and another List which is my Recipe object ingredients list...So how to add object only in a result list which contains these items ?
The problem is that its add multiple object with contains these items
My code which finds common items in both list :
final List<RecipeN> result = new ArrayList<RecipeN>();
for (RecipeN rn : allrec) {
for (ShoppingList sl : allitems) {
for(int i = 0;i<rn.getIngredient().size();i++) {
if (rn.getIngredients(i).contains(sl.getrName())) {
result.add(rn);
}
}
}
public class RecipeN {
private String recName;
private List<String> ingredient = new ArrayList<String>();
public RecipeN(){
}
public RecipeN(String item){
this.ingredient.add(item);
}
public List<String> getIngredient(){
return ingredient;
}
public String getIngredients(int i){
return ingredient.get(i);
}
public void setIngredient(List<String> item){
this.ingredient = item;
}
public String getRecName() {
return recName;
}
public void setRecName(String recName) {
this.recName = recName;
}
#Override
public String toString() {
return recName;
}
}
Use method retainAll(Collection c) to only keep the items in a shopping list that appears in a recipe. Code example is as below:
List<Item> recipe = new ArrayList<>();
List<Item> shoppingList = new ArrayList<>();
... your code ...
shoppingList.retainAll(recipe);
If you want to have only 1 times each match recipe you should use a HashSet in order to not have duplicate in the list.
final Set<RecipeN> result = new HashSet<RecipeN>();
for (RecipeN rn : allrec) {
for (ShoppingList sl : allitems) {
for(int i = 0;i<rn.getIngredient().size();i++) {
if (rn.getIngredients(i).contains(sl.getrName())) {
result.add(rn);
}
}
}
}
if you want to keep an ArrayList you can do that :
final Set<RecipeN> result = new HashSet<RecipeN>();
for (RecipeN rn : allrec) {
boolean recipeMatched = false;
for (ShoppingList sl : allitems) {
for(int i = 0;i<rn.getIngredient().size();i++) {
if (rn.getIngredients(i).contains(sl.getrName())) {
recipeMatched = true;
result.add(rn);
break;
}
if (recipeMatched)
break;
}
if (recipeMatched)
break;
}
}

Searching for a String in an Array of Objects

I have a Object that contains an ArrayList of self referntial objects. Each Object in that ArrayList contains the same structre upto n degrees. Now i have to search for a string in the structure and if found i have to print all the way up to the root. Here is a sample
MyClass {
string name;
ArrayList<MyClass> subClasses;
}
What data structure would be best to do this. Or do i not need one to use it.
Kind Regards
You could have a method on MyClass like below
public List<String> findPathOfName(String nameToFind) {
List<String> result = new ArrayList<String>();
if (nameToFind.equals(name)) {
result.add(name);
} else {
for (MyClass aSubClass: subClasses) {
List<String> subResult = aSubClass.findPathOfName(nameToFind);
if (!subResult.isEmpty()) {
result.add(name);
result.addAll(subResult);
break;
}
}
}
return result;
}
basically recursively go through the structure and find the path. Returned list would contain the path like personA/personB/etc..
This is http://en.wikipedia.org/wiki/Composite_pattern. Try my version
static class MyClass {
String name;
List<MyClass> subClasses;
MyClass(String name) {
this.name = name;
}
String search(String s, String path) {
if (!path.isEmpty()) {
path += "->";
}
path += name;
if (!s.equals(name)) {
if (subClasses == null) {
return null;
}
for (MyClass c : subClasses) {
return c.search(s, path);
}
}
return path;
}
}
public static void main(String[] args) throws Exception {
MyClass c1 = new MyClass("c1");
MyClass c2 = new MyClass("c2");
MyClass c3 = new MyClass("c3");
c1.subClasses = Arrays.asList(c2);
c2.subClasses = Arrays.asList(c3);
System.out.println(c1.search("c3", ""));
}
output
c1->c2->c3

Can any one explain this strange behavior of java HashMap?

I have used HashMap in Java a lot but has never encountered this behavior. I have to types, Item and ItemGroup. They are defined as shown in the following codes snippets.
public class Item {
String id;
float total;
}
public class ItemGroup {
String keyword;
int frequency;
List<Item> items;
}
So ItemGroup consists of 0..* items. These items have a keyword in common and the keyword appears in the system with some frequency. Now the fun part, I have following method that given a list of items creates a list of groups.
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Process keywords
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
ItemGroup group = groups.get(words[j]);
if (group != null){
group.incrementFrequency();
group.getItems().add(items[i]);
}else {
group = EconomFactory.eINSTANCE.createItemGroup();
group.setKeyword(words[j]);
group.incrementFrequency();
group.getItems().add(items[i]);
groups.put(words[j], group);
}
}
}
return groups.values().toArray(new ItemGroup[0]);
}
The part where it gets strange is when adding the item to an itemgroup (the line group.getItems().add(items[i]);). During rehashing the group loses its items in a strange way. Using Debugging I can see that the group contains the item just after the operation but latter on, e.g. when returning the value of the method, all the groups has lost their items.
I tried this:
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Create a new item based on the current one in the list
Item item = EconomFactory.eINSTANCE.createItem();
item.setId(items[i].getId());
item.setTotal(items[i].getTotal());
// Process key words
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
ItemGroup group = groups.get(words[j]);
if (group != null){
group.incrementFrequency();
group.getItems().add(item);
}else {
group = EconomFactory.eINSTANCE.createItemGroup();
group.setKeyword(words[j]);
group.incrementFrequency();
group.getItems().add(item);
groups.put(words[j], group);
}
}
}
return groups.values().toArray(new ItemGroup[0]);
}
but got the same result. The following solution, however, works just fine.
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Process key words
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
// Create a new item based on the current one in the list
Item item = EconomFactory.eINSTANCE.createItem();
item.setId(items[i].getId());
item.setTotal(items[i].getTotal());
ItemGroup group = groups.get(words[j]);
if (group != null){
group.incrementFrequency();
group.getItems().add(item);
}else {
group = EconomFactory.eINSTANCE.createItemGroup();
group.setKeyword(words[j]);
group.incrementFrequency();
group.getItems().add(item);
groups.put(words[j], group);
}
}
}
return groups.values().toArray(new ItemGroup[0]);
}
The method EconomFactory.eINSTANCE.createItemGroup() is implemented as follow:
public ItemGroup createItemGroup() {
ItemGroupImpl itemGroup = new ItemGroupImpl();
return itemGroup;
}
where ItemGroupImpl is the implementation of ItemGroup, e.i. it subclasses the ItemGroup. It is because I use EMF (Eclipse Modeling Framework).
Can anyone please explain this behavior (why the ItemGroup objects lose their items)?
Here is the codes for ItemGroup and ItemGroupImpl. The same way looks the codes for Item and ItemImpl.
public interface ItemGroup extends EObject {
String getKeyword();
void setKeyword(String value);
int getFrequency();
void setFrequency(int value);
EList<Item> getItems();
void incrementFrequency();
}
public class ItemGroupImpl extends EObjectImpl implements ItemGroup {
protected static final String KEYWORD_EDEFAULT = null;
protected String keyword = KEYWORD_EDEFAULT;
protected static final int FREQUENCY_EDEFAULT = 0;
protected int frequency = FREQUENCY_EDEFAULT;
protected EList<Item> items;
protected ItemGroupImpl() {
super();
}
#Override
protected EClass eStaticClass() {
return EconomPackage.Literals.ITEM_GROUP;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String newKeyword) {
String oldKeyword = keyword;
keyword = newKeyword;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
EconomPackage.ITEM_GROUP__KEYWORD, oldKeyword, keyword));
}
public int getFrequency() {
return frequency;
}
public void setFrequency(int newFrequency) {
int oldFrequency = frequency;
frequency = newFrequency;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
EconomPackage.ITEM_GROUP__FREQUENCY, oldFrequency, frequency));
}
public EList<Item> getItems() {
if (items == null) {
items = new EObjectContainmentEList<Item>(Item.class, this,
EconomPackage.ITEM_GROUP__ITEMS);
}
return items;
}
public void incrementFrequency() {
this.frequency = getFrequency() + 1;
}
#Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID,
NotificationChain msgs) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__ITEMS:
return ((InternalEList<?>)getItems()).basicRemove(otherEnd,
msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
#Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
return getKeyword();
case EconomPackage.ITEM_GROUP__FREQUENCY:
return getFrequency();
case EconomPackage.ITEM_GROUP__ITEMS:
return getItems();
}
return super.eGet(featureID, resolve, coreType);
}
#SuppressWarnings("unchecked")
#Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
setKeyword((String)newValue);
return;
case EconomPackage.ITEM_GROUP__FREQUENCY:
setFrequency((Integer)newValue);
return;
case EconomPackage.ITEM_GROUP__ITEMS:
getItems().clear();
getItems().addAll((Collection<? extends Item>)newValue);
return;
}
super.eSet(featureID, newValue);
}
#Override
public void eUnset(int featureID) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
setKeyword(KEYWORD_EDEFAULT);
return;
case EconomPackage.ITEM_GROUP__FREQUENCY:
setFrequency(FREQUENCY_EDEFAULT);
return;
case EconomPackage.ITEM_GROUP__ITEMS:
getItems().clear();
return;
}
super.eUnset(featureID);
}
#Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
return KEYWORD_EDEFAULT == null ? keyword != null :
!KEYWORD_EDEFAULT.equals(keyword);
case EconomPackage.ITEM_GROUP__FREQUENCY:
return frequency != FREQUENCY_EDEFAULT;
case EconomPackage.ITEM_GROUP__ITEMS:
return items != null && !items.isEmpty();
}
return super.eIsSet(featureID);
}
#Override
public String toString() {
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer();
result.append("(keyword: ");
result.append(keyword);
result.append(", frequency: ");
result.append(frequency);
result.append(')');
return result.toString();
}
}
In your second set of Code, where is I intialized?
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
// Create a new item based on the current one in the list
Item item = EconomFactory.eINSTANCE.createItem();
item.setId(items[i].getId());
item.setTotal(items[i].getTotal());
The variable i has not been initialized in this context, so it could be any value (since its not blowing up, I assume you have a global "i" somehwere else in your code, and you are starting your method with that value instaed of 0.
In your code that is working you have i initialized in the method before you access it :
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Process key words
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
So, that is my guess as to why you are seeing the behavior you are seeing... ALWAYS INITIALIZE VARIABLES BEFORE ACCESSING THEM.
Tell us please what happens in EconomFactory.eINSTANCE.createItemGroup() ? I cannot tell if a unique instance with a unique items List is created each time.
I tried it out with some modifications (I am not currently using Java 6 so can't use String.isEmpty) and assuming regular object creation and it works for me. See below my runnable example (something like which you should post next time you ask a question):
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ItemGrouper {
public static class Item {
String id;
float total;
Item(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
public static class ItemGroup {
String keyword;
int frequency;
List<Item> items = new ArrayList<ItemGrouper.Item>();
public void incrementFrequency() {
frequency++;
}
public List<Item> getItems() {
return items;
}
public void setKeyword(String string) {
keyword = string;
}
#Override
public String toString() {
return String.format("key=%s freq=%s", keyword, frequency);
}
}
public static ItemGroup[] createGroups(Item[] items) {
Map<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i = 0; i < items.length; i++) {
words = items[i].getId().split(" ");
// Process keywords
for (int j = 0; j < words.length; j++) {
if (words[j].length() == 0) {
break;
}
ItemGroup group = groups.get(words[j]);
if (group == null) {
group = new ItemGroup();
group.setKeyword(words[j]);
groups.put(words[j], group);
}
group.incrementFrequency();
group.getItems().add(items[i]);
}
}
return groups.values().toArray(new ItemGroup[0]);
}
public static void main(String[] args) {
Item[] items = new Item[] {new Item("one two"), new Item("two three")};
ItemGroup[] itemgroups = createGroups(items);
System.out.println(Arrays.toString(itemgroups));
}
}
Output:
[key=one freq=1, key=two freq=2, key=three freq=1]

Categories