基于公共属性组合集合的智能方法

时间:2016-01-27 04:46:09

标签: java guava

说我有以下两个班级......

public class Computer {
    private String computerName;
    private boolean hasTechnicalIssue;
}   

public class TechnicalIssue {
    private String issueId;
    private String computerName;
}   

public class ComputerManager {

   ComputerDao computerDao;
   IssueDao issueDao;

   public void getComputers {
       List<Computer> computers = computerDao.getComputers();
       List<TechnicalIssues> technicalIssues = issueDao.getTechnicalIssues();  
       // I would like to do something here to set the hasTechnicalIssue flag
   }

}

Computer类和TechnicalIssue类都具有computername属性。

是否有使用Guava的智能方法,我可以使用TechnicalIssues列表中的computerName属性在计算机列表中设置hasTechnicalIssue布尔值?

例如,如果包含计算机的列表包含computerName为computer9999的条目,并且包含技术问题的列表也包含具有相同computerName的条目,则Computer类上的hasTechnicalIssue应该等于true。

4 个答案:

答案 0 :(得分:3)

为了避免使用O(n * m)算法(O(n ^ 2)假设2个集合具有可比较的大小),您需要对每个集合进行一次迭代,如果您收集一个中间集合,即涉及技术问题的计算机名称:

Set<String> computersWithIssues = Sets.newHashSetWithExpectedSize(technicalIssues.size());
for (TechnicalIssue issue : technicalIssues) {
    computersWithIssues.add(issue.getComputerName());
}
for (Computer computer : computers) {
    computer.setHasTechnicalIssue(computersWithIssues.contains(computer.getComputerName());
}

你可以对Guava充满乐趣并使用Function<TechnicalIssue, String>将技术问题的集合转换为名称集合,但除非你因某些原因需要概括,否则它只会是噪音。请参阅番石榴功能概念解释中的caveat,重点是写作时不够清晰或更短:

Function<TechnicalIssue, String> toName = new Function<>() {
    @Override
    public String apply(TechnicalIssue input) {
        return input.getComputerName();
    }
}
Set<String> computersWithIssues = FluentIterable.from(technicalIssues)
    .transform(toName)
    .toSet();

答案 1 :(得分:2)

这听起来像FluentIterable的方法和anyMatch运算符的使用。需要注意的关键事项:

  • 我们不在乎 匹配发生在技术问题列表中,只要 匹配
  • 我们需要遍历计算机集合中的所有元素
  • 这仍然是一项昂贵的操作,因为我们正在进行O(nm)

考虑到这一点,流畅的可迭代表达式很简单。

final FluentIterable<TechnicalIssue> fluentIterable = FluentIterable.from(technicalIssues);
for(Computer computer : computers) {
    boolean match = fluentIterable.anyMatch(new Predicate<TechnicalIssue>() {
        @Override
        public boolean apply(final TechnicalIssue input) {
            return input.getComputerName().equals(computer.getComputerName());
        }
    });
    if(match) {
        computer.setHasTechnicalIssue(true);
    }
}

答案 2 :(得分:0)

class Computer {

private String computerName;
private boolean hasTechnicalIssue;

public String getComputerName() {
    return computerName;
}

public void setComputerName(String computerName) {
    this.computerName = computerName;
}

public boolean isHasTechnicalIssue() {
    return hasTechnicalIssue;
}

public void setHasTechnicalIssue(boolean hasTechnicalIssue) {
    this.hasTechnicalIssue = hasTechnicalIssue;
}

}

class TechnicalIssue {

private String issueId;
private String computerName;

public String getComputerName() {
    return computerName;
}

public void setComputerName(String computerName) {
    this.computerName = computerName;
}

public String getIssueId() {
    return issueId;
}

public void setIssueId(String issueId) {
    this.issueId = issueId;
}

}

class ComputerDao {

List<Computer> getComputers() {
    List<Computer> clist = new ArrayList<Computer>();
    Computer c = new Computer();
    c.setComputerName("rahul");
    c.setHasTechnicalIssue(true);
    clist.add(c);
    Computer c1 = new Computer();
    c1.setComputerName("rahul1");
    c1.setHasTechnicalIssue(false);
    clist.add(c1);
    return clist;
}

}

类IssueDao {

List<TechnicalIssue> getTechnicalIssues() {
    List<TechnicalIssue> clist = new ArrayList<TechnicalIssue>();
    TechnicalIssue c = new TechnicalIssue();
    c.setComputerName("rahul");
    c.setIssueId("111");
    clist.add(c);
    TechnicalIssue c1 = new TechnicalIssue();
    c1.setComputerName("rahul1");
    c1.setIssueId("112");
    clist.add(c1);
    return clist;
}

}

public class QuestionClass {

ComputerDao computerDao;
IssueDao issueDao;

public void getComputers() {
    computerDao = new ComputerDao();
    issueDao = new IssueDao();
    List<Computer> computers = computerDao.getComputers();
    List<TechnicalIssue> technicalIssues = issueDao.getTechnicalIssues();
    for (Iterator<TechnicalIssue> it = technicalIssues.iterator(); it.hasNext();) {
        TechnicalIssue technicalIssue = it.next();
        for (Iterator<Computer> it1 = computers.iterator(); it1.hasNext();) {
            Computer computers1 = it1.next();
            if (technicalIssue.getComputerName().equals(computers1.getComputerName()) && computers1.isHasTechnicalIssue()) {
                System.out.println("Has techincal issue : " + computers1.getComputerName());
                //Print all other details
            }
        }
    }
}

public static void main(String[] args) {
    QuestionClass QC = new QuestionClass();
    QC.getComputers();
}

}

##输出##
有技术问题:rahul
建立成功(总时间:0秒)

答案 3 :(得分:0)

U特别要求提供涉及番石榴的解决方案。我从未使用过番石榴。如果你不介意我可以用一种简单的方式告诉你如何做到这一点:

for (int i = 0; i < computers.size(); i++){ 
String cn = computers.get(i).getComputerName(); 
for (int j = 0; j < technicalIssues.size(); j++){ 
if (cn.contentEquals(technicalIssues.get(j).getComputerName())){ 
computers.get(i).setHasTechnicalIssue(true); 
break; 
} 
} 
}