1

Warnings: These examples are just examples. Not same my code, so don't think it's duplicate or it's bad question and vote down!

This title may be a little confusing sorry for that. Here's my problem;

I have two Arraylist. One of them takes a string and onether one takes integer. Let me illustrate it

arrList1 = {"apple", "strawberry", "banana", "watermelon"};
arrList2 = {   60,        90,         77 ,       160};

arrList2 store how much fruits in arrList1 in same index number. For example there are 60 apples, 90 strawberry, 77 banana, 160 watermelon.

Also I have two more Arraylist like above;

arrList3 = { "strawberry", "watermelon", "apple", "banana" };
arrList4 = {      45,          40 ,         10 ,     11 };

arrList1 and arrList3 have same string but different index number. Now I want to print like by divide arrList2's number by arrList1 number and print objects by amount order. Let me illustrate it;

apple = 60/10 = 6
strawberry = 90/45 = 2
banana =  77/11 = 7
watermelon = 160/40 = 4

We divided and get some numbers and print to console ordered by amounts;

Banana  // first because we got 7 
Apple   // second because we got 6  and etc
Watermelon 
Strawberry

So, how I do it effectively?


To be clear, there are two questions here:

  1. How do I efficiently do the lookup for each fruit in each pair of arrays?
  2. How do I efficiently sort the results of dividing the corresponding entries' values?
DaoWen
  • 32,589
  • 6
  • 74
  • 101
PeerNet
  • 855
  • 1
  • 16
  • 31
  • 1
    can you just make one Object Fruit and have these as properties – jmj Aug 25 '14 at 01:10
  • Maybe I can but redesigning the program takes a lot of time – PeerNet Aug 25 '14 at 01:11
  • 2
    @PeerNet You will get that time back if you design it effectively now, rather than dealing with problems in the future. – starf Aug 25 '14 at 01:13
  • 1
    What have you tried? What didn't work? It looks like you have fruit, divisor and dividend - perhaps you should start there (by the way, Java is an OO language, making an object would be quite natural). Also, get used to giving your variables meaningful names – Romski Aug 25 '14 at 01:14
  • @starf Yes you are right, I just wanted solve quickly. By the way why I got minus point? Did I something wrong? – PeerNet Aug 25 '14 at 01:15
  • @Romski this is tiny part of my code and I just want to illustrate, of course my arraylist far different from them – PeerNet Aug 25 '14 at 01:17
  • I downvoted your question because it has already been asked *so many times*. Also, those are arrays, not `ArrayList`s. – DaoWen Aug 25 '14 at 01:18
  • @DaoWen I do not think sir, I think mines is different also I can ensure you they are arraylist. My examples are so simple because I wanted everyone get it easily. I have huge arraylists and more complicated. – PeerNet Aug 25 '14 at 01:23
  • I see—in that case, thanks for simplifying the example. However, since you used the *array* syntax in your question that makes it look like you're actually using arrays and just don't know the difference (programmers new to Java mix up those terms all too frequently). Now that I've read your question about 5 times I can finally see that you actually have _two_ problems—so you're right, this question is only half-duplicate. Succinctly summarizing your question at the end would ***REALLY*** help. I'm going to edit it for you. – DaoWen Aug 25 '14 at 01:47
  • Ah, shoot. @JarrodRoberson came along and closed your question just before I finished my edit to make your question look less like a duplicate... – DaoWen Aug 25 '14 at 01:50

4 Answers4

3

You appear to have arrays, and not ArrayList(s). Next, you should create a Fruit class that implements Comparable<Fruit>. It should have two fields, an amount and a name. You could then use a Map<String, Integer> to perform your division, and finally build and sort a List of Fruit(s). Something like this,

public class Fruit implements Comparable<Fruit> {
    private final String name;
    private int amount;

    public Fruit(String name, int amount) {
        super();
        this.name = (name != null) ? name.trim() : "";
        setAmount(amount);
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public int getAmount() {
        return amount;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof Fruit) {
            Fruit that = (Fruit) o;
            return this.name.equals(that.name);
        }
        return false;
    }

    @Override
    public String toString() {
        return String.format("%s = %d", name, amount);
    }

    @Override
    public int compareTo(Fruit o) {
        return Integer.valueOf(o.amount).compareTo(amount);
    }

    @Override
    public int hashCode() {
        return this.name.hashCode();
    }

    public static void main(String[] args) {
        String[] arrList1 = { "apple", "strawberry", "banana", "watermelon" };
        int[] arrList2 = { 60, 90, 77, 160 };
        String[] arrList3 = { "strawberry", "watermelon", "apple", "banana" };
        int[] arrList4 = { 45, 40, 10, 11 };
        Map<String, Integer> map = new TreeMap<>();
        for (int i = 0; i < arrList1.length; i++) {
            map.put(arrList1[i], arrList2[i]);
        }
        List<Fruit> al = new ArrayList<>();
        for (int i = 0; i < arrList3.length; i++) {
            String key = arrList3[i];
            int val = map.get(key) / arrList4[i];
            al.add(new Fruit(key, val));
        }
        Collections.sort(al);
        System.out.println(al);
    }
}

Which (when I run it here) outputs,

[banana = 7, apple = 6, watermelon = 4, strawberry = 2]
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
0
public class Main {

    public static void main(String[] args) {

        String[] arrList1 = { "apple", "strawberry", "banana", "watermelon" };
        Integer[] arrList2 = { 60, 90, 77, 160 };

        String[] arrList3 = { "strawberry", "watermelon", "apple", "banana" };
        Integer[] arrList4 = { 45, 40, 10, 11 };

        HashMap<String, Integer> result = new HashMap<>();

        for (int i = 0; i < arrList1.length; i++) {
            for (int j = 0; j < arrList3.length; j++) {
                if (arrList1[i].contains(arrList3[j])) {
                    result.put(arrList1[i], arrList2[i] + arrList4[j]);
                }
            }
        }

        LinkedHashMap sorted = sortHashMap(result);
        Set<String> keys = sorted.keySet();
        for(String k:keys){
            System.out.println(k+" -- "+sorted.get(k));
        }
        System.out.println("End");

    }

    public static LinkedHashMap sortHashMap(HashMap passedMap) {
        List mapKeys = new ArrayList(passedMap.keySet());
        List mapValues = new ArrayList(passedMap.values());
        Collections.sort(mapValues);
        Collections.sort(mapKeys);

        LinkedHashMap sortedMap = new LinkedHashMap();

        Iterator valueIt = mapValues.iterator();
        while (valueIt.hasNext()) {
            Object val = valueIt.next();
            Iterator keyIt = mapKeys.iterator();

            while (keyIt.hasNext()) {
                Object key = keyIt.next();
                String comp1 = passedMap.get(key).toString();
                String comp2 = val.toString();

                if (comp1.equals(comp2)) {
                    passedMap.remove(key);
                    mapKeys.remove(key);
                    sortedMap.put((String) key, (Integer) val);
                    break;
                }

            }

        }
        return sortedMap;
    }

}

That is it, of course is doesn't have the best programming practices. I recommend using generics on it.

Bruno Franco
  • 2,028
  • 11
  • 20
0

You can use maps:

Map<String, Integer> fruit1 = new HashMap<String, Integer>();
Map<String, Integer> fruit2 = new HashMap<String, Integer>();

then:

fruit1.put("apple", 60);
fruit2.put("apple", 10);

And lastly:

System.out.println(fruit1.get("apple")/fruit2.get("apple"));

EDIT: To have it sorted use another map - this time TreeMap which maintains sorted order (be key):

Map<Integer, String> results = new TreeMap<Integer, String>();
results.add(fruit1.get("apple")/fruit2.get("apple"), "apple");
// add more...

Then to print them so they look like you specified in your question:

for(Map.Entry<Integer,String> entry : results.entrySet()) {
    System.out.println(entry.getValue() + ": " + entry.getKey());
}

This will print:

apple: 6
//and so on...
Lucas
  • 3,181
  • 4
  • 26
  • 45
  • Sir I have a lot of elements, I cannot put evey element like that – PeerNet Aug 25 '14 at 01:24
  • I don't think the `.getValue()` is needed since Java automatically unboxes `Integer`s. – DaoWen Aug 25 '14 at 01:25
  • oops that's right. let me update! – Lucas Aug 25 '14 at 01:25
  • @PeerNet you will have to enter your values somehow and trust me: Hash map is much better then several arrays – Lucas Aug 25 '14 at 01:26
  • @PeerNet - Haven't you learned how to use loops yet? – DaoWen Aug 25 '14 at 01:27
  • @DaoWen Are you trolling? If so get out please – PeerNet Aug 25 '14 at 01:35
  • @Lucase You seem to have forgotten to sort here. – Elliott Frisch Aug 25 '14 at 01:40
  • @PeerNet If you're expressing concern about _how_ to put many elements in a `Map`, asking if you know about loops is a reasonable question – jdphenix Aug 25 '14 at 01:40
  • @PeerNet - No, I'm not. That was a serious question. When you say _"Sir I have a lot of elements, I cannot put evey element like that"_, that's just silly because you can do it in one line: `for (int i=0; i< arrList1.size(); i++) fruits1.put(arrList1.get(i), arrList2.get(i));` – DaoWen Aug 25 '14 at 01:40
  • @DaoWen I don't know what elements are. My elements are huge and I don't know that they are, and I just want to illustrate four elements. I wrote warning section in my question. Please read it – PeerNet Aug 25 '14 at 01:44
  • @PeerNet - Did you even read what I wrote? That code only depends on you having access to the lists—nothing else. The whole point is that you don't need to add individual elements statically, but rather have a loop that adds them all dynamically. – DaoWen Aug 25 '14 at 01:57
  • I added sorting (forgot about for some reason), see my edit. – Lucas Aug 25 '14 at 10:24
  • @DaoWen I do not think you understand my problem correctly because I didn't tell clearly because of my english. Anyway let it go – PeerNet Aug 25 '14 at 12:39
0

So, how I do it effectively?

Don't use seperate arrays. Encapsulate the data you need within POJOs (Plain Old Java Objects) and make use of the Collections API

But, without using List or Map, you need to build, at least, two more arrays (or at least I did ;))...

The first will hold the results of the calcaultions. To do this, you need some way to find the matching indexes from arrList1 in arrList3, for example...

This will find the index of the given value in the given array or return -1 if it was not found...

public static int find(String value, String[] list) {

    int matchIndex = -1;
    for (int index = 0; index < list.length; index++) {
        if (list[index].equals(value)) {
            matchIndex = index;
            break;
        }
    }
    return matchIndex;

}

Next, we need to calculate the results ...

int[] results = new int[arrList1.length];
for (int index = 0; index < arrList1.length; index++) {
    String v1 = arrList1[index];
    int v2 = arrList2[index];
    int subIndex = find(v1, arrList3);
    if (subIndex != -1) {
        int v4 = arrList4[subIndex];
        results[index] = (v2 / v4);
        System.out.println(v1 + " = " + v2 + " / " + v4 + " = " + results[index]);
    }
}

This will generate the output of...

apple = 60 / 10 = 6
strawberry = 90 / 45 = 2
banana = 77 / 11 = 7
watermelon = 160 / 40 = 4

And store the results of the calculations in the results array...

Now comes the fun part...We could sort ALL the arrays, but that just seems messy to me, or we could create a "proxy" array whose individual elements pointed to the index in the other arrays. This would represent a "virtual" sorted view of all the arrays...

int[] proxy = new int[arrList1.length];
for (int index = 0; index < proxy.length; index++) {
    proxy[index] = index;
}

for (int n = 0; n < results.length; n++) {
    for (int m = 0; m < results.length - 1 - n; m++) {
        if ((results[proxy[m + 1]] - (results[proxy[m]])) > 0) {
            int index = proxy[m];
            proxy[m] = proxy[m + 1];
            proxy[m + 1] = index;
        }
    }
}

This means that proxy[0] will hold the index of the first item, when sorted.

And if we use this to print the results...

for (int index : proxy) {

    System.out.println(arrList1[index] + " = " + results[index]);

}

We get something like...

banana = 7
apple = 6
watermelon = 4
strawberry = 2

I know, it might sound confusing to start with, but this means that all the original arrays remain unaffected and you reduce the risk of the arrays becoming out of sequence.

If you needed the list in sorted order, you could easily create new arrays and apply the values accordingly (like we did when printing the results)

Having said all that. POJOs, which could hold the various properties and List and/or a sorted Map would be significantly easier :P

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Seriously...why the downvote? Sure it doesn't make use of the `Collections` API, but does demonstrate concepts that the OP can use in their existing code, based on the available information. Enlighten me with your concerns so we might be able to improve the answer... – MadProgrammer Aug 25 '14 at 02:38