简体   繁体   English

带有地图的ArrayList <K,V> 值

[英]ArrayList with Map<K,V> values

I have n number of users with their name and time value eg 我有n个具有其名称和时间值的用户,例如

String userName = "user1"
String time = "09:30"

In an ArrayList ArrayList<Map<String,String>> userData = new ArrayList<>( ); 在ArrayList中ArrayList<Map<String,String>> userData = new ArrayList<>( ); I would like to have something like this 我想要这样的东西

在此处输入图片说明

But i'm confused with the K,V values. 但是我对K,V值感到困惑。 Should i first convert the userName and time in Map values separately? 我应该首先在地图值中分别转换用户名时间吗? like 喜欢

Map<String, String> uName = new HashMap<String, String>();
Map<String, String> uTime = new HashMap<String, String>();

uName.put("userName",userName);
uTime.put("time",time);

But then, how to add the two values in the same index of the Array? 但是,然后,如何将两个值添加到数组的同一索引中?

Or how which steps should i do first? 还是我应该首先做什么?

Could you please, write down an example or references that could help me as well. 您能否写下一个示例或参考资料对我也有帮助。

Thank you! 谢谢!

If I understand your question right, you may want to create a class: 如果我正确理解您的问题,则可能要创建一个类:

public class MyClass {
    private String userName;
    private LocalTime time;
    public MyClass(String userName, LocalTime time) { 
        this.userName = userName;
        this.time = time;
    }

    public String getUserName() { return userName; }
    public LocalTime getUserName() { return time; }
}

The you can simply have an ArrayList<MyClass> . 您只需拥有一个ArrayList<MyClass> You may want the time variable to be of type String , whatever works best for you. 您可能希望时间变量的类型为String ,这对您而言最合适。 I would not recommend storing timestamps as strings though. 我不建议将时间戳记存储为字符串。

I don't think you need a ArrayList of Maps here, there are two more suitable alternatives in my mind: 我认为您这里不需要Maps的ArrayList,在我看来有两种更合适的选择:

  1. Create a class User that will have two string variables - name and time, and have an ArrayList of User 创建一个类User ,该类将具有两个字符串变量-name和time,并具有一个ArrayList of User
  2. Map that points name->time 指向名称->时间的地图

either will do, having ArrayList of Maps seems redundant 两者都会做,让ArrayList of Maps显得多余

Just use one map only for each index. 只需为每个索引使用一张地图。 For instance: 例如:

List<Map<String, String>> userData = new ArrayList<Map<String, String>>();
Map<String, String> user1 = new HashMap<String, String>();
user1.put("name", "John");
user1.put("time", "9:03");
userData.add(user1);

While this works, then if you need to look for any user you'll have to go through the list and find the user you're looking for by accessing the map. 在此过程中,如果您需要查找任何用户,则必须遍历列表,并通过访问地图找到要查找的用户。 So you could have a Map of Maps: Map<String, Map<String, String>> this way: 因此,您可以通过以下方式获得Maps: Map<String, Map<String, String>>

Map<String, Map<String, String>> userData = new HashMap<String, Map<String, String>>();
Map<String, String> user1 = new HashMap<String, String>();
user1.put("time", "9:03");
userData.put("John", user1);

this way if you're looking for John's data you can just simply do userData.get("John") 这样,如果您正在寻找John的数据,则只需执行userData.get("John")

An even better solution would be to have a User class with defined properties. 更好的解决方案是使User类具有定义的属性。 For instance: 例如:

public class User {
    private String name;
    private String time;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getTime() { return time; }
    public void setTime(String time) { this.time = time; }
}

Map<String, User> userData = new HashMap<String, User>();
User user1 = new User();
user1.setName("John");
user1.setTime("9:03");
userData.put(user1.getName(), user1);

Based on your question "Is it possible to keep the map sorted everytime a user is inserted?" 根据您的问题“每次插入用户是否可以对地图进行排序?” the answer is NO. 答案是不。 Maps are unsorted. 地图未排序。 You seem to need a SortedList that inserts items ordered. 您似乎需要一个SortedList来插入已排序的项目。 Here's a simple Implementation: 这是一个简单的实现:

    public class SortedList<T> implements List<T> {
  private List<T> delegate;
  private Comparator<T> order;

  public SortedList(List<T> delegate, Comparator<T> order) {
    this.delegate = delegate;
    this.order = order;
  }

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

  @Override
  public boolean isEmpty() {
    return delegate.isEmpty();
  }

  @Override
  public boolean contains(Object o) {
    return delegate.contains(o);
  }

  @Override
  public Iterator<T> iterator() {
    return delegate.iterator();
  }

  @Override
  public Object[] toArray() {
    return delegate.toArray();
  }

  @Override
  public <T1> T1[] toArray(T1[] a) {
    return delegate.toArray(a);
  }

  @Override
  public boolean add(T t) {
    int i=0;
    for(; i < delegate.size(); i++) {
      if(order.compare(t, delegate.get(i)) < 0) {
        break;
      }
    }
    delegate.add(i, t);
    return true;
  }

  @Override
  public boolean remove(Object o) {
    return delegate.remove(o);
  }

  @Override
  public boolean containsAll(Collection<?> c) {
    return delegate.containsAll(c);
  }

  @Override
  public boolean addAll(Collection<? extends T> c) {
    if (c!= null && !c.isEmpty()) {
      return c.stream().map(this::add).reduce(Boolean.FALSE, (l, r) -> l || r);
    }
    return false;
  }

  @Override
  public boolean addAll(int index, Collection<? extends T> c) {
    throw new IllegalStateException("Can only add in order");
  }

  @Override
  public boolean removeAll(Collection<?> c) {
    return delegate.removeAll(c);
  }

  @Override
  public boolean retainAll(Collection<?> c) {
    return delegate.retainAll(c);
  }

  @Override
  public void clear() {
    delegate.clear();
  }

  @Override
  public T get(int index) {
    return delegate.get(index);
  }

  @Override
  public T set(int index, T element) {
    throw new IllegalStateException("Can only add in order");
  }

  @Override
  public void add(int index, T element) {
    throw new IllegalStateException("Can only add in order");
  }

  @Override
  public T remove(int index) {
    return delegate.remove(index);
  }

  @Override
  public int indexOf(Object o) {
    return delegate.indexOf(o);
  }

  @Override
  public int lastIndexOf(Object o) {
    return delegate.lastIndexOf(o);
  }

  @Override
  public ListIterator<T> listIterator() {
    return delegate.listIterator();
  }

  @Override
  public ListIterator<T> listIterator(int index) {
    return delegate.listIterator(index);
  }

  @Override
  public List<T> subList(int fromIndex, int toIndex) {
    return new SortedList<>(delegate.subList(fromIndex, toIndex), order);
  }

  @Override
  public String toString() {
    return delegate.toString();
  }
}

Which you'll instantiate for instance for a sorted integers list, like this: 例如,您将实例化排序的整数列表,如下所示:

SortedList<Integer> nums = 
new SortedList<Integer>(new ArrayList<Integer>(), Comparator.naturalOrder());

Alternatively, you could define your own data structure, say User . 或者,您可以定义自己的数据结构,例如User Then it goes something like this: 然后它是这样的:

public class User {
    private String name;
    private String time;

   // getters and setters
}

Main advantages to using a data structure as opposed to Map<String, String> include: Map<String, String>相比,使用数据结构的主要优点包括:

  1. Ease of use (no longer need Map , simply a list of User type elements), 易于使用(不再需要Map ,只需一个User类型元素的列表),
  2. Flexibility (perhaps at a later stage you decide to add a location info, this will require modification to the way Map works but it is as simple as adding a field "location" to the data structure). 灵活性(也许稍后您决定添加位置信息,这需要对Map工作方式进行修改,但就像在数据结构中添加字段“ location”一样简单)。
  3. Clarity of API and code intention. API和代码意图的清晰性。 Map<String, String> doesn't say much about what it holds or what it is used for. Map<String, String>并没有太多说明它的用途或用途。 Conversely, List<User> can be immediately identified as a list of users. 相反,可以将List<User>立即标识为用户列表。
  4. Being a pure data structure, or a Java Bean, it can be easily picked up by IDEs and other frameworks. 作为纯数据结构或Java Bean,IDE和其他框架可以轻松选择它。 For instance, serialization of such a class to json becomes a trivial task. 例如,将这样的类序列化为json变得很简单。

" User " may not be the right name for the type, but the concept applies nonetheless. User ”可能不是该类型的正确名称,但是该概念仍然适用。

You could load a list with Map.Entry: 您可以使用Map.Entry加载列表:

 final List<Map.Entry<String,String>> listOfEntries =
        new ArrayList<>();
listOfEntries.add(new AbstractMap.SimpleEntry<>("Name", "01:01"));
listOfEntries.add(new AbstractMap.SimpleEntry<>("Name2", "05:10"));

Alternatively, you could load this list with Maps.immutableEntry("firstValue", "secondValue") if you have a Guava dependency. 另外,如果您具有Guava依赖项,则可以使用Maps.immutableEntry("firstValue", "secondValue")加载此列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM