Performance issue due to recursivity usage - java

I have a performance issue when I execute my code below. It is using recursive function. For now, it takes me 10670 ms to run it. Can someone help me to improve it? I am using java 8 but as I am not familiar yet with it, I did not implement it with java 8. I red online, it says that java 8 can improve performance but can make performance as well depending of the amount of data you manipulate. Thanks all
public static void RemoveDuplicateData(List<VariableDataGroup> variableDataGroups) {
if (variableDataGroups == null) {
return;
}
for (VariableDataGroup varDataGroup : variableDataGroups) {
RemoveDuplicateData(varDataGroup.getOrDataList());
if (varDataGroup.getAndDataList() != null) {
removeAnyDuplicateAndBlankCodesFromAndDataList(varDataGroup);
}
if (varDataGroup.getNotDataList() != null) {
removeAnyDuplicateAndBlankCodesFromNotDataList(varDataGroup);
}
}
}
private static void removeAnyDuplicateAndBlankCodesFromAndDataList(VariableDataGroup varDataGroup) {
for (int x = (varDataGroup.getAndDataList().size()-1) ; x >= 0; x--) {
if (varDataGroup.getAndDataList().get(x) == null || varDataGroup.getAndDataList().get(x).isEmpty())
{
varDataGroup.getAndDataList().remove(x);
} else {
for (int y = 0; y < x; y++) {
if (varDataGroup.getAndDataList().get(x).equals(varDataGroup.getAndDataList().get(y))) {
varDataGroup.getAndDataList().remove(x);
break;
}
}
}
}
}
private static void removeAnyDuplicateAndBlankCodesFromNotDataList(VariableDataGroup varDataGroup) {
for (int x = (varDataGroup.getNotDataList().size()-1) ; x >= 0; x--) {
if (varDataGroup.getNotDataList().get(x) == null || varDataGroup.getNotDataList().get(x).isEmpty())
{
varDataGroup.getNotDataList().remove(x);
} else {
for (int y = 0; y < x; y++) {
if (varDataGroup.getNotDataList().get(x).equals(varDataGroup.getNotDataList().get(y))) {
varDataGroup.getNotDataList().remove(x);
break;
}
}
}
}
}
public class VariableDataGroup {
private String appearingData = "";
private boolean dataFound ;
private List<String> notDataList = new ArrayList();
private List<String> andDataList = new ArrayList();
private List<VariableGroup> orDataList = new ArrayList();
...
}
Thanks Andy Turner and everyone for your help and advice. Here is what I do then.
private static void removeDuplicateAndEmptyData(VariableDataGroup varDataGroup) {
Set<String> dedupedAndDataSet = new LinkedHashSet<>();
List<String> andDataList = varDataGroup.getAndDataList();
Set<String> dedupedNotDataSet = new LinkedHashSet<>();
List<String> notDataList = varDataGroup.getNotDataList();
for (String s : andDataList) {
if (s != null && !s.isEmpty()) {
dedupedAndDataSet.add(s);
}
}
andDataList.clear();
andDataList.addAll(dedupedAndDataSet);
for (String s : notDataList) {
if (s != null && !s.isEmpty()) {
dedupedNotDataSet.add(s);
}
}
notDataList.clear();
notDataList.addAll(dedupedNotDataSet);
}
public static void RemoveDuplicateData(List<VariableDataGroup> variableDataGroups) {
if (variableDataGroups == null) {
return;
}
for (VariableDataGroup varDataGroup : variableDataGroups) {
RemoveDuplicateData(varDataGroup.getOrDataList());
if (varDataGroup.getAndDataList() != null) {
removeDuplicateAndEmptyData(varDataGroup);
}
if (varDataGroup.getNotDataList() != null) {
removeDuplicateAndEmptyData(varDataGroup);
}
}
}

As I commented above, it is hard to offer much help, as we don't know anything about the amount of data you are processing.
However, you would be well served to use Sets instead of Lists to do your deduplication.
For example, your removeAnyDuplicateAndBlankCodesFromAndDataList could be written like this:
private static void removeAnyDuplicateAndBlankCodesFromAndDataList(VariableDataGroup varDataGroup) {
List<String> list = varDataGroup.getAndDataList();
// Copy the list into the set - this removes duplicates.
Set<String> deduped = new LinkedHashSet<>(list);
// Remove the null and empty string, if they are present.
deduped.remove("");
deduped.remove(null);
// Replace the list contents with those of deduped.
list.clear();
list.addAll(deduped);
}
This simply does a lot less work than with the List: Sets automatically contain no duplicates, and repeatedly removing single elements from an ArrayList is quite inefficient (unless it is at the end).
Note that everything from the // Copy the list into the set comment downwards works on "some list" - so you don't need to duplicate this method for the not list, you can simply change the method to accept the list as the parameter:
private static void removeDuplicates(List<String> list) {
// ...
}
Then invoke like this:
if (varDataGroup.getAndDataList() != null) {
removeDuplicates(varDataGroup.getAndDataList());
}
if (varDataGroup.getNotDataList() != null) {
removeDuplicates(varDataGroup.getNotDataList());
}
(and you could even move the null check into the method, to avoid duplicating that).
Of course, you could also just declare the andDataList as a Set in the first place, then you'd not have to worry about the duplicates (although you would have to somehow filter the null and empty strings).
private Set<String> andDataList = new LinkedHashSet<>();

Related

How to I add a single object into an array

For my project I need to add a Creature into an array of creatures thats created in a room
public class Room
{
String name;
String description;
String state;
Creature [] creatures = new Creature[10];
public Room(String roomName)
{
name = roomName;
}
public String toString()
{
String retValue = "";
for (int i = 0; i < creatures.length; i++) {
retValue = retValue + creatures[i].toString();
}
return retValue;
}
public void addCreature(String creatureName)
{
for (int i = 0; i < creatures.length; i++)
{
if(creatures[i] == null)
{
creatures[i] = new Creature(creatureName);
}
}
}
}
when I do this, it overwrites the entire array, what can I do to add a single creature to the array?
Use break statement.
if(creatures[i] == null)
{
creatures[i] = new Creature(creatureName);
break;
}
Arrays have only a fixed size. When you write new Creatures[10], it means that your creatures array has at maximum 10 elements inside of it.
You can add items in two different ways:
You can copy the array and make it bigger, and then add the item
You can use ArrayList, which is a class which automatically does #1 for you
I would recommend ArrayList:
ArrayList:
List<Creature> creatures = new ArrayList<>();
public void addCreature(String creatureName) {
creatures.add(new Creature(creatureName));
}
Seems you miss one condition in if clause. I guess it should be
if(current == null || current.getCreatureName() == null) {
creatures[i] = new Creature(creatureName);
}

Java - return the key with the longest ArrayList in Hashmap<Class,ArrayList<Class>>

I've been trying to modify the code from top answers from a similar question here, but I can't get it to work for arraylist lengths
Get the keys with the biggest values from a hashmap?
Lets say I have
HashMap<Customer,ArrayList<Call>> outgoingCalls = new HashMap<Customer,ArrayList<Call>>();
When the program runs, it stores every call made in the hashmap. I want to run through this hashmap and return the Customer who has made the most calls. I've been trying to modify this code from the link above but I'm completely lost
Entry<Customer,ArrayList<Call> mostCalls = null;
for(Entry<String,ArrayList<Call> e : outgoingCalls.entrySet()) {
if (mostCalls == null || e.getValue() > mostCalls.getValue()) {
mostCalls = e;
Close, but not quite.
Entry<Customer,ArrayList<Call>> mostCalls = null;
for(Entry<String,ArrayList<Call>> e : outgoingCalls.entrySet()) {
if (mostCalls == null || e.getValue().size() > mostCalls.getValue().size()) {
mostCalls = e;
}
}
You can try this out. You will not need any extra imports.
int maxSize = Integer.MIN_VALUE;
for(Customer e: outgoingCalls.keySet()) {
if (maxSize < outgoingCalls.get(e).size()) {
maxSize = outgoingCalls.get(e).size();
mostCalls = e;
}
}
public class T {
public static void main(String[] args) {
List<Customer> customerList = new ArrayList<Customer>();
customerList.add(new Customer());
Collections.sort(customerList, new Comparator<Customer>() {
#Override
public int compare(Customer c1, Customer c2) {
return c1.callsMadeByCustomer.size() - c2.callsMadeByCustomer.size();
}
});
System.out.println("Most Calls: " + customerList.get(customerList.size() - 1));
}
}
class Customer {
ArrayList<Call> callsMadeByCustomer;
public Customer() {
callsMadeByCustomer = new ArrayList<Call>();
}
}
You can even organise it like this. So now callsMadeByCustomer are inside the customer class.

Java Arrays[] - Assigning Specific Elements in a For Loop to Certain Values

I was attempting to write some code for a program in BlueJ (Java) that lists bags and adds and removes items from those bags, that sort of thing. Then I got stuck in the first class; I couldn't get to add an item to the bag properly as you can notice below in the addItem() method; it keeps adding String s to every null element in the array rather the first encountered. Any help would be tremendously appreciated.
Best wishes & many thanks,
Xenos
public class Bag1 {
private String[] store; // This is an array holding mutlitple strings.
public Bag1(int storageCapacity) {
store = new String[storageCapacity];
} // That was the primitive array constructor.
public boolean isFull() {
boolean full = true;
for(int i = 0; i < store.length; i++) {
if(store[i] == null) {
full = false;
}
}
return full;
} // The method above checks if the bag is full or not, and returns a boolean value on that basis.
public void add(String s) {
for(int i = store.length; i >= 0; i--) {
if(store[i] == null) {
store[i] = s;
}
}
}
}
You should exit the loop after finding the first empty spot :
public void add(String s)
{
for(int i=store.length-1; i>=0; i--) { // note the change in the starting index
if(store[i]==null) {
store[i] = s;
break;
}
}
}

NullPointerException in add() Method

My problem is I created an add() method for my ArrayList.
I get an NullPointerException. How can I implement an add() method in my class as the following code suggests?
here is the code:
public class XY{
private List<DictEntry> dict = new ArrayList<DictEntry>();
public void add(String word, int frequency) {
DictEntry neu = new DictEntry(word, frequency);
if (word == null || frequency == 0) {
return;
}
if (!dict.isEmpty()) {
for (int i = 0; i < dict.size(); i++) {
if (dict.get(i).getWord() == word) {
return;
}
}
}
dict.add(neu);
}
}
You have a null element in your array. dict.get(i).getWord() is like null.getWord()
Without the line number it's thrown on, it's harder to say. But I'd suggest not taking the approach you are, anyhow.
First off: don't reimplement functionality that exists:
public class XY{
private List<DictEntry> dict = new ArrayList<DictEntry>();
public void add(String word, int frequency) {
if (word == null || frequency == 0) {
return;
}
DictEntry neu = new DictEntry(word, frequency);
if (!dict.contains(word)) {
dict.add(word);
}
}
}
Even better, use a structure more appropriate to the problem. You're mapping a word to a count - that's all that you appear to be doing with the DictEntry, here. So why not:
public class XY{
private Map<String, Integer> dict = new HashMap<String, Integer>();
public void add(String word, int frequency) {
dict.put(word, frequency);
}

Compare strings in two different arraylist (JAVA)

This is a pice of my code :
ArrayList<String> Alist= new ArrayList<String>();
ArrayList<String> Blist= new ArrayList<String>();
Alist.add("gsm");
Alist.add("tablet");
Alist.add("pc");
Alist.add("mouse");
Blist.add("gsm");
Blist.add("something");
Blist.add("pc");
Blist.add("something");
so i have two array list i want to compare all items and check if they are not equal and if they are to print out only the items that are not equal.
so i make something like this:
http://postimage.org/image/adxix2i13/
sorry for the image but i have somekind of bug when i post here a for looop.
and the result is :
not equals..:tablet
not equals..:pc
not equals..:mouse
not equals..:gsm
not equals..:tablet
not equals..:pc
not equals..:mouse
not equals..:gsm
not equals..:tablet
not equals..:pc
not equals..:mouse
not equals..:gsm
not equals..:tablet
i want to print only the 2 that are not equal in the example they are gsm and pc
not equals..:gsm
not equals..:pc
Don't use != to compare strings. Use the equals method :
if (! Blist.get(i).equals(Alist.get(j))
But this wouldn't probably fix your algorithmic problem (which isn't clear at all).
If what you want is know what items are the same at the same position, you could use a simple loop :
int sizeOfTheShortestList = Math.min(Alist.size(), Blist.size());
for (int i=0; i<sizeOfTheShortestList; i++) {
if (Blist.get(i).equals(Alist.get(i))) {
System.out.println("Equals..: " + Blist.get(i));
}
}
If you want to get items that are in both lists, use
for (int i = 0; i < Alist.size(); i++) {
if (Blist.contains(Alist.get(i))) {
System.out.println("Equals..: " + Alist.get(i));
}
}
You can use the RemoveAll(Collection c) on one of the lists, if you happen to know if one list always contains them all.
You could use the following code:
ArrayList<String> Alist = new ArrayList<String>();
ArrayList<String> Blist = new ArrayList<String>();
Alist.add("gsm");
Alist.add("tablet");
Alist.add("pc");
Alist.add("mouse");
Blist.add("gsm");
Blist.add("something");
Blist.add("pc");
Blist.add("something");
for (String a : Alist)
{
for (String b : Blist)
{
if (a.equals(b))
{
System.out.println("Equals " + a);
break;
}
}
}
Output is:
Equals gsm
Equals pc
right now your comparing each element to all of the other ones. Do something like
for (int i = 0; i < Alist.size(); i++) {
if (!Alist.get(i).equals(Blist.get(i)) {
// print what you want
}
}
Thats of course assuming both lists have the same length.
Rather than writing code to manually compare list elements you might consider using Apache Commons Collections.
import org.apache.commons.collections.CollectionUtils;
List listA = ...;
List listB = ...;
Collection intersection = CollectionUtils.intersection(listA, listB);
import java.util.HashSet;
public class CheckSet<T> extends HashSet<T>{
#Override
public boolean add(T e) {
if (contains(e)) {
remove(e);
return true;
} else {
return super.add(e);
}
}
}
Add all elements of both of your lists to a CheckSet intance, and at the end it will only contain the ones not equal.
Here is one way:
public static boolean compare(List<String> first, List<String> second) {
if (first==null && second==null) return true;
if (first!=null && second==null) return false;
if (first==null && second!=null) return false;
if ( first.size()!=second.size() ) return false;
HashMap<String, String> map = new HashMap<String, String>();
for (String str : first) {
map.put(str, str);
}
for (String str : second) {
if ( ! map.containsKey(str) ) {
return false;
}
}
return true;
}
public static void main(String args[] ) throws Exception {
List<String> arrayList1 = new ArrayList<String>();
arrayList1.add("a");
arrayList1.add("b");
arrayList1.add("c");
arrayList1.add("d");
List<String> arrayList2 = new ArrayList<String>();
arrayList2.add("a");
arrayList2.add("b");
arrayList2.add("c");
arrayList2.add("d");
boolean isEqual = false;
if(arrayList1.size() == arrayList2.size()){
List<String> arrayListTemp = new ArrayList<String>();
arrayListTemp.addAll(arrayList1);
arrayListTemp.addAll(arrayList2);
HashSet<Object> hashSet = new HashSet<Object>();
hashSet.addAll(arrayListTemp);
if(hashSet.size() == arrayList1.size() &&
hashSet.size() == arrayList2.size()){
isEqual = true;
}
}
System.out.println(isEqual);
}
we can compare two different size arrayList in java or Android as follow.
ArrayList<String> array1 = new ArrayList<String>();
ArrayList<String> array2 = new ArrayList<String>();
array1.add("1");
array1.add("2");
array1.add("3");
array1.add("4");
array1.add("5");
array1.add("6");
array1.add("7");
array1.add("8");
array2.add("1");
array2.add("2");
array2.add("3");
array2.add("4");
for (int i = 0; i < array1.size(); i++) {
for (int j=0;j<array2.size();j++) {
if (array1.get(i) == array2.get(j)) {
//if match do the needful
} else {
// if not match
}
}
}
import java.util.Arrays;
public class ExampleContains {
public static boolean EligibleState(String state){
String[] cities = new String[]{"Washington", "London", "Paris", "NewYork"};
boolean test = Arrays.asList(cities).contains(state)?true:false;
return test;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(EligibleState("London"));
}
}

Categories