简体   繁体   中英

Java - How to use a for each loop to check the different occurrences of a value in a list of objects

Sorry if the title isn't clear, I wasn't sure how to word it. I have an arraylist of objects and within each of these objects I store an integer value referring to a category and one referring to an ID.

I want to find the number of unique combinations of category and IDs that there are.

So at the moment I have

for(Object object: listofObjects){
     //For each unique type of object.getID
     //For each unique type of object.getCategory
     //Add 1 to counter
}

I can't figure out how to do this. Doing things like for(int cat: object.getCategory()) brings up an error.

I can add the values to a new list within the initial for each loop like so,

ArrayList<Integer> aList= new ArrayList<Integer>();
for (Object object : spriteExplore) {
    aList.add(object.getCategory());
}
for (int cat : aList) {
    testCounter++;
}

but this obviosuly does not take into account uniqueness and also makes it awkward for factoring in the other variable of ID.

I feel like there is probably some easier work around that I am missing. Any advice? Thanks in advance.

So you list of UserDefine object in ArrayList and you want to find unique Object.Just create set from list.

For eg Suppose you have

List<Customer> list=new ArrayList<Custeomer>();
list.add(new Customer("A",12));
list.add(new Customer("B",13));
list.add(new Customer("A",12));

now create set From this list

Set<Customer> set = new HashSet<Customer>(list);

this will have unique Customer IMP : dont forget to override equals and hashcode method for Customer

Your best approach would be storing the data correctly.

It's possible that you still need to store non-unique items, if that's so - continue using an ArrayList, but in addition, use the following:

Override the hashcode & equels function as shown in this link: What issues should be considered when overriding equals and hashCode in Java?

Then, use a Set (HashSet would probably be enough for you) to store all your objects. This data structure will disregard elements which are not unique to elements already inside the set.

Then, all you need to do is query the size of the set, and that gives you the amount of unique elements in the list.

I don't know any library that does this automatically, but you can do it manually using sets. Sets will retain only unique object so if you try to add the same value twice it will only keep one reference.

Set<Integer> categories = new HashSet<Integer>();
Set<Integer> ids= new HashSet<Integer>();

for (Object object : listofObjects) {
    categories.add(object.getCategory());
    ids.add(object.getID());
}

Then you get the number of unique categories / ids by doing

categories.size()
ids.size()

And all your unique values are stored in the sets if you want to use them.

I would look into using a (Hash)Map<Integer, Integer> . Then just have 1 foreach loop, checking to see if the value of Map<object.getId(), object.getCategory()> is null by checking if map.get(object.getId()) is null - if it is, then this pair does not exist yet, so add this pair into the map by using map.put(object.getId(), object.getCategory()) . If not, do nothing. Then at the end, to find the number of unique pairs you can just use map.size()

Hope this helps

Map<Integer,List<Integer>> uniqueCombinations = new HashMap<Integer,List<Integer>>();

for (Object object : listofObjects) {
  if(uniqueCombinations.get(object.getCategoryId())==null) {
    uniqueCombinations.put(object.getCategoryId(), new LinkedList<Integer>);
  }
  uniqueCombinations.get(object.getCategoryId()).add(object.getId());
}

return uniqueCombinations.size()

Use the Hashmap to save occurence. Dont forget to implement hashcode und equals Methods. You can generate them if you work with Eclipse IDE.

public static void main(String[] args) {

    List<MyObject> myObjects = Arrays.asList(new MyObject(1, 2), new MyObject(2, 3), new MyObject(3, 4), new MyObject(3, 4));

    Map<MyObject, Integer> map = new HashMap<>();

    for (MyObject myObject : myObjects) {

        Integer counter = map.get(myObject);

        if(counter == null){
            counter = 1;
        } else {
            counter = counter + 1;
        }

        map.put(myObject, counter);
    }

    long uniqueness = 0;
    for(Integer i : map.values()){
        if(i == 1){
            ++uniqueness;
        }
    }

    System.out.println(uniqueness);

}

The last part can be replaced by this one line expression if you are working with Java 8:

long uniqueness = map.values().stream().filter(i -> i == 1).count();

I believe you want unique combinations of both category and id, right?

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


public class SO {

    class MyObject{
        private int id;
        private int category;
        private String name;
        private MyObject(int id, int category,String name) {
            super();
            this.id = id;
            this.category = category;
            this.name = name;
        }
        protected int getId() {
            return id;
        }
        protected int getCategory() {
            return category;
        }
        @Override
        public String toString() {
            return "MyObject [id=" + id + ", category=" + category + ", name=" + name + "]";
        }

    }

    public static void main(String[] args) {

        SO so = new SO();

        List<Object> listofObjects = new ArrayList<Object>();
        listofObjects.add(so.new MyObject(1,1,"One"));
        listofObjects.add(so.new MyObject(1,1,"Two"));
        listofObjects.add(so.new MyObject(1,2,"Three"));

        Map<String,List<MyObject>> combinations = new HashMap<String,List<MyObject>>();

        for(Object object: listofObjects ){
             //For each unique type of object.getID
             //For each unique type of object.getCategory
             //Add 1 to counter
            if (object instanceof MyObject){
                MyObject obj = (MyObject)object;
                String unique = obj.id+"-"+obj.category;
                if (combinations.get(unique) == null){
                    combinations.put(unique, new ArrayList<MyObject>());
                }
                combinations.get(unique).add(obj);
            }
        }

        System.out.println(combinations);

        //counts

        for(Entry<String,List<MyObject>> entry:combinations.entrySet()){
            System.out.println(entry.getKey()+"="+entry.getValue().size());
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM