实例化:List[<数据类型>] list = new ArrayList[<数据类型>]();
获得集合内元素个数:listsize();
添加元素:
默认添加:listadd(e);
指定下标添加(添加后下标后的元素向后挪一位):listadd(index,e);
删除元素:
返回是否删除:listremove(e);
直接删除指定下标的元素(只删除找到的第一个相符合的元素):listremove(index);
替换元素(替换掉指定下标的元素):listset(index,e);
取出元素:listget(index);
清空集合:listclear();
判断集合中是否存在某个元素(存在返回true,不存在返回false):listcontains(e);
对比两个集合中的所有元素:
两个对象一定相等:listequals(list2);
两个对象不一定相等:listhashCode() == list2hashCode();
(两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象。)
获得元素下标:
元素存在则返回找到的第一个元素的下标,不存在则返回-1:listindexOf(e);
元素存在则返回找到的最后一个元素的下标,不存在则返回-1:listlastIndexOf(e);
判断集合是否为空(空则返回true,非空则返回false):listisEmpty();
返回Iterator集合对象:listiterator();
将集合转换为字符串:listtoString();
截取集合(从fromIndex开始在toIndex前结束,[fromIndex,toIndex)):listsubList(fromIndex,toIndex);
将集合转换为数组:
默认类型:listtoArray();
指定类型(objects为指定类型的数组对象,并将转换好的数组赋值给objects数组):listtoArray(objects);
以上为List常用的方法。在循环外创建一个变量就行
List list;
for (int i : 要遍历的集合或数组) {
listadd(i);
}
listforEach(x -> sysout(x));我遇到一个问题,我找不到自己解决的正确方法。
基本上,我有两个对象Object1和Object2,它们都具有相同类型的两个属性:
public class Object1 {
private String name;
private String description;
Object1 () {
}
public String getName() {
return name;
}
public void setName(String name) {
thisname = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
thisdescription = description;
}
}
public class Object2 {
private String name;
private String description;
Object2 () {
}
public String getName() {
return name;
}
public void setName(String name) {
thisname = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
thisdescription = description;
}
}
现在显然在示例中,我将它们的属性设置为字符串,但实际上它们是其他类型。
注意:Object1和Object2实际上是从我需要SOAP服务的XML模型生成的类。 所以我不能修改它们。
在我的代码中的某些时候,我必须根据不同的因素访问说Object1或Object2的'name'属性。 这一点是一个事件处理程序,因此在一定时间内它会捕获一个用Object1调用的事件,而其他时候则用Object2捕获一个事件。
我的猜测是要制作一个包含这两种类型的类,并公开一个" name"属性和一个" description"属性。
这样做的标准方法是什么?
您可以为Object1和Object2创建共享接口
大声笑,我喜欢这样的问题,当它们都是相同的OO设计时,它们会得出诸如"您得到一个接口,您得到一个接口,您得到一个超类,您得到一个抽象超类,这是一个额外的接口"的答案。 都有优点/缺点的成语:)
基本上有两种方法可以做到这一点:
使用公共接口公开getter和setter。然后,让两个类都实现该接口,并让处理程序使用它。
如果可能的话(两个对象都尚未扩展其他超类),可以使用抽象超类并将属性以及getter和setter放在此处。然后,处理程序使用该超类。
请注意,这两种方法可以组合使用,即为处理程序使用接口,并使用将接口实现为适配器类的抽象超类,即可以在可能时扩展该适配器,或者在无法扩展适配器时仅实现该接口。
例:
interface Common {
String getName();
}
abstract class CommonAdapter implements Common {
String name;
String getName() {
return name;
}
//setter as well
}
//just extend the adapter and enjoy
class Object1 extends CommonAdapter {
//specific code for Object1
}
//extending not possible, so implement the interface directly
class Object2 extends SomeOtherClass implements Common {
String name;
String getName() {
return name;
}
}
class Handler {
void handle( Common c ) {
cgetName();
}
}
更新:
如果生成了类,则可以将这些对象创建为包装器,并将所有调用委派给实际的类,例如
class Object1CommonWrapper implements Common {
Object1 delegate;
String getName() {
return delegategetName();
}
}
这是理论上最好的方法,完全符合OOP标准。
那将是最简单的方法,也是最明显的方法,但是我无法处理Object1和Object2,因为我是从SOAP消息所需的XML模型中生成它们的。
您可以定义Object1和Object2都实现的接口。该接口将包含您需要调用的方法,但是每个类都可以以自己的方式实现它们。
例如,它可能看起来像这样:
public interface Describable {
String getName();
String getDescription();
}
public class Object1 implements Describable {
implements the methods in some way
}
public class Object2 implements Describable {
implements the methods in another way
}
这样,无论需要处理这两种类型的对象的任何代码,都可以将它们称为Describable并利用多态性。例如:
Describable eventObject = get the object
eventObjectgetName();
eventObjectgetDescription();
甚至类似:
public void handle(Describable describable) {
describablegetDescription();
more stuff
}
该代码不知道(或不在乎)实际上将哪种类型的对象传递给该方法,只是它可以作为Describable与它交互。
通常,这是Java和OO设计中的一个常见习语。核心库在各处使用它。
顺便说一句,继承(即,使用公共的基超类)是另一种选择。请注意,实现继承的技术需要权衡取舍,并且经常被滥用/滥用。例如,请参见此讨论。
Object1和Object2实际上是从我需要SOAP服务的XML模型生成的类。 所以我不能碰他们。
这个细节需要成为问题的一部分; 从根本上改变了您的潜在选择。
它有点取决于所述方法的行为。因此,如果:
这两个Object1 / Object2都具有与继承有关的那些方法的绝对相同的代码,并具有定义这些字段/方法的超类,并且两个对象对其进行了扩展。
两个Object1 / object2必须具有相同的方法签名,但必须以不同的方式处理内部逻辑,我将使用定义两个Object1 / 2必须实现的方法签名的接口。
使用接口或抽象类
public interface CommonObject {
//gettter and setter
}
public Class Object1 implements CommonObject { }
public Class Object2 implements CommonObject { }
public Class MainClass {
public void someMethod() {
if(someCondition) {
CommonObject obj1 = new Object1();
//use obj1
} else {
CommonObject obj2 = new Object1();
//use obj2
}
}
}
使用工厂模式
制作一个抽象类,让两个类都从中扩展
Object1和Object2实际上是从我需要SOAP服务的XML模型生成的类。 所以我不能碰他们。看到这个标题,估计很多人会纳闷:连集合类的removeAll方法都用不好还当什么程序员。
好吧,我承认我确实没用好这个方法,鄙视我吧。O(∩_∩)O哈!
先贴问题--->
实体类(User):
[java] view
plaincopy
public class User {
private String name;
private int age;
//setter and getter
public String getName() {
return name;
}
public void setName(String name) {
thisname = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
thisage = age;
}
}
测试集合类(UserList):
[java] view
plaincopy
import javautilArrayList;
import javautilList;
public class UserList {
private List<User> subList;
private List<User> allList;
public UserList(){
subList=new ArrayList<User>();
allList=new ArrayList<User>();
for(int i=0;i<3;i++){
User user=new User();
usersetAge(i);
usersetName("lyh"+i);
subListadd(user);
}
for(int i=0;i<10;i++){
User user=new User();
usersetAge(i);
usersetName("lyh"+i);
allListadd(user);
}
}
public static void main(String[] args){
UserList userList=new UserList();
userListallListremoveAll(userListsubList);//调用removeAll方法
Systemoutprintln(userListallListsize());
}
}
诸君认为最后的打印的结果是多少? 7 ?That's wrong !! 结果是10。
为什么会这样哪?难道removeAll方法有问题?
这个就是最近在用到removeAll时遇到的疑问(当然,我是把实际中的问题简单的抽象出来了)。当时百思不得其解,甚至幼稚的以为是Java的BUG 。殊不知是自己脑袋BUG了 !
原因解析:
先看API
[xhtml] view
plaincopy
boolean removeAll(Collection<> c)
从列表中移除指定 collection 中包含的其所有元素(可选 *** 作)。
没错,就是移除子集合包含的元素,那为什么不是7,而是10 。
再看API说明,移除所包含的其所有元素,注意这个字眼:包含!
因为在执行removeAll方法时,会先对集合元素进行比较,如果元素相等才执行移除 *** 作,说到这,相信很多人都已经明白是怎么回事了,因为不相等(equals),所以没有执行移除。
查看源码进一步证实上述猜测,remove和removeAll的方法实现在:
javautilAbstractCollection<E>
具体代码为:
[java] view
plaincopy
public boolean removeAll(Collection<> c) {
boolean modified = false;
Iterator<> it = iterator();
while (ithasNext()) {
if (ccontains(itnext())) {
itremove();
modified = true;
}
}
return modified;
}
[java] view
plaincopy
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (ithasNext()) {
if (itnext()==null) {
itremove();
return true;
}
}
} else {
while (ithasNext()) {
if (oequals(itnext())) {
itremove();
return true;
}
}
}
return false;
}
可以看到在调用removeAll方法时,实际上是循环调用了remove方法,而remove方法中有一段关键的代码:if (oequals(itnext()))
!
So,得出结论,因为上述例子中的实体类没有Override
hashCode和equals方法 !而在执行removeAll方法时是通过equals方法来判断集合元素是否相等的,如果没有Override
equals方法,其默认的仍是比较对象,所以会出现上述问题!
归根到底,还是基础没有掌握牢固,同时也给自己提了个醒,写实体类时尽量Override hashCode和equals方法,不这样说不定哪天就会出问题。Java中,集合主要有List、Set和Map,我个人理解集合的主要作用是相当于一个容器,你可以在里面装你希望装的对象,可以是Java内置的类,也可以是自定义的类。再者,这些集合支持一些方便的 *** 作,比如Set可以排除重复,Map可以快速检索等等。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)