带有字符串键和值集的映射<T>

时间:2019-10-05 20:28:32

标签: java generics collections

我有一个值列表:

{(“ 1”,“ 3”),(“ 1”,“ 5”),(“ 3”,“ 13”)(“ 5”,“ 4”),(“ 1”,“ 7 “),(” 8“,” 9“),(” 9“,” 1“),(” 1“,” 23“),(” 5“,” 7“)}

和一个必须应用于每个元素“ 1:3,3:13,5:-”的过滤器。 我需要获取另一个列表,该列表具有与过滤器匹配的值。在这种情况下,结果应为:

值:1 3 值:3 13 值:5 4 值:5 7

在过滤器中,该值 5:- 表示它与第一个元素匹配,并且不考虑第二个值,因此任何以5开头的元素都是好吧。

import java.util.*;
import java.util.Set;
import java.util.stream.Collectors;

class Filter {
    private String valueFilter1;
    private String valueFilter2;

    public Filter(String valueFilter1, String valueFilter2) {
        this.valueFilter1 = valueFilter1;
        this.valueFilter2 = valueFilter2;
    }

    public Filter(String fil) {
        String[] filResult = fil.split(":");
        this.valueFilter1 = filResult[0];
        this.valueFilter2 = filResult[1];
    }

    public String getValueFilter1() {
        return valueFilter1;
    }

    public String getValueFilter2() { return valueFilter2; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Filter that = (Filter) o;
        return Objects.equals(valueFilter1, that.valueFilter1) &&
                Objects.equals(valueFilter2, that.valueFilter2);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((valueFilter1 == null) ? 0 : valueFilter1.hashCode());
        result = prime * result + ((valueFilter2 == null) ? 0 : valueFilter2.hashCode());
        return result;
    }

}


public class FilterUtils {
    private static void filterMessages(List<Filter> eventsParam, String type) {

        Set<Filter> filter1 = new HashSet<>();
        Set<String> filter2 = new HashSet<>();

        Arrays.stream(type.split(","))
                .forEach(f -> {
                    if (f.contains("-"))
                        filter2.add(f.split(":")[0]);
                    else
                        filter1.add(new Filter(f));
                });

        // This following logic is in another method called processMessage().
        // So I'm trying to return both filters as in processMessage I have something like this:
        // .stream()
        //                .filter(e -> filterMessages(eventsParam).contains(new Filter(e.getValueFilter1(), e.getValueFilter2()))
        //                .collect(Collectors.toList());
        // the real method filterMessages only receives List<Filter> eventsParam as argument
        // I was thinking of returning a map of Set like this Map<String, Set<Object>> or Map<String, Set<T>> but it didn't work
        // map.put("filter1", filter1);
        // map.put("filter2", filter2);
        // Not sure how to make it work

        List<Filter> result = eventsParam
                .stream()
                .filter(e -> filter1.contains(new Filter(e.getValueFilter1(), e.getValueFilter2())) |
                             filter2.contains(e.getValueFilter1()))
                .collect(Collectors.toList());

        for (Filter r: result) {
            System.out.println("Values: " + r.getValueFilter1() + " " + r.getValueFilter2());
        }
    }



    public static void main(String[] args) {
        List events = new ArrayList<Filter>();
        events.add(new Filter("1", "3"));
        events.add(new Filter("1", "5"));
        events.add(new Filter("3", "13"));
        events.add(new Filter("5", "4"));
        events.add(new Filter("1", "7"));
        events.add(new Filter("8", "9"));
        events.add(new Filter("9", "1"));
        events.add(new Filter("1", "23"));
        events.add(new Filter("5", "7"));

        filterMessages(events, "1:3,3:13,5:-");
    }
}

到目前为止,我拥有的代码可以正常工作,但是我认为这是一种有点复杂的方法,并且不允许我将其调整为适合我目前拥有的现有代码。任何想法?或面对这个问题的更好方法?谢谢

1 个答案:

答案 0 :(得分:0)

我建议您在代码审查网站https://codereview.stackexchange.com/上问这个问题。

简而言之:

1)不需要构造函数Filter(String valueFilter1, String valueFilter2)

2)尽管代码可以工作,但equals()的这种定义在其他情况下仍可能导致错误:

Filter a = new Filter("1", "2");
Filter b = new Filter("-", "2");
Filter c = new Filter("5", "2");
System.out.println(a.equals(b)); // true
System.out.println(b.equals(c)); // true
System.out.println(a.equals(c)); // false

根据常识,如果a = b和b = c,则它必须是a = c。但您的情况并非如此。在实际的应用程序中,这可能会导致难以发现的错误。