无法编写正确的foreach语法

时间:2018-07-20 14:39:26

标签: java arraylist

我正在寻找迭代有时有一个共同的head元素的arrayList。 arrayList的填充如下:

     //getters, setters
     public static void main(String[] args) {

     ArrayList<Sports> kayak = new ArrayList<>();
     kayak.add(new Sports(sportsmanID[0], 21)
     kayak.add(new Sports(sportsmanID[0], 24)
     kayak.add(new Sports(sportsmanID[1], 29)

sportsmanID在我的main方法中声明,并且声明如下:

     sportsmanID = new int[20];
     // bunch of equals

重点是将与每个sportsmanID关联的整数相加一次。 查看预期结果:

    sportsmanID[0] = 21+24
    sportsmanID[1] = 29

当然,我所有的变量都有各自的getter和setter,否则我将无法访问arrayList。

尝试了我能想到的每种形式的阵列信号后,我想尝试使用增强的for循环解决此问题。从逻辑上讲,这是有道理的:我希望对每个sportsID都执行一次演算。 但是,由于我要处理的是对象数组,而且我的语法严重不正确,因此我很挣扎。鉴于java是OOP语言,这似乎具有含义。但是我不能把头缠住。

有人能指出我的正确方向吗?我被困在这上面一段时间了,祝福任何能救我的人。

最好先谢谢

4 个答案:

答案 0 :(得分:1)

假设您的Sports如下所示:

class Sports {
    private final int sportsmanId;
    private final int someInt;


    public Sports(final int sportsmanId, final int someInt) {
        this.sportsmanId = sportsmanId;
        this.someInt = someInt;
    }

    public int getSportsmanId() {
        return sportsmanId;
    }

    public int getSomeInt() {
        return someInt;
    }
}

然后,以下将满足您的要求:

final Map<Integer, Integer> sumBySportsmanId = kayak.stream()
        .collect(groupingBy(Sports::getSportsmanId, summingInt(Sports::getSomeInt)));

使用以下static导入:

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;

这是如何工作的:

  • kayak.stream()返回Stream<Kayak>,给出元素的“流”
  • stream.collect取一个Collector,这会收集所有元素
  • Collectors.groupingBy在这里有两个参数,第一个是对要分组的项目的方法引用。它将创建一个Map<>,键为分组,值为下游收集器的结果
  • Sports::getSportsmanId是一种方法引用,它允许groupingBy分组为sportsmanId
  • Collectors.summingInt是另一种Collector,这是通过某种方式从传入的项目中获取int的方式,因为分组生活在Map<Integer, List<Sports>>中,我们需要提取someInt中的Sports
  • Sports::getSomeInt是一种方法引用,将int赋予summingInt Collector

答案 1 :(得分:1)

我将equalshashcode覆盖如下:

class Sports {
    private int id;
    private int value;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Sports sports = (Sports) o;
        return id == sports.id;
    }

    @Override
    public int hashCode() {    
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "Sports{" +
                "id=" + id +
                ", value=" + value +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    Sports(int id, int value){
        this.id = id;
        this.value = value;
    }
}

然后创建一个merge方法,您可以使用该方法将Sports对象与列表一起传递。然后,此方法将通过id来检查列表中是否已经存在要添加的对象,然后只需将它们的值加在一起,而不必再添加具有相同ID的另一个对象。

但是,如果尚不存在,则将该对象添加到列表中。

public static void merge(Sports obj, List<Sports> source){
        int index = source.indexOf(obj);
        if(index == -1) {
            source.add(obj);
            return;
        }
        Sports tempObj = source.get(index);
        tempObj.setValue(obj.getValue() + tempObj.getValue());
}

然后简单地做:

ArrayList<Sports> kayak = new ArrayList<>();
merge(new Sports(sportsmanID[0], 21), kayak);
merge(new Sports(sportsmanID[0], 24), kayak);
merge(new Sports(sportsmanID[1], 29), kayak);

kayak现在具有以下元素:

[Sports{id=1, value=45}, Sports{id=2, value=29}]

答案 2 :(得分:0)

我建议您添加一个getset方法,以便可以从每个Sport中检索ID,然后,可以用两种不同的方式进行迭代:

kayak.forEach(s -> //perform something here);

for (Sport s: kayak){
//perform something here
}

然后,您将使用getId()方法来检索值并对其进行处理

答案 3 :(得分:0)

Map

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

ArrayList<Sports> kayak = new ArrayList<Sports>();
kayak.add(new Sports(sportsmanID[0], 21);
kayak.add(new Sports(sportsmanID[0], 24);
kayak.add(new Sports(sportsmanID[1], 29);

for(Sports s:kayak) {
    if(count.containsKey(s.getSportsmanID())) {
        count.put(s.getSportsmanID(), count.get(s.getSportsmanID())+s.getScore());
    } else {
        count.put(s.getSportsmanID(), s.getScore());
    }
}

System.out.println(count.get(sportsmanID[0]));