方法能否以简洁的方式返回一组不同的返回类型?

问题描述 投票:0回答:6

如何从getData获取字符串Percent?有没有一种方法可以让getData返回多个字符串并仅请求我从中选择的字符串,例如,如果我想要百分比数字,我将调用getData(“ http://woot.com”)。Percentage?

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;

    }

}
java
6个回答
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
投票

类似结构的对象返回

您可以通过几种方法获得“有效的”多重回报。我通常使用类似轻量级结构的类来支持此]

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" ;

}

0
投票

您可以创建一个具有百分比属性的类数据。类似于:

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();

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);

}

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);
}

希望该片段清楚地表明,通常还有一些您可以做得更好的事情-对对象进行计算[[in:

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设计而言,它们却是非常糟糕的替代方案。番石榴也为他们的Idea Graveyard提供了一些见识。

另见@RichardTingle的关于将可变对象传递到您的方法中以用附加数据更新它的建议,但请严格认为这是不得已的选择;通常,它带来的混乱多于收益。


-1
投票
您可以使用String []并返回一个字符串数组。
© www.soinside.com 2019 - 2024. All rights reserved.