如何在Java中以优雅的方式在两个集合中找到相等的对象?(循环集)
比如说,你必须有一套充满了狗。。。我们想知道一只狗在一个月后体重减轻了多少。这里有一些代码:如何在Java中以优雅的方式在两个集合中找到相等的对象?(循环集),java,loops,for-loop,set,Java,Loops,For Loop,Set,比如说,你必须有一套充满了狗。。。我们想知道一只狗在一个月后体重减轻了多少。这里有一些代码: Set<Dog> dogsJanuary = getDogsInJanuaryFromDB(); Set<Dog> dogsFebruary = getDogsInFebruaryFromDB(); 还有更好的办法吗 来自番石榴图书馆 编辑,重新使用Music_coder的地图创意,并将狗名作为关键: package com.stackoverflow.so21326160;
Set<Dog> dogsJanuary = getDogsInJanuaryFromDB();
Set<Dog> dogsFebruary = getDogsInFebruaryFromDB();
还有更好的办法吗 来自番石榴图书馆
编辑,重新使用Music_coder的地图创意,并将狗名作为关键:
package com.stackoverflow.so21326160;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import lombok.Data;
import lombok.EqualsAndHashCode;
public class App {
public static void main(final String[] args)
{
final Map<String, Dog> dogsJanuary = Maps.uniqueIndex(getDogsInJanuaryFromDB(), ToName.INSTANCE);
final Map<String, Dog> dogsFebruary = Maps.uniqueIndex(getDogsInFebruaryFromDB(), ToName.INSTANCE);
final Set<String> commonDogNames = Sets.intersection(dogsJanuary.keySet(), dogsFebruary.keySet());
for (final String commonDogName : commonDogNames) {
final Dog january = dogsJanuary.get(commonDogName);
final Dog february = dogsFebruary.get(commonDogName);
// use the dogs
}
}
static enum ToName implements Function<Dog, String> {
INSTANCE;
@Override
public String apply(final Dog input)
{
return input == null ? null : input.getName();
}
}
}
package com.stackoverflow.so21326160;
导入com.google.common.base.Function;
导入com.google.common.collect.Maps;
导入com.google.common.collect.set;
导入java.util.Iterator;
导入java.util.Map;
导入java.util.Set;
导入龙目数据;
导入lombok.EqualsAndHashCode;
公共类应用程序{
公共静态void main(最终字符串[]args)
{
final Map dogsJanuary=Maps.uniqueIndex(getDogsInJanuaryFromDB(),ToName.INSTANCE);
final-Map-dogsFebruary=Maps.uniqueIndex(getDogsInFebruaryFromDB(),ToName.INSTANCE);
final Set commonDogNames=Set.intersection(dogsJanuary.keySet(),dogsFebruary.keySet());
for(最终字符串commonDogName:commonDogName){
最终的狗一月=dogsJanuary.get(commonDogName);
final Dog二月=dogsFebruary.get(commonDogName);
//用狗
}
}
静态枚举ToName实现函数{
实例;
@凌驾
公共字符串应用(最终狗输入)
{
返回input==null?null:input.getName();
}
}
}
如果不编写助手方法或使用侧库,则无法简化此代码。侧库的作用与此代码中的作用几乎相同。如果您有一个主键,可以唯一地标识数据库中的每只狗,请使用映射来避免内部for
循环:
Map<int,Dog> dogsJanuary = getDogsInJanuaryFromDB();
Map<int,Dog> dogsFebruary = getDogsInFebruaryFromDB();
Iterator<Entry<int,Dog>> iter = dogsJanuary.entrySet().iterator();
while( iter.hasNext() ) {
Entry<int,Dog> entry = iter.next();
int dog_id = entry.key();
Dog d = entry.value();
Dog g = dogsFebruary.get(dog_id);
boolean dogLostWeight = compareDogs(d,g);
}
Map dogsJanuary=getDogsInJanuaryFromDB();
Map dogsFebruary=getDogsInFebruaryFromDB();
迭代器iter=dogsJanuary.entrySet().Iterator();
while(iter.hasNext()){
Entry=iter.next();
int dog_id=entry.key();
Dog d=entry.value();
Dog=dogsferray.get(Dog_uid);
布尔值dogLostWeight=compareDogs(d,g);
}
如果使用类似的有序集,则可以进一步降低循环的复杂性。有序集保证了集合中元素的顺序。
这样,您只需在所有元素上循环一次,就可以在集合的给定索引(与顺序变化相同)处比较两个Dog
,并找到等待中的差异 如果您可以使用排序集,并且如果getDogsInJanuaryFromDB()和getDogsInFebruaryFromDB()都返回相同的结果,那么您可以通过一个循环并在其中执行操作。您可以在开始之前每个月删除所有多余的狗,以减少必须进行的比较次数
Set<Dog> commonDogsJanuary = new HashSet<Dog>(dogsJanuary);
commonDogsJanuary.retainAll(dogsFebruary);
Set<Dog> commonDogsFebruary = new HashSet<Dog>(dogsFebruary);
commonDogsFebruary.retainAll(dogsJanuary);
for (Dog januaryDog : commonDogsJanuary) {
int januaryWeight = januaryDog.getWeight();
for (Dog februaryDog : commonDogsFebruary) {
if (januaryDog.equals(februaryDog) && januaryWeight > februaryDog.getWeight()) {
// Do whatever
}
}
Set commonDogsJanuary=新哈希集(dogsJanuary);
普通狗狗手工饲养(狗狗饲养);
Set commonDogsFebruary=新哈希集(dogsFebruary);
普通狗属(狗属);
用于(狗一月日日志:普通狗一月日){
int januaryWeight=januaryDog.getWeight();
用于(狗狗二月狗狗:普通狗狗二月){
if(januaryDog.equals(februaryDog)&&januaryWeight>februaryDog.getWeight()){
//做任何事
}
}
}这与我想要的正好相反。你能提供一些细节吗?我不完全明白我能用Sets.SetView intersection做些什么?@KorayTugay这可以找到原始的公共部分,所以它不适合你的需要,你不需要一种方法来找到相等的元素,你需要一种方法来计算公共元素。真的非常感谢你的努力,但看起来它变得更复杂了。:)不过,谢谢..我在这个级别上没有控制权。即使您只能以集合的形式获取数据,您也可以迭代该集合并将其放入映射中。这需要线性时间。为什么被否决,被否决的选民?
Set<Dog> commonDogsJanuary = new HashSet<Dog>(dogsJanuary);
commonDogsJanuary.retainAll(dogsFebruary);
Set<Dog> commonDogsFebruary = new HashSet<Dog>(dogsFebruary);
commonDogsFebruary.retainAll(dogsJanuary);
for (Dog januaryDog : commonDogsJanuary) {
int januaryWeight = januaryDog.getWeight();
for (Dog februaryDog : commonDogsFebruary) {
if (januaryDog.equals(februaryDog) && januaryWeight > februaryDog.getWeight()) {
// Do whatever
}
}