允许 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 中有一个反射的概念,你可以在这里使用。

  1. 您可以使用SearchCategory从对象中获取字段值
  2. 然后您可以使用它与Quarry进行比较

工作代码如下

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Songs {
String sName;
String fPath;
String aName;
double sLength;
static Songs[] AudioListing = new Songs[1];
static {
AudioListing[0] = new Songs("Danger Zone", "danger zone.mp3", "Kenny Loggins", 3.33);
}
public Songs(String songName, String filePath, String Artist, double songLength) {
sName = songName;
fPath = filePath;
aName = Artist;
sLength = songLength;
}
public static Songs[] search(String SearchCategory, String Quarry) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// Returned array value
Songs[] ReturnedResult = new Songs[0];
// Method only list
List<Songs> SearchResult = new ArrayList<Songs>();
for (Songs song : AudioListing) {
Field field = Songs.class.getDeclaredField(SearchCategory);
String fieldValue = (String) field.get(song);
if (fieldValue.equals(Quarry)) {
SearchResult.add(song);
}
}
// Conversion of list to array for ease of use
ReturnedResult = SearchResult.toArray(ReturnedResult);
return ReturnedResult;
}

@Override
public String toString() {
return "Songs [sName=" + sName + ", fPath=" + fPath + ", aName=" + aName + ", sLength=" + sLength + "]";
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
//Calling of method
Songs[] results = Songs.search("aName", "Kenny Loggins");
System.out.println(Arrays.toString(results));
}
}

这解释了如何实现它,您可以在进一步探索这个方向后进一步增强您的代码。

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

在Java中,这些都是通过函数接口实现的。

您可以通过Songs::aName引用Song类(应大写和单数,而不是songs(本身的方法或字段。此外,如果您想找到价值,利用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,扩展性更好,更易于阅读,更不容易出错,整体更干净。

你要找的有点高级; 它是界面Function<Song, String>。这将允许您提供一些转换,为Song对象选择字符串值,特别是在这种情况下,例如Song::getSName.这是处理流(和集合(的方式:

songList.stream()
.filter(song -> quarry.equals(function.apply(song)))
.findAll();

但是,我强烈建议您在深入研究更复杂的逻辑之前更熟悉 Java 的基础知识,尤其是有关命名(类应该大写;变量不应该(、集合(列表通常优先于数组(、静态与实例成员和接口的标准。

相关内容

最新更新