用于向Java Bean添加业务逻辑的良好设计

时间:2014-07-20 16:15:58

标签: java compare software-design compareto

在下面的代码中,在这里使用isMatched()是有意义的(在Value对象/ java bean中) ?什么是好设计。顺便说一句,我尝试了compareTo,compare,hashSet等,通过关注Stack溢出的其他帖子,不知何故,我仍然无法从两个列表中删除重复。

public class SessionAttributes { 

private static final Logger LOGGER = Logger
        .getLogger(SessionAttributes.class);

public SessionNotificationAttributes(String userName, String sessionState) {
    this.userName = userName;
    this.sessionState = sessionState;
}

String userName;
public String getUserName() {
    return userName;
}
public void setUserName(String userName) {
    this.userName = userName;
}
// .. getters/setters for sessionState

 public static isMatched (List<SessionAttributes> list1, 
             List<SessionAttributes> list2) {

   //.. custom logic here...
 }

}

====大卫在评论中提出的整个代码。看看main()方法。这是直接从Eclipse粘贴的,以满足http://sscce.org/要求========

package snippet;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;


public class SessionAttributes  implements 
    Comparable<SessionAttributes>, Comparator<SessionAttributes>  {

private static final Logger LOGGER = Logger
        .getLogger(SessionAttributes.class);

public SessionAttributes(String userName, String sessionState) {
    /*
     * String nasPort, String endpointProfile, String audiSessionId, String
     * epsStatus, String securityGroup, String nasIp, String postureStatus,
     * String postureTimestamp) {
     */

    this.userName = userName;
    this.sessionState = sessionState;

    /*
     * this.nasPort = nasPort; this.endpoinProfile = endpointProfile;
     * this.auditSessionId = audiSessionId; this.epsStatus = epsStatus;
     * this.securityGroup = securityGroup; this.nasIp = nasIp;
     * this.postureStatus = postureStatus; this.postureTimestamp =
     * postureTimestamp;
     */

}


String userName;
public String getUserName() {
    return userName;
}
String sessionState;
public String getSessionState() {
    return sessionState;
}
public int compareTo(SessionAttributes o) {
    // TODO Auto-generated method stub
    if (this.getUserName().equals(o.getUserName()) && this.getSessionState().equalsIgnoreCase(o.getSessionState())) {
        return 0;
    }
    return -1;
}

public String toString() {

    return "\n User Name : " + this.getUserName() + " Session State : "
            + getSessionState() + "\n";
}



static boolean isMatched(List<SessionAttributes> list1,
        List<SessionAttributes> list2) {

    if (null == list1 || null == list2)
        return false;

    System.out.println("Actual List=>" + list1);
    System.out.println("Expected List=>" + list2);
    Iterator<SessionAttributes> iterator = list1.iterator();

    while (iterator.hasNext()) {
        SessionAttributes actual = iterator.next();
        Iterator<SessionAttributes> iterator2 = list2
                .iterator();
        while (iterator2.hasNext()) {
            SessionAttributes expected = iterator2.next();
            if (expected.getUserName().equalsIgnoreCase(
                    actual.getUserName())) {
                if (expected.getSessionState().equalsIgnoreCase(
                        actual.getSessionState())) {
                    System.out.println("Element matched - user name-"
                            + expected.getUserName() + " State -"
                            + expected.getSessionState());
                    iterator.remove();
                    iterator2.remove();
                }
            } else {
                System.out.println("Element NOT matched - user name-"
                        + expected.getUserName() + " State -"
                        + expected.getSessionState());

            }
        }
    }

    System.out.println("Lists after removing Dups -");
    System.out.println("list1 =>" + list1.toString() + " list2 -"
            + list2.toString());

    if (list1.size() > 0 || list2.size() > 0)
        return false;

    return true;
}

static void sortLists () {

    List<SessionAttributes> expectedSessionList = new ArrayList<SessionAttributes>();

    SessionAttributes user11 = new SessionAttributes(
            "postureuser1", "STARTED"); //
    // ,null,null,null,null,null,null,null,null);

    SessionAttributes user12 = new SessionAttributes(
            "postureuser1", "DISCONNECTED");

    SessionAttributes user13 = new SessionAttributes(
            "postureuser5", "STARTED");

    // ,null,null,null,null,null,null,null,null);

    expectedSessionList.add(user11);
    expectedSessionList.add(user12);
    expectedSessionList.add(user13);

    List<SessionAttributes> actualSessionList = new ArrayList<SessionAttributes>();

    SessionAttributes user3 = new SessionAttributes(
            "postureuser1", "STARTED");
    // ,null,null,null,null,null,null,null,null);

    SessionAttributes user4 = new SessionAttributes(
            "postureuser1", "DISCONNECTED");

    SessionAttributes user5 = new SessionAttributes(
            "postureuser2", "DISCONNECTED");

    // ,null,null,null,null,null,null,null,null);

    actualSessionList.add(user3);
    actualSessionList.add(user4);
    actualSessionList.add(user5);

    Set<SessionAttributes> removeDups = new HashSet<SessionAttributes>();

    boolean b1 = removeDups.add(user11);
    boolean b2 = removeDups.add(user12);
    boolean b3 = removeDups.add(user13);
    boolean b4 = removeDups.add(user3);
    boolean b5 = removeDups.add(user4);
    boolean b6 = removeDups.add(user5);
    System.out.println(" Set--" + removeDups);

    // removeDups.addAll(expectedSessionList);
    // removeDups.addAll(actualSessionList);

    System.out.println("== Printing Set ====");
    int countMisMatch = 0;

    System.out.println(isMatched(actualSessionList, expectedSessionList));

    // int isMatch = user3.compareTo(user1);
    // System.out.println("Compare=>" + isMatch);
}

static void  sortSet () {

    List<SessionAttributes> expectedSessionList = new ArrayList<SessionAttributes>();

    SessionAttributes user11 = new SessionAttributes(
            "postureuser1", "STARTED"); //
    // ,null,null,null,null,null,null,null,null);

    SessionAttributes user12 = new SessionAttributes(
            "postureuser1", "DISCONNECTED");

    SessionAttributes user13 = new SessionAttributes(
            "postureuser5", "STARTED");

    SessionAttributes user3 = new SessionAttributes(
            "postureuser1", "STARTED");
    // ,null,null,null,null,null,null,null,null);

    SessionAttributes user4 = new SessionAttributes(
            "postureuser1", "DISCONNECTED");

    SessionAttributes user5 = new SessionAttributes(
            "postureuser2", "DISCONNECTED");

    // ,null,null,null,null,null,null,null,null);


    Set<SessionAttributes> removeDups = new HashSet<SessionAttributes>();

    boolean b1 = removeDups.add(user11);
    boolean b2 = removeDups.add(user12);
    boolean b3 = removeDups.add(user13);
    boolean b4 = removeDups.add(user3);
    boolean b5 = removeDups.add(user4);
    boolean b6 = removeDups.add(user5);
    System.out.println(" Set--" + removeDups);

    // removeDups.addAll(expectedSessionList);
    // removeDups.addAll(actualSessionList);

    System.out.println("== Printing Set ====");
    System.out.println(removeDups);

    // int isMatch = user3.compareTo(user1);
    // System.out.println("Compare=>" + isMatch);



}

public int compare(SessionAttributes o1,
        SessionAttributes o2) {

    LOGGER.debug("Compare called -[" + o1.getUserName() + "] ["
            + o2.getUserName() + "]");
    boolean isSameUserName = o1.userName.equalsIgnoreCase(o2.userName);
    boolean isSameState = o1.sessionState
            .equalsIgnoreCase(this.sessionState);

    if (isSameUserName && isSameState)
        return 0;

    return -1;
}

public boolean equals(SessionAttributes obj) {

    if (obj == null || !(obj instanceof SessionAttributes)) {
        return false;
    }
    System.out.println(" In equals==");
    boolean isSameUserName = obj.userName.equalsIgnoreCase(this.userName);
    boolean isSameState = obj.sessionState
            .equalsIgnoreCase(this.sessionState);
    return (isSameUserName && isSameState);
}

public int hashCode() {

    System.out.println(" in hashcode ");
    int hash = 1;
    hash = hash * 17 + this.getUserName().hashCode();
    hash = hash * 31 + this.getSessionState().hashCode();
    // hash = hash * 13 + this.getAuditSessionId().hashCode();
    System.out.println(" hash=>" + hash);
    return hash;
}

public static void main(String[] args) {
    //sortSet();
    sortLists();
}

}

====大卫的代码应该删除重复。粘贴相关部分以便更好地进行比较。不知何故,这仍然无效

    public int compareTo(SessionAttributesFromDavid o) {
          if (this == o) {
            return 0;
        }
        // Null is considered less than any object.
        if (o == null) {
            return 1;
        }

        // Use compareToIgnoreCase since you used equalsIgnoreCase in equals.

        int diff = userName.compareToIgnoreCase(o.userName);
        if (diff != 0)
            return diff;

        diff = sessionState.compareToIgnoreCase(o.sessionState);
        return diff;
    }
 public boolean equals(Object o) {
        // See if o is the same object. If it is, return true.
        if (o == this) {
            return true;
        }

        // The instanceof check also checks for null. If o is null, instanceof will be false.
        if (!(o instanceof SessionAttributes)) {
            return false;
        }

        SessionAttributes that = (SessionAttributes) o;
        return userName.equalsIgnoreCase(that.userName) &&   sessionState.equalsIgnoreCase(sessionState);
    }

设置removeDups = new TreeSet();

        boolean b1 = removeDups.add(user11);
        boolean b2 = removeDups.add(user12);
        boolean b3 = removeDups.add(user13);
        boolean b4 = removeDups.add(user3);
        boolean b5 = removeDups.add(user4);
        boolean b6 = removeDups.add(user5);

        System.out.println(" Set--" + removeDups);

设置 - [  用户名:postureuser2会话状态:DISCONNECTED ,  用户名:postureuser1会话状态:已启动 ,  用户名:postureuser5会话状态:已启动 ,  用户名:postureuser1会话状态:DISCONNECTED ,  用户名:postureuser1会话状态:已启动 ]

1 个答案:

答案 0 :(得分:0)

我不会创建一个isMatched方法来比较两个SessionAttributes列表。

我肯定会使用SessionAttributes实现equals和hashCode。以同样的方式实现它们至关重要。如果要比较两个字符串的相等性,请使用两个字符串计算hashCode。如果你没有得到equals和hashCode,那么这一切都不会起作用。

如果你想将SessionAttributes放在SortedSet中,我也会让SessionAttributes实现Comparable。

另外,我会使SessionAttributes不可变,因此没有setter并将两个String元素声明为final。如果这样做,您可以将SessionAttributes添加到Set或Map中,您不必担心它们的值会发生变化。如果你不能使它们成为不可变的,你必须确保在将它们添加到List或Set之后不要更改任何SessionAttributes值。

我将它们放在一个Set中,而不是将它们放在List中,以确保你不会在同一个SessionAttributes集合中有重复项。

如果要从其中一个集合中删除重复项,请在其上使用Collection的removeAll方法,并将其传递给另一个SessionAttributes集合。

作为旁注,sessionState看起来像一个具有有限数量的可能值的变量,因此我会考虑为它定义一个Enum而不是使它成为一个String。

我希望这会有所帮助。

编辑:

您的compareTo方法无效,因为如果相等则返回0,否则返回-1。 它不符合compareTo的合同。请阅读javadocs

以下是SSCCE的一些变更和评论。因为在equals中,你比较等同忽略大小写,你必须在你的hashCode方法中将字符串转换为所有大写或小写,这样它将与equals一致。您还必须在compareTo方法中使用compareIgnoreCase以保持一致性。 由于compareTo方法有效,您现在可以简单地使用TreeSet对对象的集合进行排序。

我删除了您不再需要的方法,并尝试在代码中添加一些有用的注释。

package snippet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

// You don't need to implement Comparator.
public class SessionAttributes implements Comparable<SessionAttributes> {

    // You typically define member variables at the top of the class definition.
    private final String userName;
    private final String sessionState;

    public SessionAttributes(String userName, String sessionState) {

        // Throw a NullPointerException from the constructor if either of the Strings is null. This way, you know that
        // if the object is constructed successfully, it is free of nulls.
        if (userName == null) {
            throw new NullPointerException("userName must not be null");
        }
        if (sessionState == null) {
            throw new NullPointerException("sessionState must not be null");
        }
        /*
         * String nasPort, String endpointProfile, String audiSessionId, String epsStatus, String securityGroup, String
         * nasIp, String postureStatus, String postureTimestamp) {
         */

        this.userName = userName;
        this.sessionState = sessionState;

        /*
         * this.nasPort = nasPort; this.endpoinProfile = endpointProfile; this.auditSessionId = audiSessionId;
         * this.epsStatus = epsStatus; this.securityGroup = securityGroup; this.nasIp = nasIp; this.postureStatus =
         * postureStatus; this.postureTimestamp = postureTimestamp;
         */

    }

    public String getUserName() {
        return userName;
    }

    public String getSessionState() {
        return sessionState;
    }

    @Override
    public int compareTo(SessionAttributes o) {
        if (this == o) {
            return 0;
        }
        // Null is considered less than any object.
        if (o == null) {
            return 1;
        }

        // Use compareToIgnoreCase since you used equalsIgnoreCase in equals.

        int diff = userName.compareToIgnoreCase(o.userName);
        if (diff != 0)
            return diff;

        diff = sessionState.compareToIgnoreCase(o.sessionState);
        return diff;
    }

    // public int compareTo(SessionAttributes o) {
    // // TODO Auto-generated method stub
    // if (this.getUserName().equals(o.getUserName()) && this.getSessionState().equalsIgnoreCase(o.getSessionState())) {
    // return 0;
    // }
    // return -1;
    // }

    public String toString() {

        return "\n User Name : " + this.getUserName() + " Session State : " + getSessionState() + "\n";
    }

    // public boolean equals(SessionAttributes obj) {
    //
    // if (obj == null || !(obj instanceof SessionAttributes)) {
    // return false;
    // }
    // System.out.println(" In equals==");
    // boolean isSameUserName = obj.userName.equalsIgnoreCase(this.userName);
    // boolean isSameState = obj.sessionState.equalsIgnoreCase(this.sessionState);
    // return (isSameUserName && isSameState);
    // }

    public boolean equals(Object o) {
        // See if o is the same object. If it is, return true.
        if (o == this) {
            return true;
        }

        // The instanceof check also checks for null. If o is null, instanceof will be false.
        if (!(o instanceof SessionAttributes)) {
            return false;
        }

        SessionAttributes that = (SessionAttributes) o;
        return userName.equalsIgnoreCase(that.userName) && sessionState.equalsIgnoreCase(sessionState);
    }

    public int hashCode() {

        System.out.println(" in hashcode ");
        int hash = 1;
        // Since in equals you are comparing for equality and ignoring case, you must convert the Strings to either
        // lower
        // or upper case when computing the hashCode so that it will always be consistent with equals.
        hash = hash * 17 + this.getUserName().toUpperCase().hashCode();
        hash = hash * 31 + this.getSessionState().toUpperCase().hashCode();
        // hash = hash * 13 + this.getAuditSessionId().hashCode();
        System.out.println(" hash=>" + hash);
        return hash;
    }

    public static void main(String[] args) {
        // sortSet();
        // sortLists();

        // expectedSessionList
        List<SessionAttributes> expectedSessionList = new ArrayList<SessionAttributes>();

        SessionAttributes user11 = new SessionAttributes("postureuser1", "STARTED"); //
        // ,null,null,null,null,null,null,null,null);

        SessionAttributes user12 = new SessionAttributes("postureuser1", "DISCONNECTED");

        SessionAttributes user13 = new SessionAttributes("postureuser5", "STARTED");

        expectedSessionList.add(user11);
        expectedSessionList.add(user12);
        expectedSessionList.add(user13);

        System.out.println("expectedSessionList: " + expectedSessionList);

        // actualSessionList
        List<SessionAttributes> actualSessionList = new ArrayList<SessionAttributes>();

        SessionAttributes user3 = new SessionAttributes("postureuser1", "STARTED");
        // ,null,null,null,null,null,null,null,null);

        SessionAttributes user4 = new SessionAttributes("postureuser1", "DISCONNECTED");

        SessionAttributes user5 = new SessionAttributes("postureuser2", "DISCONNECTED");

        // ,null,null,null,null,null,null,null,null);

        actualSessionList.add(user3);
        actualSessionList.add(user4);
        actualSessionList.add(user5);

        System.out.println("actualSessionList: " + actualSessionList);

        // removeDups
        // Use a TreeSet to sort it.
        Set<SessionAttributes> removeDups = new TreeSet<SessionAttributes>();

        boolean b1 = removeDups.add(user11);
        boolean b2 = removeDups.add(user12);
        boolean b3 = removeDups.add(user13);
        boolean b4 = removeDups.add(user3);
        boolean b5 = removeDups.add(user4);
        boolean b6 = removeDups.add(user5);

        System.out.println(" Set--" + removeDups);

        actualSessionList.removeAll(expectedSessionList);
        System.out.println("actualSessionList after removeAll: " + actualSessionList);

    }

}

输出:

expectedSessionList:[  用户名:postureuser1会话状态:已启动 ,  用户名:postureuser1会话状态:DISCONNECTED ,  用户名:postureuser5会话状态:已启动 ]

actualSessionList:[  用户名:postureuser1会话状态:已启动 ,  用户名:postureuser1会话状态:DISCONNECTED ,  用户名:postureuser2会话状态:DISCONNECTED ]

设置 - [  用户名:postureuser1会话状态:DISCONNECTED ,  用户名:postureuser1会话状态:已启动 ,  用户名:postureuser2会话状态:DISCONNECTED ,  用户名:postureuser5会话状态:已启动 ]

删除后的

actualSessionList:[  用户名:postureuser2会话状态:DISCONNECTED ]