Java 泛型方法用于过滤和查找列表中的第一个元素。

huangapple go评论73阅读模式
英文:

Java generics method to filter and find first element in list

问题

private Feature findFeature(String name, List list) {
for (Feature item : list) {
if (item.getName().equals(name)) {
return item;
}
}
return null;
}

我有其他10个类似的方法。签名相同,逻辑相同。唯一不同的是List参数使用不同的对象,例如List<Data> list,或者List<Option> list等。所有对象都有一个getName()方法。我想创建一个通用方法并删除所有其他方法。

如果我使用类似这样的东西,

private T findInList(String name, List list) {

我无法访问getName()方法。创建这个方法最简单的方式是什么?反射API是唯一的选择吗?

编辑:

我发现了我犯的错误。像这样工作得很好:

对于(FeatureEntity entity:data.getFeatures()){
谓词过滤器= f - > f.getName()。equalsIgnoreCase(entity.getName());
如果(entity.getFeatureId()!= null && findInList(featureList,filter)== null){
FeatureEntity n = new FeatureEntity();
n.setId(entity.getId());
// ...
}
}

英文:
private Feature findFeature(String name, List&lt;Feature&gt; list) {
    for (Feature item : list) {
        if (item.getName().equals(name)) {
            return  item;
        }
    }
    return null;
}

I have 10 other methods like this. Same signature, same logic. Only different is that List parameter is using different objects, e.g. List&lt;Data&gt; list, or List&lt;Option&gt; list, etc. All objects has a getName() method in it. I want to create a generic method and remove all others.

If I use something like this,

private &lt;T&gt; T findInList(String name, List&lt;T&gt; list) {

I don't have access the getName() method. What is the easiest way to create this method? Is reflection api the only option?

EDIT:

I found the mistake I did. It is working just fine like this:

for (FeatureEntity entity : data.getFeatures()) {
    Predicate&lt;Feature&gt; filter = f -&gt; f.getName().equalsIgnoreCase(entity.getName());
    if (entity.getFeatureId() != null &amp;&amp; findInList(featureList, filter) == null) {
        FeatureEntity n = new FeatureEntity();
        n.setId(entity.getId());
        // ...
    }
}

答案1

得分: 5

可以创建一个通用的方法该方法接受带有 `Predicate` 的通用列表以获取过滤后的第一个匹配项

    private <T> T findFeature(List<T> list, Predicate<T> predicate) {
		return list.stream().filter(predicate).findFirst().orElse(null);
	}

然后创建所需类型的 `Predicate` 并调用该方法

    Predicate<Feature> filter = f -> f.getName().equalsIgnoreCase(name);
    findFeature(list, filter);

另一方面当找不到元素时也可以返回 `Optional<T>` 而不是 `null`:

    private <T> Optional<T> findFeature(List<T> list, Predicate<T> predicate) {
		return list.stream().filter(predicate).findFirst();
	}
英文:

You can create generic method that takes generic list with Predicate to get the first matching item after filtering

private &lt;T&gt; T findFeature(List&lt;T&gt; list, Predicate&lt;T&gt; predicate) {
	return list.stream().filter(predicate).findFirst().orElse(null);
}

And then create Predicate with required type and call that method

Predicate&lt; Feature &gt; filter = f-&gt;f.getName().equalsIgnoreCase(name);
findFeature(list,filter);

On another side, you can also return Optional&lt;T&gt; instead of null when no element is found:

private &lt;T&gt; Optional&lt;T&gt; findFeature(List&lt;T&gt; list, Predicate&lt;T&gt; predicate) {
	return list.stream().filter(predicate).findFirst();
}

答案2

得分: 1

你可以创建一个通用的 Named 接口,就像这样:

public interface Named {
    String getName();
}

然后使用通配符来指定方法需要 Named 接口:

private <T extends Named> T findInList(String name, List<T> list)

然后你就可以使用 getName 方法了。当然,你需要修改希望使用的类以实现 Named 接口(但你提到它们已经都有 getName() 方法)。

英文:

You could create a common Named interface, like

public interface Named {
    String getName();
}

Then use a wildcard to specify that the method requires that Named interface.

private &lt;T extends Named&gt; T findInList(String name, List&lt;T&gt; list)

Then you can use getName. Of course, you need to modify the classes you wish to use to implements Named (but you mentioned they all already have getName() methods).

答案3

得分: 0

首先,你需要一个接口:

public interface HasName {
    String getName();
}

然后,你的 Feature 类需要实现它:

public class Feature implements HasName {

在你的类名后添加 implements 后,你需要实现 getName() 方法(让你的IDE帮助你完成这一步骤)。

接着进行如下步骤:

private <T extends HasName> T findFeature(String name, List<T> list) {
    // 在这里进行你的逻辑操作,getName方法将可用。
}
英文:

first, you need an Inferface:

public interface HasName {
    String getName();
}

then, your Feature class has to implement it:

public class Feature implements HasName {

After you add the implements to your class name, you need to implement the getName() method (let your IDE help you with this)

then go as follows:

private &lt;T extends HasName&gt; findFeature(String name, List&lt;T&gt; list) {
    // Do your logic, getName will be availible here.
}

huangapple
  • 本文由 发表于 2020年3月16日 23:22:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/60708666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定