我正在寻找迭代有时有一个共同的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语言,这似乎具有含义。但是我不能把头缠住。
有人能指出我的正确方向吗?我被困在这上面一段时间了,祝福任何能救我的人。
最好先谢谢
答案 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)
我将equals
和hashcode
覆盖如下:
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)
我建议您添加一个get
和set
方法,以便可以从每个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]));