我可以从方法中获得多个回报吗?

时间:2014-05-21 14:30:54

标签: java

如何从getData获取字符串Percent?有没有办法让getData返回多个字符串并只请求我选择的字符串,比如我想要的百分比数字我会调用getData(“http://woot.com”)。百分比?

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;


public class Wooot {
    public static void main(String[] args) throws IOException, InterruptedException {
        needData();
        Report();
    }
    public static void Report() throws InterruptedException, IOException{
        while (needData() == true)
        {
            System.out.println(getData("http://woot.com"));
            Thread.sleep(5000);
        }
    }
    public static boolean needData(){
        return true;
    }
    public static String getData(String url) throws IOException {
        Document doc = Jsoup
                .connect(url)
                .get();
        String percent = doc.select(".percent-remaining").first().text();
        String name = doc.select("h2").first().text();
        return name;

    }

}

6 个答案:

答案 0 :(得分:5)

您可以创建一个类来保存您想要的字段:

class SomeData {
    private final String percent;
    private final String name;
    public SomeData(String percent, String name) {
        this.percent = percent;
        this.name = name;
    }
    public String getName() {return name;}
    public String getPercent() {return percent;}
}

这是getters here are not an absolute necessity的有效点。由于Java不遵循通用访问原则,以后介绍它们可能有点尴尬,所以我在前面添加它们。但主要是我这样做,因为我的同事习惯于看到吸气剂,我试图避免过多地将它们扯掉。

您还可以添加一个便利构造函数:

    public SomeData(Document document) {
        this(doc.select(".percent-remaining").first().text(),
        doc.select("h2").first().text());
    }

这种检索数据字段的方式与连接逻辑位于不同的位置,因此您没有SRP违规,因为有多个原因需要更改类。

使用像元组或地图这样的通用集合是一种选择。元组很难看,因为字段的名称被丢弃了。使用映射,如果条目具有不同的类型,则编译时类型检查会丢失。

或者,您可以返回Document对象。我不确定在这里引入新的数据持有者类比使用Document更好。

答案 1 :(得分:1)

类似Struct的对象返回

有几种方法可以获得“有效”的多重回报。我通常使用一个轻量级的类似的类来支持这个

public static String getData(String url) throws IOException {
    Document doc = Jsoup
            .connect(url)
            .get();
    String percent = doc.select(".percent-remaining").first().text();
    String name = doc.select("h2").first().text();
    return new ImportantData(name,percent) ;

}

class ImportantData{
     public final String name;
     public final String percent;  //not sure why the percentage is a string

     public ImportantData(String name, String percent){
          this.name=name;
          this.percentage=percentage;
     }

}

这是极少数情况下,getter不会添加任何值,而final字段更有意义。

存储作为参数传递的对象

我还看到另一种方法是将商店对象传递给方法。这仅适用于可变对象,并且远不如类似Struct的对象返回。如果使用这种方法,请务必生成清晰的文档。

public static String getData(String url, Vector3d store) throws IOException {

    store.x=1;
    store.y=2;
    store.z=3;

    return "someOtherString" ;

}

答案 2 :(得分:0)

您可以使用属性Percentage创建一个类Data。类似的东西:

public class Data {

    private String percentage;

    public Data() {
    }

    public String getPercentage() {
        return percentage;
    }

    public void setPercentage(String percentage) {
        this.percentage = percentage;
    }
}

然后,您可以致电:

Data d = wooot.getData();
String percentage = d.getPercentage();

答案 3 :(得分:0)

如果不注意你想要完成的事情,我认为"通用目的"这个问题的解决方案是返回一个包含两个值的新类的实例。

    public static class DataResults
{
    private final String percent;
    private final String name;
    public DataResults(String percent, String name) {
        super();
        this.percent = percent;
        this.name = name;
    }
    public String getPercent() {
        return percent;
    }
    public String getName() {
        return name;
    }

}
public static DataResults getData(String url) throws IOException {
    Document doc = Jsoup
            .connect(url)
            .get();
    String percent = doc.select(".percent-remaining").first().text();
    String name = doc.select("h2").first().text();
    return new DataResults(percent, name);

}

答案 4 :(得分:0)

如果您认为某个方法需要多个结果,那么您实际上是在尝试表示概念上比两个单独值更复杂的内容。您实际上是在尝试表示两个结果以及它们之间的关系。例如,当您关心结果和余数时,采用整数除法的概念。第一种选择是仅定义两个单独的方法divide()mod()。问题是现在a)你做了两次相同的操作,和b)你分开明显连接的逻辑。您实际上并没有尝试返回两个数据,而是试图返回一个更复杂的结果。

public class DivMod {
  public final int result;
  public final int remainder;
  // standard constructor, getters aren't strictly necessary in such a simple class
}

public static DivMod divMod(int dividend, int divisor) {
  // compute remainder, result
  return new DivMod(remainder, result);
}

这个片段有希望清楚地表明,您可以做的事情往往更好 - 在对象中进行计算

public class DivMod {
  private final int dividend, divisor, result, remainder;

  public DivMod(int dividend, int divisor) {
    this.dividend = dividend;
    this.divisor = divisor;
    // calculate and set result and remainder
  }

  // standard getters
}

现在我们已经真正划分了我们正在尝试使用适当的面向对象编程。不需要静态方法,所有逻辑显然都在一个地方。更好的是,我们避免了上述构造无意义DivMod的情况(一个实际上并不代表分割结果的情况)。我们保证每个DivMod实例都是整数除法的不可变结果。


上面有两种标准替代品,两者都是反模式。第一种是返回一个数组或一个Collection,第二种是定义某种包含多种任意数据类型的通用Tuple类。虽然元组至少提供了固定大小的好处,并且能够在同一个对象中保存不同类型,但它们是适当的OOP设计的非常差的替代方案。 Guava也在他们的Idea Graveyard中提供了一些见解。

另请参阅@ RichardTingle关于将可变对象传递到您的方法以便使用其他数据更新它的建议,但请认为这绝对是最后的选择;它通常引入了比利益更多的混乱。

答案 5 :(得分:-1)

您可以使用String []并返回一个字符串数组。