我最近学会了3种新语言,我开始让他们感到困惑。几年后我没有在Java上做任何特别复杂的事情(在android之外)。我无法记住这是否可能:
我主要是继承ArrayList,所以我可以保持arraylist的顺序。我试图覆盖add(object)
方法,但我希望它返回一个int而不是一个布尔值(添加的对象的位置)。但是我的方法返回类型出错了。
我想要的语言甚至可能吗?你能在子类中有一个方法返回与超类'方法不同的东西吗?
还是我想做一些蠢事?这是否打破了is-a
继承的想法?我应该封装一个arraylist而不是扩展它吗?
供参考,我正在尝试做的一部分:
public class AuthorArray extends ArrayList \{
@Override
public int add(Author object) {
super.add(object);
Collections.sort(this, new SortByLastName());
return this.indexOf(object);
}
}
答案 0 :(得分:3)
你能否在子类中有一个方法返回与超类'方法不同的东西?
一般来说,没有。当重写方法在基类/接口方法中返回返回类型的子类时,唯一的例外是协变返回类型。这在Java5中成为可能,并且是很好的做法。但是你的情况不属于这一类。
这是否打破了继承的想法?
是即可。 ArrayList
的用户希望从boolean
获得add
返回值,并按照他们添加的相同顺序查看元素,您就会打破这种期望。不要那样做。
我应该封装一个arraylist而不是扩展它吗?
是。然后,您可以使用您喜欢的任何合约定义自己的界面。但首先,考虑使用TreeSet
代替。
答案 1 :(得分:1)
改变语义是不好的。在您的情况下,如果您想要一个简单的修复,将方法名称从add
更改为myadd
可以解决您的问题。
就我个人而言,我建议学习如何使用Google guava-libraries不可变的排序数据结构和'function',以获得进修概述,浏览youtube。
但是在标准的Java中,我做了一个示例,如何使用TreeSet autosort - 自定义类,2值比较器和高效的二进制搜索等效。
public static class customC {
private String name;
private int value;
public customC(String name, int value) {super();this.name = name;this.value = value;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getValue() {return value;}
public void setValue(int value) {this.value = value;}
@Override
public String toString() {
return new StringBuilder().append("[").append(this.name)
.append(":").append(this.value).append("]").toString();
}
}
public static void main(String[] args) {
TreeSet<customC> ts = new TreeSet<customC>(new Comparator<customC>(){
public int compare(customC a, customC b) {
int result = a.getName().compareToIgnoreCase(b.getName());
return (result != 0 ? result : a.getValue() - b.getValue());
}
});
ts.add(new customC("ab", 1988));
ts.add(new customC("ab", 1979));
ts.add(new customC("ba", 1988));
ts.add(new customC("ab", 1984));
ts.add(new customC("ab", 1980));
customC ce = new customC("ab", 1983);
ts.add(ce);
StringBuilder sb = new StringBuilder();
sb.append(ts.headSet(ce).last()).append(" comes before ")
.append(ce).append("\n").append(ts);
System.out.println(sb.toString());
}
这将输出:
[ab:1980] comes before [ab:1983]
[[ab:1979], [ab:1980], [ab:1983], [ab:1984], [ab:1988], [ba:1988]]
答案 2 :(得分:0)
List接口保证元素的返回顺序与添加元素的顺序相同。因此,如果您只有一个线程操作列表,则可以轻松执行添加,然后请求其大小。 size - 1是元素的序数值。
如果上述顺序不是您想要的,那么您有两个选择 - 使用Collection.sort()方法对列表进行排序,或使用SortedSet。这两种方法都可以采用比较器。
我从未发现需要扩展Java集合框架,并且不建议您在这种情况下这样做。