首页 > 解决方案 > 允许 Java 方法参数接受构造函数参数

问题描述

我正在尝试优化我的代码的一部分,该部分需要一个带有构造函数参数的对象数组。有没有办法将它添加到方法的参数中?

我有一个名为 SongList 的对象数组,在该数组中有来自 Song 类的具有构造函数参数的对象:

songs[] songList = new songs[1];
songList[0] = new songs("Danger Zone", "danger zone.mp3", "Kenny Loggins", 3.33);

我还有一种基于类别和搜索查询搜索数组的方法:

//Method 
public static songs[] search(songs SearchCategory , String Quarry){}

//Calling of method 
search = AudioPlayer.search("aName", "Kenny Loggins");

歌曲类:

public class songs {
    String sName;
    String fPath;
    String aName;
    double sLength;

    public songs(String songName,
                 String filePath,
                 String Artist,
                 double songLength) {
        sName = songName;
        fPath = filePath;
        aName = Artist;
        sLength = songLength;
    }
}

有没有办法让代码的第一个参数接受像 Name 这样的构造函数参数?这将允许我减少代码的总长度,因为我不需要使用 switch 语句。

搜索方法:

public static songs[] search(String SearchCategory , String Quarry){

    //Returned array value
    songs[] ReturnedResult = new songs[0];
    // Method only list
    List<songs> SearchResult = new ArrayList<songs>();

    switch (SearchCategory) {
        case "aName":
            //for loop looks through all objects with the SearchCategory and places any found values into the list
            for (songs songs : AudioListing) {
                if (songs.aName.equals(Quarry)) {
                    SearchResult.add(songs);
                }
            }
        case "sName":
            for (songs songs : AudioListing) {
                if (songs.sName.equals(Quarry)) {
                    SearchResult.add(songs);
                }
            }
        case "fPath":
            for (songs songs : AudioListing) {
                if (songs.fPath.equals(Quarry)) {
                    SearchResult.add(songs);
                }
            }
        case "sLength":
            //Since the given quarry is a string and the length is a double the quarry is converted
            double QuarryDoubleTypeC = Double.parseDouble(Quarry);

            for (songs songs : AudioListing) {
                if (songs.sLength == QuarryDoubleTypeC) {
                    SearchResult.add(songs);
                }
            }
    }
    // Conversion of list to array for ease of use
    ReturnedResult = SearchResult.toArray(ReturnedResult);

    return ReturnedResult;
}

标签: java

解决方案


这是利用高阶函数的绝佳机会。

在 Java 中,这些是通过功能接口实现的。

Song可以songs通过Songs::aName. 此外,如果您想找到一个价值,那么杠杆Predicate<Song>是一个绝妙的主意。

此外,建议使用集合而不是数组。

简而言之,您的代码很容易看起来像这样:

class AudioPlayer {
    List<Song> audioListings = new ArrayList<>();

    public void add(Song song) { audioListings.add(song); }

    public List<Song> search(Predicate<Song> predicate) {
        return audioListings.stream()
            .find(predicate)
            .collect(Collectors.toList());
    }
}

然后你会像这样使用它:

AudioPlayer player = new AudioPlayer();
// fill with songs 
player.add(new Song("Danger Zone", "danger zone.mp3", "Kenny Loggins", 3.33));
// find song with a specific aName
var songs = player.search(song => song.aName.equals("Kenny Loggins"));

额外的好处是您可以通过构建更复杂的谓词来搜索非常复杂的事物:

// find song with specific aName AND shorter then a given length
Predicate<Song> query = 
    song => song.aName.equals("Kenny Loggins")
        .and(song => song.sLength <= 3.5);
var songs = player.search(query);

我建议不要为此使用反射。反射带来了一系列问题,根本不需要它。我在上面概述的方法是自 Java 8 以来更惯用的 Java,可扩展性更好,更易于阅读,不易出错且整体更简洁。


推荐阅读