3

我有这样的方法:

public void show(Object o)
{
   //show content of object
}

我想将 TreeSet 或 HashMap 传递给它。但它是一个不同的迭代,我的意思是,当我想显示 TreeSet 的内容时,我使用该代码:

 while ( iter.hasNext() )
    {
      System.out.println( iter.next());
    }

但是当我有一个 HasMap 时,我会这样打印它:

Iterator iterator = map.keySet().iterator();  

while (iterator.hasNext()) {  
   String key = iterator.next().toString();  
   String value = map.get(key).toString();  

   System.out.println(key + " " + value);  
} 

当我不知道用户是否传递 TreeSet 或 HashMap 时,有没有办法显示集合的内容?我无法在 show 方法中进行任何转换(这不是重点)。有任何想法吗?

4

4 回答 4

4

不是直接的,但是如果你的方法被声明为:

public <T> void show(Iterable<T> iterable) {
  for(T t: iterable) {
    System.out.println(t);
  }
}

那么你可以像这样使用它:

show(set);
show(map.entrySet());

不完全是您想要的,但本质MapSet是不同的,您不能真正以相同的方式对待它们(多态)。

于 2012-11-21T22:12:46.283 回答
1
if (o instanceof Map) {
            HashMap map = (HashMap) o;
            Iterator iterator = map.keySet().iterator();

            while (iterator.hasNext()) {
                String key = iterator.next().toString();
                String value = map.get(key).toString();

                System.out.println(key + " " + value);
            }
        } else if (o instanceof Set) {
            TreeSet tree = (TreeSet) o;
            Iterator iter = tree.iterator();
            while (iter.hasNext()) {
                System.out.println(iter.next());
            }
        }
于 2012-11-21T22:13:36.063 回答
1

The answer is yes, but it's a little ugly:

public static void display(Object o) {
    if (o instanceof Iterable) { // includes Sets, Lists etc
        for (Object element : (Iterable<?>) o) {
            System.out.println(element);
        }
    } else if (o instanceof Map) {
        for (Map.Entry<Object, Object> entry : ((Map<Object,Object>) o).entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue());
        }
    } else if (o != null && o.getClass().isArray()){
        // How to detect and handle arrays
        for (Object element : (Object[])o) {
            System.out.println(o);
        }
    } else {
        // default case
        System.out.println(o);
    }
}
于 2012-11-21T22:17:02.473 回答
0

遵循更紧密的面向对象方法,您可以为 TreeSet 和 HashMap 类创建装饰器。然后,不是调用 show(object),而是调用 object.show(),恕我直言,它更干净,并且遵循 OOP 原则,例如封装和抽象:

public interface Showable {
    void show();
}

public class ShowableTreeSet<E> extends TreeSet<E> implements Showable
{
    private TreeSet<E> delegate;

    public ShowableTreeSet(TreeSet<E> delegate) {
        this.delegate = delegate;
    }

    public void show() {
        for (E e : delegate) {
            System.out.println(e);
        }
    }

    public boolean add(E e) {
        return delegate.add(e);
    }

//all other delegate methods
}

public class ShowableHashMap<K, V> extends HashMap<K, V> implements Showable 
{
    private HashMap<K, V> delegate;

    public ShowableHashMap(HashMap<K, V> delegate) {
        this.delegate = delegate;
    }

    public void show(){
        Iterator<K> iterator = delegate.keySet().iterator();  

        while (iterator.hasNext()) {  
           String key = iterator.next().toString();  
           String value = delegate.get(key).toString();  

           System.out.println(key + " " + value);  
        } 
    }

    public int size() {
        return delegate.size();
    }

//all other delegate methods
}

因此,您只需将可展示的内容包裹在您将使用的任何实际对象周围:

ShowableTreeSet<String> sts = new ShowableTreeSet<String>(new TreeSet<String>());
sts.show();

或者,如果您只想要任何 Showable 用于打印输出,您可以:

Showable showable = new ShowableTreeSet<String>(new TreeSet<String>());
showable.show();

您可以为几乎任何东西创建这些装饰器 - Iterable、List、Collection 等......然后使用依赖注入来使用您碰巧使用的任何 Collection(Iterable、List...)实现。

于 2012-11-21T23:00:56.447 回答