列出商品订购问题

问题描述 投票:0回答:4

我有一个项目列表和一组用户。用户可以对列表项重新排序。每个用户都有自己的列表视图,他可以按照自己的方式排列项目。对于不同的用户,一项可以放置在列表中的不同位置。我必须跟踪列表项中用户的项目位置。请提出实施此建议的建议。列表的大小不是恒定的。我正在使用Java。我的意图是我必须以每个用户的订购格式显示列表。请大师给我建议。

java algorithm
4个回答
2
投票

为什么不按照glowcoder 的建议首先为此进行经典的面向对象设计。然后你将有 User 类和 Item 类。用户类将有一个项目实例的列表。

class User{
  String userId;
  List<Item> userItems;
}

反向结构也会反映在数据库中(用户表、项目表和具有外键映射到前两个表的用户-项目表)。 Mark 建议的 Map of List 解决方案是可行的,但在像 Java 这样的面向对象语言中并不是“正确”的方法。


1
投票

您可以保留一个有序列表,从主列表中检索项目的顺序:

List<Foo> items = new ArrayList<Foo>();
// add stuff to items (say, 6 things)

Map<String,List<Integer>> userOrders = new HashMap<String,List<Integer>>();
userOrders.put("A", Arrays.asList(0,1,2,3,4,5)); // add user A's order
userOrders.put("B", Arrays.asList(5,4,3,2,1,0)); // add user B's order

// display for userA:
for(Integer i : userOrders.get("A")){
    show(items.get(i)); // show the userA's i-th item
}

这里我还使用

Map
来保存订单。根据您的应用程序,您可能会使用其他方案来检索用户的自定义排序,但原则始终是相同的:如果用户可以有自定义订单,您应该将该 ordering 存储在某处,然后迭代列表基于该顺序的事物(如上所示)。

还要注意您使用的

List
的类型,调用
get
进行随机访问
LinkedList
的成本比在
ArrayList
上要高得多。


0
投票

您有一个位置来存储实际的项目列表。然后每个用户都会获得自己的数据模型。它由实际列表支持,但模型更多的是每个项目的实际索引与用户对该项目具有的显示索引之间的映射。然后您就有了一个查看器,可以使用该模型在 GUI 中显示列表。就查看者而言,模型正在告诉它正确的索引。但该模型允许从显示顺序到实际顺序的转换。当用户通过视图操作列表时,您可以更新索引图并且永远不会触及实际数据。


0
投票

为了扩展正确的rahulmohan的回答,我将添加一些示例代码。

定义我们的

Item
User
类。

record Item( String description ) { }

final class User
{
    private final String name;
    private final List < Item > items;

    User ( String name , List < Item > items )
    {
        this.name = name;
        this.items = items;
    }

    public String id ( ) { return name; }

    public List < Item > items ( ) { return items; }

    public void addItem ( final Item item )
    {
        this.items.addLast( item );  // Or, before Java 21: `List.add( this.items.size() , item )`.
    }

    @Override
    public boolean equals ( Object obj )
    {
        if ( obj == this ) return true;
        if ( obj == null || obj.getClass( ) != this.getClass( ) ) return false;
        var that = ( User ) obj;
        return Objects.equals( this.name , that.name ) &&
                Objects.equals( this.items , that.items );
    }

    @Override
    public int hashCode ( )
    {
        return Objects.hash( name , items );
    }

    @Override
    public String toString ( )
    {
        return "User[" +
                "id=" + name + ", " +
                "items=" + items + ']';
    }
}

一些示例数据。

final List < Item > masterListOfItems =
        new ArrayList <>(
                List.of(
                        new Item( "Dog" ) ,
                        new Item( "Cat" ) ,
                        new Item( "Bird" )
                )
        );
final List < User > users =
        new ArrayList <>(
                List.of(
                        new User( "Alice" , new LinkedList <>( masterListOfItems ) ) ,
                        new User( "Bob" , new LinkedList <>( masterListOfItems ) ) ,
                        new User( "Carol" , new LinkedList <>( masterListOfItems ) )
                )
        );

鲍勃更喜欢猫。因此,他将第二个项目

Cat
移动到第一个位置(索引零),位于
Dog
项目上方。

// Bob prefers cats.
User bob = users.stream( ).filter( user -> user.id( ).equalsIgnoreCase( "Bob" ) ).findAny( ).get( );
System.out.println( "(before move) bob = " + bob );
Item cat = bob.items( ).stream( ).filter( item -> item.description( ).equalsIgnoreCase( "Cat" ) ).findAny( ).get( );
bob.items( ).remove( cat );
bob.items( ).addFirst( cat );
System.out.println( "(after move) bob = " + bob );

运行时:

(before move) bob = User[id=Bob, items=[Item[description=Dog], Item[description=Cat], Item[description=Bird]]]
(after move) bob = User[id=Bob, items=[Item[description=Cat], Item[description=Dog], Item[description=Bird]]]
// Add new item.
Item hamster = new Item( "Hamster" );
masterListOfItems.addLast( hamster );
users.forEach( user -> user.addItem( hamster ) );
System.out.println( "(after add) bob = " + bob );
System.out.println( "masterListOfItems = " + masterListOfItems );

运行时,我们看到 Bob 有自己的列表,按照他的个人喜好排序,而我们的主列表的顺序保持不变。

(after add) bob = User[id=Bob, items=[Item[description=Cat], Item[description=Dog], Item[description=Bird], Item[description=Hamster]]]
masterListOfItems = [Item[description=Dog], Item[description=Cat], Item[description=Bird], Item[description=Hamster]]

请注意,使用多个列表可以有效节省内存。内容对象(

User
Item
对象) 被重复。内存中每个 Item
 对象只有 
一个实例,在许多
List
对象之间共享,每个对象都由一个
User
对象拥有。

© www.soinside.com 2019 - 2024. All rights reserved.