【问题标题】:Good Design for adding business logic to Java Bean将业务逻辑添加到 Java Bean 的良好设计
【发布时间】:2014-07-20 16:15:58
【问题描述】:

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

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();
}

}

==== 来自 David 的代码,它应该删除 dups。仅粘贴相关部分以进行更好的比较。不知何故,这仍然不起作用

    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);

设置--[ 用户名:poseuser2 会话状态:DISCONNECTED , 用户名:poseuser1 会话状态:STARTED , 用户名:poseuser5 会话状态:STARTED , 用户名:poseuser1 会话状态:DISCONNECTED , 用户名:poseuser1 会话状态:STARTED ]

【问题讨论】:

    标签: java compare software-design compareto


    【解决方案1】:

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

    我肯定会选择让 SessionAttributes 实现 equals 和 hashCode。以相同的方式同时实现它们至关重要。如果您想比较两个字符串是否相等,请使用两个字符串计算您的 hashCode。如果你没有得到正确的 equals 和 hashCode,这些都不会起作用。

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

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

    我不会将它们放在一个列表中,而是将它们放在一个集合中,以确保您在同一个 SessionAttributes 集合中没有重复项。

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

    附带说明一下,sessionState 看起来像一个具有有限数量可能值的变量,所以我会考虑为它定义一个 Enum 而不是将其设为 String。

    我希望这会有所帮助。

    编辑:

    您的 compareTo 方法不起作用,因为如果相等则返回 0,否则返回 -1。 它不履行 compareTo 的合同。请阅读其javadocs

    以下是带有一些更改和 cmets 的 SSCCE。由于在 equals 中,您比较忽略大小写的相等性,因此您必须在 hashCode 方法中将字符串转换为全部大写或小写,以便与 equals 保持一致。您还必须在 compareTo 方法中使用 compareIgnoreCase 以保持一致性。 由于 compareTo 方法有效,您现在可以简单地使用 TreeSet 对对象集合进行排序。

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

    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);
    
        }
    
    }
    

    输出:

    预期会话列表:[ 用户名:poseuser1 会话状态:STARTED , 用户名:poseuser1 会话状态:DISCONNECTED , 用户名:poseuser5 会话状态:STARTED ]

    实际会话列表:[ 用户名:poseuser1 会话状态:STARTED , 用户名:poseuser1 会话状态:DISCONNECTED , 用户名:poseuser2 会话状态:DISCONNECTED ]

    设置--[ 用户名:poseuser1 会话状态:DISCONNECTED , 用户名:poseuser1 会话状态:STARTED , 用户名:poseuser2 会话状态:DISCONNECTED , 用户名:poseuser5 会话状态:STARTED ]

    removeAll 后的实际会话列表:[ 用户名:poseuser2 会话状态:DISCONNECTED ]

    【讨论】:

    • 感谢您的 cmets。我确实实现了equals和hashCode。我没有粘贴整个代码。删除设置器的好点。我确实尝试了可比较的比较器,将对象添加到 Set、HashSet 但不知何故它对我不起作用。我想要两个列表中的两个值匹配,例如 userName=user1, sessionState=disconnected。不知何故 Set 等对我不起作用。 SO上有与此相关的帖子,我关注但没有工作。不确定 getter/setter 是否导致了这种情况。让我尝试删除 setter/getter 并尝试 Set/removaAll 方法。
    • 如果您仍然无法使用它,请使用简短、独立、可编译的示例更新您的问题。 http://sscce.org/
    • 其实上面的代码是针对SSCCE的。让我获取整个代码,您可以建议可能缺少的内容。我放弃了 Comparator 并采用了蛮力方式(迭代会话 bean 列表以使用 equals 找到匹配项)
    • 谢谢,大卫。你测试了吗?它似乎与我粘贴的相似。非常感谢您花时间在这上面。欣赏它。
    • 嗨,是的,我测试过了。有用。别客气。 stackoverflow 表示感谢的方式是批准答案。如果您觉得我对您的问题的回答令您满意,请批准。谢谢
    猜你喜欢
    • 1970-01-01
    • 2013-02-18
    • 2011-07-03
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    相关资源
    最近更新 更多